示例#1
0
static int x509_get_basic_constraints( unsigned char **p,
                                       const unsigned char *end,
                                       int *ca_istrue,
                                       int *max_pathlen )
{
    int ret;
    size_t len;

    /*
     * BasicConstraints ::= SEQUENCE {
     *      cA                      BOOLEAN DEFAULT FALSE,
     *      pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
     */
    *ca_istrue = 0; /* DEFAULT FALSE */
    *max_pathlen = 0; /* endless */

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

    if( *p == end )
        return 0;

    if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
    {
        if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
            ret = asn1_get_int( p, end, ca_istrue );

        if( ret != 0 )
            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );

        if( *ca_istrue != 0 )
            *ca_istrue = 1;
    }

    if( *p == end )
        return 0;

    if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );

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

    (*max_pathlen)++;

    return 0;
}
示例#2
0
文件: x509.c 项目: slaff/axtls-8266
/**
 * Basic constraints - see https://tools.ietf.org/html/rfc5280#page-39
 */
static int x509_v3_basic_constraints(const uint8_t *cert, int offset, 
        X509_CTX *x509_ctx)
{
    int ret = X509_OK;
    int lenSeq = 0;

    if ((offset = asn1_is_basic_constraints(cert, offset)) == 0)
        goto end_contraints;

    x509_ctx->basic_constraint_present = true;
    x509_ctx->basic_constraint_is_critical = 
                    asn1_is_critical_ext(cert, &offset);

    /* Assign Defaults in case not specified
    basic_constraint_cA will already by zero by virtue of the calloc */
    x509_ctx->basic_constraint_cA = 0;
    /* basic_constraint_pathLenConstraint is unlimited by default. 
    10000 is just a large number (limits.h is not already included) */
    x509_ctx->basic_constraint_pathLenConstraint = 10000;
    
    if ((asn1_next_obj(cert, &offset, ASN1_OCTET_STRING) < 0) ||
            ((lenSeq = asn1_next_obj(cert, &offset, ASN1_SEQUENCE)) < 0))
    {
        ret = X509_NOT_OK;       
    }
    
    /* If the Sequence Length is greater than zero, 
    continue with the basic_constraint_cA */
    if ((lenSeq>0)&&(asn1_get_bool(cert, &offset, 
            &x509_ctx->basic_constraint_cA) < 0))
    {
        ret = X509_NOT_OK;
    }
    
    /* If the Sequence Length is greater than 3, it has more content than 
    the basic_constraint_cA bool, so grab the pathLenConstraint */
    if ((lenSeq>3) && (asn1_get_int(cert, &offset, 
            &x509_ctx->basic_constraint_pathLenConstraint) < 0))
    {
        ret = X509_NOT_OK;
    }

end_contraints:
    return ret;
}
示例#3
0
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;
}
示例#4
0
文件: x509_read.c 项目: ebichu/dd-wrt
/*
 * X.509 v3 extensions (only BasicConstraints are parsed)
 */
static int x509_get_ext( unsigned char **p,
                         unsigned char *end,
                         x509_buf *ext,
                         int *ca_istrue,
                         int *max_pathlen )
{
    int ret, len;
    int is_critical = 1;
    int is_cacert   = 0;
    unsigned char *end2;

    if( *p == end )
        return( 0 );

    ext->tag = **p;

    if( ( ret = asn1_get_tag( p, end, &ext->len,
            ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 )
    {
        if( ret == ERR_ASN1_UNEXPECTED_TAG )
            return( 0 );

        return( ret );
    }

    ext->p = *p;
    end = *p + ext->len;

    /*
     * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
     *
     * Extension  ::=  SEQUENCE  {
     *      extnID      OBJECT IDENTIFIER,
     *      critical    BOOLEAN DEFAULT FALSE,
     *      extnValue   OCTET STRING  }
     */
    if( ( ret = asn1_get_tag( p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
        return( ERR_X509_CERT_INVALID_EXTENSIONS | ret );

    if( end != *p + len )
        return( ERR_X509_CERT_INVALID_EXTENSIONS |
                ERR_ASN1_LENGTH_MISMATCH );

    while( *p < end )
    {
        if( ( ret = asn1_get_tag( p, end, &len,
                ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
            return( ERR_X509_CERT_INVALID_EXTENSIONS | ret );

        if( memcmp( *p, "\x06\x03\x55\x1D\x13", 5 ) != 0 )
        {
            *p += len;
            continue;
        }

        *p += 5;

        if( ( ret = asn1_get_bool( p, end, &is_critical ) ) != 0 &&
            ( ret != ERR_ASN1_UNEXPECTED_TAG ) )
            return( ERR_X509_CERT_INVALID_EXTENSIONS | ret );

        if( ( ret = asn1_get_tag( p, end, &len,
                ASN1_OCTET_STRING ) ) != 0 )
            return( ERR_X509_CERT_INVALID_EXTENSIONS | ret );

        /*
         * BasicConstraints ::= SEQUENCE {
         *      cA                      BOOLEAN DEFAULT FALSE,
         *      pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
         */
        end2 = *p + len;

        if( ( ret = asn1_get_tag( p, end2, &len,
                ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
            return( ERR_X509_CERT_INVALID_EXTENSIONS | ret );

        if( *p == end2 )
            continue;

        if( ( ret = asn1_get_bool( p, end2, &is_cacert ) ) != 0 )
            return( ERR_X509_CERT_INVALID_EXTENSIONS | ret );

        if( *p == end2 )
            continue;

        if( ( ret = asn1_get_int( p, end2, max_pathlen ) ) != 0 )
            return( ERR_X509_CERT_INVALID_EXTENSIONS | ret );

        if( *p != end2 )
            return( ERR_X509_CERT_INVALID_EXTENSIONS |
                    ERR_ASN1_LENGTH_MISMATCH );

        max_pathlen++;
    }

    if( *p != end )
        return( ERR_X509_CERT_INVALID_EXTENSIONS |
                ERR_ASN1_LENGTH_MISMATCH );

    *ca_istrue = is_critical & is_cacert;

    return( 0 );
}
示例#5
0
/*
 * X.509 v3 extensions
 *
 * TODO: Perform all of the basic constraints tests required by the RFC
 * TODO: Set values for undetected extensions to a sane default?
 *
 */
static int x509_get_crt_ext( unsigned char **p,
                             const unsigned char *end,
                             x509_crt *crt )
{
    int ret;
    size_t len;
    unsigned char *end_ext_data, *end_ext_octet;

    if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
    {
        if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
            return( 0 );

        return( ret );
    }

    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 */
        int ext_type = 0;

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

        end_ext_data = *p + len;

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

        if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 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 */
        if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
            ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
            return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );

        /* Data should be octet string type */
        if( ( ret = asn1_get_tag( p, end_ext_data, &len,
                ASN1_OCTET_STRING ) ) != 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 supported extensions
         */
        ret = oid_get_x509_ext_type( &extn_oid, &ext_type );

        if( ret != 0 )
        {
            /* No parser found, skip extension */
            *p = end_ext_octet;

#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
            if( is_critical )
            {
                /* Data is marked as critical: fail */
                return ( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
                        POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
            }
#endif
            continue;
        }

        crt->ext_types |= ext_type;

        switch( ext_type )
        {
        case EXT_BASIC_CONSTRAINTS:
            /* Parse basic constraints */
            if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
                    &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
                return ( ret );
            break;

        case EXT_KEY_USAGE:
            /* Parse key usage */
            if( ( ret = x509_get_key_usage( p, end_ext_octet,
                    &crt->key_usage ) ) != 0 )
                return ( ret );
            break;

        case EXT_EXTENDED_KEY_USAGE:
            /* Parse extended key usage */
            if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
                    &crt->ext_key_usage ) ) != 0 )
                return ( ret );
            break;

        case EXT_SUBJECT_ALT_NAME:
            /* Parse subject alt name */
            if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
                    &crt->subject_alt_names ) ) != 0 )
                return ( ret );
            break;

        case EXT_NS_CERT_TYPE:
            /* Parse netscape certificate type */
            if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
                    &crt->ns_cert_type ) ) != 0 )
                return ( ret );
            break;

        default:
            return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
        }
    }

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

    return( 0 );
}