/*
+ * Copyright (C) 2018 Tobias Brunner
* Copyright (C) 2016 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
#define ED25519_SUBJECT_PUBLIC_KEY_ALGORITHM 1
#define ED25519_SUBJECT_PUBLIC_KEY 2
+/**
+ * Parse the ASN.1-encoded subjectPublicKeyInfo
+ */
+static bool parse_public_key_info(private_curve25519_public_key_t *this,
+ chunk_t blob)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ bool success = FALSE;
+ int objectID, oid;
+
+ parser = asn1_parser_create(pubkeyObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case ED25519_SUBJECT_PUBLIC_KEY_ALGORITHM:
+ {
+ oid = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser) + 1, NULL);
+ if (oid != OID_ED25519)
+ {
+ goto end;
+ }
+ break;
+ }
+ case ED25519_SUBJECT_PUBLIC_KEY:
+ {
+ /* encoded as an ASN1 BIT STRING */
+ if (object.len != 1 + ED25519_KEY_LEN)
+ {
+ goto end;
+ }
+ this->pubkey = chunk_clone(chunk_skip(object, 1));
+ break;
+ }
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
/**
* See header.
*/
va_list args)
{
private_curve25519_public_key_t *this;
- chunk_t blob = chunk_empty, object;
- asn1_parser_t *parser;
- bool success = FALSE;
- int objectID, oid;
+ chunk_t asn1 = chunk_empty, blob = chunk_empty;
while (TRUE)
{
switch (va_arg(args, builder_part_t))
{
case BUILD_BLOB_ASN1_DER:
+ asn1 = va_arg(args, chunk_t);
+ continue;
+ case BUILD_EDDSA_PUB:
blob = va_arg(args, chunk_t);
continue;
case BUILD_END:
.ref = 1,
);
- parser = asn1_parser_create(pubkeyObjects, blob);
-
- while (parser->iterate(parser, &objectID, &object))
+ if (blob.len == ED25519_KEY_LEN)
{
- switch (objectID)
- {
- case ED25519_SUBJECT_PUBLIC_KEY_ALGORITHM:
- {
- oid = asn1_parse_algorithmIdentifier(object,
- parser->get_level(parser) + 1, NULL);
- if (oid != OID_ED25519)
- {
- goto end;
- }
- break;
- }
- case ED25519_SUBJECT_PUBLIC_KEY:
- {
- /* encoded as an ASN1 BIT STRING */
- if (object.len != 1 + ED25519_KEY_LEN)
- {
- goto end;
- }
- this->pubkey = chunk_clone(chunk_skip(object, 1));
- break;
- }
- }
+ this->pubkey = chunk_clone(blob);
}
- success = parser->success(parser);
-
-end:
- parser->destroy(parser);
- if (!success)
+ else if (!asn1.len || !parse_public_key_info(this, asn1))
{
destroy(this);
return NULL;