int rsa_private_key_from_der_iterator(struct rsa_public_key *pub, struct rsa_private_key *priv, unsigned limit, struct asn1_der_iterator *i) { /* RSAPrivateKey ::= SEQUENCE { version Version, modulus INTEGER, -- n publicExponent INTEGER, -- e privateExponent INTEGER, -- d prime1 INTEGER, -- p prime2 INTEGER, -- q exponent1 INTEGER, -- d mod (p-1) exponent2 INTEGER, -- d mod (q-1) coefficient INTEGER, -- (inverse of q) mod p otherPrimeInfos OtherPrimeInfos OPTIONAL } */ uint32_t version; if (i->type != ASN1_SEQUENCE) return 0; if (asn1_der_decode_constructed_last(i) == ASN1_ITERATOR_PRIMITIVE && i->type == ASN1_INTEGER && asn1_der_get_uint32(i, &version) && version <= 1 && GET(i, pub->n, limit) && GET(i, pub->e, limit) && rsa_public_key_prepare(pub) && GET(i, priv->d, limit) && GET(i, priv->p, limit) && GET(i, priv->q, limit) && GET(i, priv->a, limit) && GET(i, priv->b, limit) && GET(i, priv->c, limit) && rsa_private_key_prepare(priv)) { if (version == 1) { /* otherPrimeInfos must be present. We ignore the contents */ if (!(asn1_der_iterator_next(i) == ASN1_ITERATOR_CONSTRUCTED && i->type == ASN1_SEQUENCE)) return 0; } return (asn1_der_iterator_next(i) == ASN1_ITERATOR_END); } return 0; }
enum asn1_iterator_result asn1_der_iterator_first(struct asn1_der_iterator *i, unsigned length, const uint8_t *input) { asn1_der_iterator_init(i, length, input); return asn1_der_iterator_next(i); }
int rsa_public_key_from_der_iterator(struct rsa_public_key *pub, unsigned limit, struct asn1_der_iterator *i) { /* RSAPublicKey ::= SEQUENCE { modulus INTEGER, -- n publicExponent INTEGER -- e } */ return (i->type == ASN1_SEQUENCE && asn1_der_decode_constructed_last(i) == ASN1_ITERATOR_PRIMITIVE && asn1_der_get_bignum(i, pub->n, limit) && mpz_sgn(pub->n) > 0 && GET(i, pub->e, limit) && asn1_der_iterator_next(i) == ASN1_ITERATOR_END && rsa_public_key_prepare(pub)); }
static char * _verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock, unsigned int sigblock_len, unsigned char* key, unsigned int keylen) { uint8_t digest[SHA1_DIGEST_SIZE]; uint8_t key_t_value; int res = 0; size_t offset; struct dsa_public_key pubkey; struct dsa_signature signature; unsigned int expected_len; /* Extract DSA signature from the record */ nettle_dsa_signature_init(&signature); /* Signature length: 41 bytes - RFC 2536 sec. 3 */ if(sigblock_len == 41) { if(key[0] != sigblock[0]) return "invalid T value in DSA signature or pubkey"; nettle_mpz_set_str_256_u(signature.r, 20, sigblock+1); nettle_mpz_set_str_256_u(signature.s, 20, sigblock+1+20); } else { /* DER encoded, decode the ASN1 notated R and S bignums */ /* SEQUENCE { r INTEGER, s INTEGER } */ struct asn1_der_iterator i, seq; if(asn1_der_iterator_first(&i, sigblock_len, (uint8_t*)sigblock) != ASN1_ITERATOR_CONSTRUCTED || i.type != ASN1_SEQUENCE) return "malformed DER encoded DSA signature"; /* decode this element of i using the seq iterator */ if(asn1_der_decode_constructed(&i, &seq) != ASN1_ITERATOR_PRIMITIVE || seq.type != ASN1_INTEGER) return "malformed DER encoded DSA signature"; if(!asn1_der_get_bignum(&seq, signature.r, 20*8)) return "malformed DER encoded DSA signature"; if(asn1_der_iterator_next(&seq) != ASN1_ITERATOR_PRIMITIVE || seq.type != ASN1_INTEGER) return "malformed DER encoded DSA signature"; if(!asn1_der_get_bignum(&seq, signature.s, 20*8)) return "malformed DER encoded DSA signature"; if(asn1_der_iterator_next(&i) != ASN1_ITERATOR_END) return "malformed DER encoded DSA signature"; } /* Validate T values constraints - RFC 2536 sec. 2 & sec. 3 */ key_t_value = key[0]; if (key_t_value > 8) { return "invalid T value in DSA pubkey"; } /* Pubkey minimum length: 21 bytes - RFC 2536 sec. 2 */ if (keylen < 21) { return "DSA pubkey too short"; } expected_len = 1 + /* T */ 20 + /* Q */ (64 + key_t_value*8) + /* P */ (64 + key_t_value*8) + /* G */ (64 + key_t_value*8); /* Y */ if (keylen != expected_len ) { return "invalid DSA pubkey length"; } /* Extract DSA pubkey from the record */ nettle_dsa_public_key_init(&pubkey); offset = 1; nettle_mpz_set_str_256_u(pubkey.q, 20, key+offset); offset += 20; nettle_mpz_set_str_256_u(pubkey.p, (64 + key_t_value*8), key+offset); offset += (64 + key_t_value*8); nettle_mpz_set_str_256_u(pubkey.g, (64 + key_t_value*8), key+offset); offset += (64 + key_t_value*8); nettle_mpz_set_str_256_u(pubkey.y, (64 + key_t_value*8), key+offset); /* Digest content of "buf" and verify its DSA signature in "sigblock"*/ res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf), (unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest); res &= dsa_sha1_verify_digest(&pubkey, digest, &signature); /* Clear and return */ nettle_dsa_signature_clear(&signature); nettle_dsa_public_key_clear(&pubkey); if (!res) return "DSA signature verification failed"; else return NULL; }
/* Returns 1 on success, 0 on error, and -1 for unsupported algorithms. */ static int convert_public_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data) { /* SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING } AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters OPTIONAL } */ struct asn1_der_iterator i; struct asn1_der_iterator j; int res = 0; if (asn1_der_iterator_first(&i, length, data) == ASN1_ITERATOR_CONSTRUCTED && i.type == ASN1_SEQUENCE && asn1_der_decode_constructed_last(&i) == ASN1_ITERATOR_CONSTRUCTED && i.type == ASN1_SEQUENCE /* Use the j iterator to parse the algorithm identifier */ && asn1_der_decode_constructed(&i, &j) == ASN1_ITERATOR_PRIMITIVE && j.type == ASN1_IDENTIFIER && asn1_der_iterator_next(&i) == ASN1_ITERATOR_PRIMITIVE && i.type == ASN1_BITSTRING /* Use i to parse the object wrapped in the bit string.*/ && asn1_der_decode_bitstring_last(&i)) { /* pkcs-1 { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) modules(0) pkcs-1(1) } -- -- When rsaEncryption is used in an AlgorithmIdentifier the -- parameters MUST be present and MUST be NULL. -- rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */ static const uint8_t id_rsaEncryption[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 }; /* -- -- When dsa is used in an AlgorithmIdentifier the -- parameters MUST be present and MUST NOT be NULL. -- dsa OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 } */ static const uint8_t id_dsa[7] = { 0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01 }; switch (j.length) { unknown: default: werror("SubjectPublicKeyInfo: Unsupported algorithm.\n"); res = -1; break; case 7: if (memcmp(j.data, id_dsa, 7) == 0) { if (asn1_der_iterator_next(&j) == ASN1_ITERATOR_CONSTRUCTED && asn1_der_decode_constructed_last(&j) == ASN1_ITERATOR_PRIMITIVE) { struct dsa_public_key pub; dsa_public_key_init(&pub); if (dsa_params_from_der_iterator(&pub, 0, &i) && dsa_public_key_from_der_iterator(&pub, 0, &j)) { nettle_buffer_reset(buffer); res = dsa_keypair_to_sexp(buffer, NULL, &pub, NULL) > 0; } } if (!res) werror("SubjectPublicKeyInfo: Invalid DSA key.\n"); break; } else goto unknown; case 9: if (memcmp(j.data, id_rsaEncryption, 9) == 0) { if (asn1_der_iterator_next(&j) == ASN1_ITERATOR_PRIMITIVE && j.type == ASN1_NULL && j.length == 0 && asn1_der_iterator_next(&j) == ASN1_ITERATOR_END) { struct rsa_public_key pub; rsa_public_key_init(&pub); if (rsa_public_key_from_der_iterator(&pub, 0, &i)) { nettle_buffer_reset(buffer); res = rsa_keypair_to_sexp(buffer, NULL, &pub, NULL) > 0; } } if (!res) werror("SubjectPublicKeyInfo: Invalid RSA key.\n"); break; } else goto unknown; } } else werror("SubjectPublicKeyInfo: Invalid object.\n"); return res; }