result_t
x509_verify_cert_eku (x509_crt *cert, const char * const expected_oid)
{
  result_t fFound = FAILURE;

  if (!(cert->ext_types & EXT_EXTENDED_KEY_USAGE))
    {
      msg (D_HANDSHAKE, "Certificate does not have extended key usage extension");
    }
  else
    {
      x509_sequence *oid_seq = &(cert->ext_key_usage);

      msg (D_HANDSHAKE, "Validating certificate extended key usage");
      while (oid_seq != NULL)
	{
	  x509_buf *oid = &oid_seq->buf;
	  char oid_num_str[1024];
	  const char *oid_str;

	  if (0 == oid_get_extended_key_usage( oid, &oid_str ))
	    {
	      msg (D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s",
		  oid_str, expected_oid);
	      if (!strcmp (expected_oid, oid_str))
		{
		  fFound = SUCCESS;
		  break;
		}
	    }

	  if (0 < oid_get_numeric_string( oid_num_str,
	      sizeof (oid_num_str), oid))
	    {
	      msg (D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s",
		  oid_num_str, expected_oid);
	      if (!strcmp (expected_oid, oid_num_str))
		{
		  fFound = SUCCESS;
		  break;
		}
	    }
	  oid_seq = oid_seq->next;
	}
    }

    return fFound;
}
Exemple #2
0
int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
{
    return oid_get_numeric_string( buf, size, oid );
}
static int x509_get_crt_ext_data(const unsigned char **ext_data,
				 size_t *ext_len,
				 x509_crt *crt,
				 const char *oid)
{
	int ret;
	size_t len;
	unsigned char *end_ext_data, *end_ext_octet;
	unsigned char *p;
	const unsigned char *end;
	char oid_str[64];

	p = crt->v3_ext.p;
	end = crt->v3_ext.p + crt->v3_ext.len;

	ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
	if (ret != 0)
		return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;

	if (end != p + len)
		return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
				POLARSSL_ERR_ASN1_LENGTH_MISMATCH;

	while (p < end) {
		/*
		 * Extension  ::=  SEQUENCE  {
		 *      extnID      OBJECT IDENTIFIER,
		 *      critical    BOOLEAN DEFAULT FALSE,
		 *      extnValue   OCTET STRING  }
		 */
		x509_buf extn_oid = {0, 0, NULL};
		int is_critical = 0; /* DEFAULT FALSE */

		ret = asn1_get_tag(&p, end, &len,
				ASN1_CONSTRUCTED | ASN1_SEQUENCE);
		if (ret != 0)
			return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;

		end_ext_data = p + len;

		/* Get extension ID */
		extn_oid.tag = *p;

		ret = asn1_get_tag(&p, end, &extn_oid.len, ASN1_OID);
		if (ret != 0)
			return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;

		extn_oid.p = p;
		p += extn_oid.len;

		if ((end - p) < 1)
			return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
					POLARSSL_ERR_ASN1_OUT_OF_DATA;

		/* Get optional critical */
		ret = asn1_get_bool(&p, end_ext_data, &is_critical);
		if (ret != 0 && (ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG))
			return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;

		/* Data should be octet string type */
		ret = asn1_get_tag(&p, end_ext_data, &len, ASN1_OCTET_STRING);
		if (ret != 0)
			return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;

		end_ext_octet = p + len;

		if (end_ext_octet != end_ext_data)
			return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
					POLARSSL_ERR_ASN1_LENGTH_MISMATCH;

		/* Detect requested extension */
		oid_get_numeric_string(oid_str, 64, &extn_oid);
		if (memcmp(oid, oid_str, sizeof(oid)) == 0) {
			*ext_data = p;
			*ext_len = len;
			return 0;
		}

		/* Next */
		p = end_ext_octet;
	}

	if (p != end)
		return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
				POLARSSL_ERR_ASN1_LENGTH_MISMATCH;

	return POLARSSL_ERR_X509_UNKNOWN_OID;
}