|
1 | 1 | /* |
| 2 | + * Copyright (C) 2018 Tobias Brunner |
2 | 3 | * Copyright (C) 2016 Andreas Steffen |
3 | 4 | * HSR Hochschule fuer Technik Rapperswil |
4 | 5 | * |
@@ -199,23 +200,69 @@ static const asn1Object_t pubkeyObjects[] = { |
199 | 200 | #define ED25519_SUBJECT_PUBLIC_KEY_ALGORITHM 1 |
200 | 201 | #define ED25519_SUBJECT_PUBLIC_KEY 2 |
201 | 202 |
|
| 203 | +/** |
| 204 | + * Parse the ASN.1-encoded subjectPublicKeyInfo |
| 205 | + */ |
| 206 | +static bool parse_public_key_info(private_curve25519_public_key_t *this, |
| 207 | + chunk_t blob) |
| 208 | +{ |
| 209 | + asn1_parser_t *parser; |
| 210 | + chunk_t object; |
| 211 | + bool success = FALSE; |
| 212 | + int objectID, oid; |
| 213 | + |
| 214 | + parser = asn1_parser_create(pubkeyObjects, blob); |
| 215 | + |
| 216 | + while (parser->iterate(parser, &objectID, &object)) |
| 217 | + { |
| 218 | + switch (objectID) |
| 219 | + { |
| 220 | + case ED25519_SUBJECT_PUBLIC_KEY_ALGORITHM: |
| 221 | + { |
| 222 | + oid = asn1_parse_algorithmIdentifier(object, |
| 223 | + parser->get_level(parser) + 1, NULL); |
| 224 | + if (oid != OID_ED25519) |
| 225 | + { |
| 226 | + goto end; |
| 227 | + } |
| 228 | + break; |
| 229 | + } |
| 230 | + case ED25519_SUBJECT_PUBLIC_KEY: |
| 231 | + { |
| 232 | + /* encoded as an ASN1 BIT STRING */ |
| 233 | + if (object.len != 1 + ED25519_KEY_LEN) |
| 234 | + { |
| 235 | + goto end; |
| 236 | + } |
| 237 | + this->pubkey = chunk_clone(chunk_skip(object, 1)); |
| 238 | + break; |
| 239 | + } |
| 240 | + } |
| 241 | + } |
| 242 | + success = parser->success(parser); |
| 243 | + |
| 244 | +end: |
| 245 | + parser->destroy(parser); |
| 246 | + return success; |
| 247 | +} |
| 248 | + |
202 | 249 | /** |
203 | 250 | * See header. |
204 | 251 | */ |
205 | 252 | curve25519_public_key_t *curve25519_public_key_load(key_type_t type, |
206 | 253 | va_list args) |
207 | 254 | { |
208 | 255 | private_curve25519_public_key_t *this; |
209 | | - chunk_t blob = chunk_empty, object; |
210 | | - asn1_parser_t *parser; |
211 | | - bool success = FALSE; |
212 | | - int objectID, oid; |
| 256 | + chunk_t asn1 = chunk_empty, blob = chunk_empty; |
213 | 257 |
|
214 | 258 | while (TRUE) |
215 | 259 | { |
216 | 260 | switch (va_arg(args, builder_part_t)) |
217 | 261 | { |
218 | 262 | case BUILD_BLOB_ASN1_DER: |
| 263 | + asn1 = va_arg(args, chunk_t); |
| 264 | + continue; |
| 265 | + case BUILD_EDDSA_PUB: |
219 | 266 | blob = va_arg(args, chunk_t); |
220 | 267 | continue; |
221 | 268 | case BUILD_END: |
@@ -244,39 +291,11 @@ curve25519_public_key_t *curve25519_public_key_load(key_type_t type, |
244 | 291 | .ref = 1, |
245 | 292 | ); |
246 | 293 |
|
247 | | - parser = asn1_parser_create(pubkeyObjects, blob); |
248 | | - |
249 | | - while (parser->iterate(parser, &objectID, &object)) |
| 294 | + if (blob.len == ED25519_KEY_LEN) |
250 | 295 | { |
251 | | - switch (objectID) |
252 | | - { |
253 | | - case ED25519_SUBJECT_PUBLIC_KEY_ALGORITHM: |
254 | | - { |
255 | | - oid = asn1_parse_algorithmIdentifier(object, |
256 | | - parser->get_level(parser) + 1, NULL); |
257 | | - if (oid != OID_ED25519) |
258 | | - { |
259 | | - goto end; |
260 | | - } |
261 | | - break; |
262 | | - } |
263 | | - case ED25519_SUBJECT_PUBLIC_KEY: |
264 | | - { |
265 | | - /* encoded as an ASN1 BIT STRING */ |
266 | | - if (object.len != 1 + ED25519_KEY_LEN) |
267 | | - { |
268 | | - goto end; |
269 | | - } |
270 | | - this->pubkey = chunk_clone(chunk_skip(object, 1)); |
271 | | - break; |
272 | | - } |
273 | | - } |
| 296 | + this->pubkey = chunk_clone(blob); |
274 | 297 | } |
275 | | - success = parser->success(parser); |
276 | | - |
277 | | -end: |
278 | | - parser->destroy(parser); |
279 | | - if (!success) |
| 298 | + else if (!asn1.len || !parse_public_key_info(this, asn1)) |
280 | 299 | { |
281 | 300 | destroy(this); |
282 | 301 | return NULL; |
|
0 commit comments