Annotation of embedaddon/strongswan/src/libstrongswan/plugins/sshkey/sshkey_encoder.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2013-2018 Tobias Brunner
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include "sshkey_encoder.h"
17:
18: #include <asn1/asn1.h>
19: #include <asn1/oid.h>
20: #include <bio/bio_writer.h>
21:
22: #define ECDSA_PREFIX "ecdsa-sha2-"
23:
24: /**
25: * Write an EC domain parameter identifier as defined in RFC 5656
26: */
27: static void write_ec_identifier(bio_writer_t *writer, char *prefix, int oid,
28: chunk_t enc)
29: {
30: char *curve, identifier[128];
31:
32: switch (oid)
33: {
34: case OID_PRIME256V1:
35: curve = strdup("nistp256");
36: break;
37: case OID_SECT384R1:
38: curve = strdup("nistp384");
39: break;
40: case OID_SECT521R1:
41: curve = strdup("nistp521");
42: break;
43: default:
44: curve = asn1_oid_to_string(enc);
45: break;
46: }
47: if (curve && snprintf(identifier, sizeof(identifier), "%s%s", prefix,
48: curve) < sizeof(identifier))
49: {
50: writer->write_data32(writer, chunk_from_str(identifier));
51: }
52: free(curve);
53: }
54:
55: /**
56: * Encode the public key as Base64 encoded SSH key blob
57: */
58: static bool build_public_key(chunk_t *encoding, va_list args)
59: {
60: bio_writer_t *writer;
61: chunk_t n, e;
62:
63: if (cred_encoding_args(args, CRED_PART_RSA_MODULUS, &n,
64: CRED_PART_RSA_PUB_EXP, &e, CRED_PART_END))
65: {
66: writer = bio_writer_create(0);
67: writer->write_data32(writer, chunk_from_str("ssh-rsa"));
68:
69: writer->write_data32(writer, e);
70: writer->write_data32(writer, n);
71: *encoding = chunk_to_base64(writer->get_buf(writer), NULL);
72: writer->destroy(writer);
73: return TRUE;
74: }
75: else if (cred_encoding_args(args, CRED_PART_EDDSA_PUB_ASN1_DER, &n,
76: CRED_PART_END))
77: {
78: chunk_t alg;
79: char *prefix;
80: int oid;
81:
82: /* parse subjectPublicKeyInfo */
83: if (asn1_unwrap(&n, &n) != ASN1_SEQUENCE)
84: {
85: return FALSE;
86: }
87: oid = asn1_parse_algorithmIdentifier(n, 1, NULL);
88: switch (oid)
89: {
90: case OID_ED25519:
91: prefix = "ssh-ed25519";
92: break;
93: case OID_ED448:
94: prefix = "ssh-ed448";
95: break;
96: default:
97: return FALSE;
98: }
99: if (asn1_unwrap(&n, &alg) != ASN1_SEQUENCE ||
100: asn1_unwrap(&n, &n) != ASN1_BIT_STRING || !n.len)
101: {
102: return FALSE;
103: }
104: writer = bio_writer_create(0);
105: writer->write_data32(writer, chunk_from_str(prefix));
106: writer->write_data32(writer, chunk_skip(n, 1));
107: *encoding = chunk_to_base64(writer->get_buf(writer), NULL);
108: writer->destroy(writer);
109: return TRUE;
110: }
111: else if (cred_encoding_args(args, CRED_PART_ECDSA_PUB_ASN1_DER, &n,
112: CRED_PART_END))
113: {
114: chunk_t params, alg, q;
115: int oid;
116:
117: /* parse subjectPublicKeyInfo */
118: if (asn1_unwrap(&n, &n) != ASN1_SEQUENCE)
119: {
120: return FALSE;
121: }
122: oid = asn1_parse_algorithmIdentifier(n, 1, ¶ms);
123: if (oid != OID_EC_PUBLICKEY ||
124: asn1_unwrap(¶ms, ¶ms) != ASN1_OID)
125: {
126: return FALSE;
127: }
128: oid = asn1_known_oid(params);
129: if (oid == OID_UNKNOWN)
130: {
131: return FALSE;
132: }
133: if (asn1_unwrap(&n, &alg) != ASN1_SEQUENCE ||
134: asn1_unwrap(&n, &q) != ASN1_BIT_STRING)
135: {
136: return FALSE;
137: }
138: writer = bio_writer_create(0);
139: write_ec_identifier(writer, ECDSA_PREFIX, oid, params);
140: write_ec_identifier(writer, "", oid, params);
141:
142: q = chunk_skip_zero(q);
143: writer->write_data32(writer, q);
144: *encoding = chunk_to_base64(writer->get_buf(writer), NULL);
145: writer->destroy(writer);
146: return TRUE;
147: }
148: return FALSE;
149: }
150:
151: bool sshkey_encoder_encode(cred_encoding_type_t type, chunk_t *encoding,
152: va_list args)
153: {
154: switch (type)
155: {
156: case PUBKEY_SSHKEY:
157: return build_public_key(encoding, args);
158: default:
159: return FALSE;
160: }
161: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>