Annotation of embedaddon/strongswan/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
3: *
4: * Permission is hereby granted, free of charge, to any person obtaining a copy
5: * of this software and associated documentation files (the "Software"), to deal
6: * in the Software without restriction, including without limitation the rights
7: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8: * copies of the Software, and to permit persons to whom the Software is
9: * furnished to do so, subject to the following conditions:
10: *
11: * The above copyright notice and this permission notice shall be included in
12: * all copies or substantial portions of the Software.
13: *
14: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20: * THE SOFTWARE.
21: */
22:
23: #include "wolfssl_common.h"
24:
25: #ifdef HAVE_ED25519
26:
27: #include "wolfssl_ed_public_key.h"
28:
29: #include <utils/debug.h>
30: #include <asn1/asn1.h>
31:
32: #include <wolfssl/wolfcrypt/ed25519.h>
33: #include <wolfssl/wolfcrypt/asn.h>
34:
35: typedef struct private_public_key_t private_public_key_t;
36:
37: /**
38: * Private data
39: */
40: struct private_public_key_t {
41:
42: /**
43: * Public interface
44: */
45: public_key_t public;
46:
47: /**
48: * Key object
49: */
50: ed25519_key key;
51:
52: /**
53: * Reference count
54: */
55: refcount_t ref;
56: };
57:
58: METHOD(public_key_t, get_type, key_type_t,
59: private_public_key_t *this)
60: {
61: return KEY_ED25519;
62: }
63:
64: METHOD(public_key_t, verify, bool,
65: private_public_key_t *this, signature_scheme_t scheme,
66: void *params, chunk_t data, chunk_t signature)
67: {
68: byte dummy[1];
69: int ret, res;
70:
71: if (scheme != SIGN_ED25519)
72: {
73: DBG1(DBG_LIB, "signature scheme %N not supported by %N key",
74: signature_scheme_names, scheme, key_type_names, KEY_ED25519);
75: return FALSE;
76: }
77:
78: if (!data.ptr && !data.len)
79: {
80: data.ptr = dummy;
81: }
82:
83: ret = wc_ed25519_verify_msg(signature.ptr, signature.len, data.ptr,
84: data.len, &res, &this->key);
85: return ret == 0 && res == 1;
86: }
87:
88: METHOD(public_key_t, encrypt, bool,
89: private_public_key_t *this, encryption_scheme_t scheme,
90: chunk_t crypto, chunk_t *plain)
91: {
92: DBG1(DBG_LIB, "encryption scheme %N not supported", encryption_scheme_names,
93: scheme);
94: return FALSE;
95: }
96:
97: METHOD(public_key_t, get_keysize, int,
98: private_public_key_t *this)
99: {
100: return ED25519_KEY_SIZE * 8;
101: }
102:
103: /**
104: * Encode the given public key as ASN.1 DER with algorithm identifier
105: */
106: static bool encode_pubkey(ed25519_key *key, chunk_t *encoding)
107: {
108: int ret;
109:
110: /* account for algorithmIdentifier/bitString */
111: *encoding = chunk_alloc(ED25519_PUB_KEY_SIZE + 2 * MAX_SEQ_SZ +
112: MAX_ALGO_SZ + TRAILING_ZERO);
113: ret = wc_Ed25519PublicKeyToDer(key, encoding->ptr, encoding->len, 1);
114: if (ret < 0)
115: {
116: return FALSE;
117: }
118: encoding->len = ret;
119: return TRUE;
120: }
121:
122: /**
123: * Calculate fingerprint from an EdDSA key, also used in ed private key.
124: */
125: bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type,
126: chunk_t *fp)
127: {
128: hasher_t *hasher;
129: chunk_t blob;
130: word32 len;
131: bool success = FALSE;
132:
133: if (lib->encoding->get_cache(lib->encoding, type, key, fp))
134: {
135: return TRUE;
136: }
137: switch (type)
138: {
139: case KEYID_PUBKEY_SHA1:
140: len = ED25519_PUB_KEY_SIZE;
141: blob = chunk_alloc(len);
142: if (wc_ed25519_export_public(key, blob.ptr, &len) != 0)
143: {
144: return FALSE;
145: }
146: break;
147: case KEYID_PUBKEY_INFO_SHA1:
148: if (!encode_pubkey(key, &blob))
149: {
150: return FALSE;
151: }
152: break;
153: default:
154: return FALSE;
155: }
156: hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
157: if (!hasher || !hasher->allocate_hash(hasher, blob, fp))
158: {
159: DBG1(DBG_LIB, "SHA1 not supported, fingerprinting failed");
160: }
161: else
162: {
163: lib->encoding->cache(lib->encoding, type, key, *fp);
164: success = TRUE;
165: }
166: DESTROY_IF(hasher);
167: chunk_free(&blob);
168: return success;
169: }
170:
171: METHOD(public_key_t, get_fingerprint, bool,
172: private_public_key_t *this, cred_encoding_type_t type, chunk_t *fingerprint)
173: {
174: return wolfssl_ed_fingerprint(&this->key, type, fingerprint);
175: }
176:
177: METHOD(public_key_t, get_encoding, bool,
178: private_public_key_t *this, cred_encoding_type_t type, chunk_t *encoding)
179: {
180: bool success = TRUE;
181:
182: if (!encode_pubkey(&this->key, encoding))
183: {
184: return FALSE;
185: }
186:
187: if (type != PUBKEY_SPKI_ASN1_DER)
188: {
189: chunk_t asn1_encoding = *encoding;
190:
191: success = lib->encoding->encode(lib->encoding, type,
192: NULL, encoding, CRED_PART_EDDSA_PUB_ASN1_DER,
193: asn1_encoding, CRED_PART_END);
194: chunk_free(&asn1_encoding);
195: }
196: return success;
197: }
198:
199: METHOD(public_key_t, get_ref, public_key_t*,
200: private_public_key_t *this)
201: {
202: ref_get(&this->ref);
203: return &this->public;
204: }
205:
206: METHOD(public_key_t, destroy, void,
207: private_public_key_t *this)
208: {
209: if (ref_put(&this->ref))
210: {
211: lib->encoding->clear_cache(lib->encoding, &this->key);
212: wc_ed25519_free(&this->key);
213: free(this);
214: }
215: }
216:
217: /**
218: * Generic private constructor
219: */
220: static private_public_key_t *create_empty()
221: {
222: private_public_key_t *this;
223:
224: INIT(this,
225: .public = {
226: .get_type = _get_type,
227: .verify = _verify,
228: .encrypt = _encrypt,
229: .get_keysize = _get_keysize,
230: .equals = public_key_equals,
231: .get_fingerprint = _get_fingerprint,
232: .has_fingerprint = public_key_has_fingerprint,
233: .get_encoding = _get_encoding,
234: .get_ref = _get_ref,
235: .destroy = _destroy,
236: },
237: .ref = 1,
238: );
239:
240: if (wc_ed25519_init(&this->key) != 0)
241: {
242: free(this);
243: return NULL;
244: }
245: return this;
246: }
247:
248: /*
249: * Described in header
250: */
251: public_key_t *wolfssl_ed_public_key_load(key_type_t type, va_list args)
252: {
253: private_public_key_t *this;
254: chunk_t blob = chunk_empty, pub = chunk_empty;
255: int idx;
256: int ret = -1;
257:
258: while (TRUE)
259: {
260: switch (va_arg(args, builder_part_t))
261: {
262: case BUILD_BLOB_ASN1_DER:
263: blob = va_arg(args, chunk_t);
264: continue;
265: case BUILD_EDDSA_PUB:
266: pub = va_arg(args, chunk_t);
267: continue;
268: case BUILD_END:
269: break;
270: default:
271: return NULL;
272: }
273: break;
274: }
275:
276: this = create_empty();
277: if (!this)
278: {
279: return NULL;
280: }
281:
282: if (pub.len)
283: {
284: ret = wc_ed25519_import_public(pub.ptr, pub.len, &this->key);
285: }
286: else if (blob.len)
287: {
288: idx = 0;
289: ret = wc_Ed25519PublicKeyDecode(blob.ptr, &idx, &this->key, blob.len);
290: }
291: if (ret != 0)
292: {
293: destroy(this);
294: return NULL;
295: }
296: return &this->public;
297: }
298:
299: #endif /* HAVE_ED25519 */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>