Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
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));
}
Ejemplo n.º 4
0
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;
}