Пример #1
0
asn1_named_data *asn1_store_named_data( asn1_named_data **head,
                                        const char *oid, size_t oid_len,
                                        const unsigned char *val,
                                        size_t val_len )
{
    asn1_named_data *cur;

    if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
    {
        // Add new entry if not present yet based on OID
        //
        if( ( cur = polarssl_malloc( sizeof(asn1_named_data) ) ) == NULL )
            return( NULL );

        memset( cur, 0, sizeof(asn1_named_data) );

        cur->oid.len = oid_len;
        cur->oid.p = polarssl_malloc( oid_len );
        if( cur->oid.p == NULL )
        {
            polarssl_free( cur );
            return( NULL );
        }

        cur->val.len = val_len;
        cur->val.p = polarssl_malloc( val_len );
        if( cur->val.p == NULL )
        {
            polarssl_free( cur->oid.p );
            polarssl_free( cur );
            return( NULL );
        }

        memcpy( cur->oid.p, oid, oid_len );

        cur->next = *head;
        *head = cur;
    }
    else if( cur->val.len < val_len )
    {
        // Enlarge existing value buffer if needed
        //
        polarssl_free( cur->val.p );
        cur->val.p = NULL;

        cur->val.len = val_len;
        cur->val.p = polarssl_malloc( val_len );
        if( cur->val.p == NULL )
        {
            polarssl_free( cur->oid.p );
            polarssl_free( cur );
            return( NULL );
        }
    }

    if( val != NULL )
        memcpy( cur->val.p, val, val_len );

    return( cur );
}
Пример #2
0
/*
 *  Name ::= CHOICE { -- only one possibility for now --
 *       rdnSequence  RDNSequence }
 *
 *  RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
 *
 *  RelativeDistinguishedName ::=
 *    SET OF AttributeTypeAndValue
 *
 *  AttributeTypeAndValue ::= SEQUENCE {
 *    type     AttributeType,
 *    value    AttributeValue }
 *
 *  AttributeType ::= OBJECT IDENTIFIER
 *
 *  AttributeValue ::= ANY DEFINED BY AttributeType
 *
 * The data structure is optimized for the common case where each RDN has only
 * one element, which is represented as a list of AttributeTypeAndValue.
 * For the general case we still use a flat list, but we mark elements of the
 * same set so that they are "merged" together in the functions that consume
 * this list, eg x509_dn_gets().
 */
int x509_get_name( unsigned char **p, const unsigned char *end,
                   x509_name *cur )
{
    int ret;
    size_t set_len;
    const unsigned char *end_set;

    /* don't use recursion, we'd risk stack overflow if not optimized */
    while( 1 )
    {
        /*
         * parse SET
         */
        if( ( ret = asn1_get_tag( p, end, &set_len,
                                  ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
            return( POLARSSL_ERR_X509_INVALID_NAME + ret );

        end_set  = *p + set_len;

        while( 1 )
        {
            if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
                return( ret );

            if( *p == end_set )
                break;

            /* Mark this item as being not the only one in a set */
            cur->next_merged = 1;

            cur->next = polarssl_malloc( sizeof( x509_name ) );

            if( cur->next == NULL )
                return( POLARSSL_ERR_X509_MALLOC_FAILED );

            memset( cur->next, 0, sizeof( x509_name ) );

            cur = cur->next;
        }

        /*
         * continue until end of SEQUENCE is reached
         */
        if( *p == end )
            return( 0 );

        cur->next = polarssl_malloc( sizeof( x509_name ) );

        if( cur->next == NULL )
            return( POLARSSL_ERR_X509_MALLOC_FAILED );

        memset( cur->next, 0, sizeof( x509_name ) );

        cur = cur->next;
    }
}
Пример #3
0
/*
 *  RelativeDistinguishedName ::=
 *    SET OF AttributeTypeAndValue
 *
 *  AttributeTypeAndValue ::= SEQUENCE {
 *    type     AttributeType,
 *    value    AttributeValue }
 *
 *  AttributeType ::= OBJECT IDENTIFIER
 *
 *  AttributeValue ::= ANY DEFINED BY AttributeType
 */
int x509_get_name( unsigned char **p, const unsigned char *end,
                   x509_name *cur )
{
    int ret;
    size_t len;
    const unsigned char *end2;
    x509_name *use;

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

    end2 = end;
    end  = *p + len;
    use = cur;

    do
    {
        if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
            return( ret );

        if( *p != end )
        {
            use->next = (x509_name *) polarssl_malloc(
                    sizeof( x509_name ) );

            if( use->next == NULL )
                return( POLARSSL_ERR_X509_MALLOC_FAILED );

            memset( use->next, 0, sizeof( x509_name ) );

            use = use->next;
        }
    }
    while( *p != end );

    /*
     * recurse until end of SEQUENCE is reached
     */
    if( *p == end2 )
        return( 0 );

    cur->next = (x509_name *) polarssl_malloc(
         sizeof( x509_name ) );

    if( cur->next == NULL )
        return( POLARSSL_ERR_X509_MALLOC_FAILED );

    memset( cur->next, 0, sizeof( x509_name ) );

    return( x509_get_name( p, end2, cur->next ) );
}
Пример #4
0
static void *eckey_alloc_wrap( void )
{
    void *ctx = polarssl_malloc( sizeof( ecp_keypair ) );

    if( ctx != NULL )
        ecp_keypair_init( ctx );

    return( ctx );
}
Пример #5
0
static void *rsa_alloc_wrap( void )
{
    void *ctx = polarssl_malloc( sizeof( rsa_context ) );

    if( ctx != NULL )
        rsa_init( (rsa_context *) ctx, 0, 0 );

    return ctx;
}
Пример #6
0
static void *rsa_alt_alloc_wrap( void )
{
    void *ctx = polarssl_malloc( sizeof( rsa_alt_context ) );

    if( ctx != NULL )
        memset( ctx, 0, sizeof( rsa_alt_context ) );

    return ctx;
}
Пример #7
0
static void *ecdsa_alloc_wrap( void )
{
    void *ctx = polarssl_malloc( sizeof( ecdsa_context ) );

    if( ctx != NULL )
        ecdsa_init( (ecdsa_context *) ctx );

    return( ctx );
}
static void *tts_alloc( void )
{
    void *ctx = polarssl_malloc( sizeof( tts_context ) );

    if( ctx != NULL )
    {
        memset( ctx, 0, sizeof( tts_context ) );
    }

    return( ctx );
}
Пример #9
0
static void * aes_ctx_alloc( void )
{
    aes_context *aes = (aes_context *) polarssl_malloc( sizeof( aes_context ) );

    if( aes == NULL )
        return( NULL );

    aes_init( aes );

    return( aes );
}
Пример #10
0
static void * des_ctx_alloc( void )
{
    des_context *des = (des_context *) polarssl_malloc( sizeof( des_context ) );

    if( des == NULL )
        return( NULL );

    des_init( des );

    return( des );
}
Пример #11
0
static void * blowfish_ctx_alloc( void )
{
    blowfish_context *ctx;
    ctx = (blowfish_context *) polarssl_malloc( sizeof( blowfish_context ) );

    if( ctx == NULL )
        return( NULL );

    blowfish_init( ctx );

    return( ctx );
}
Пример #12
0
static void * camellia_ctx_alloc( void )
{
    camellia_context *ctx;
    ctx = (camellia_context *) polarssl_malloc( sizeof( camellia_context ) );

    if( ctx == NULL )
        return( NULL );

    camellia_init( ctx );

    return( ctx );
}
Пример #13
0
static void * arc4_ctx_alloc( void )
{
    arc4_context *ctx;
    ctx = (arc4_context *) polarssl_malloc( sizeof( arc4_context ) );

    if( ctx == NULL )
        return( NULL );

    arc4_init( ctx );

    return( ctx );
}
Пример #14
0
static void * ripemd160_ctx_alloc( void )
{
    ripemd160_context *ctx;
    ctx = (ripemd160_context *) polarssl_malloc( sizeof( ripemd160_context ) );

    if( ctx == NULL )
        return( NULL );

    ripemd160_init( ctx );

    return( ctx );
}
Пример #15
0
static void * sha512_ctx_alloc( void )
{
    sha512_context *ctx;
    ctx = (sha512_context *) polarssl_malloc( sizeof( sha512_context ) );

    if( ctx == NULL )
        return( NULL );

    sha512_init( ctx );

    return( ctx );
}
Пример #16
0
/*
 *  Parses and splits an ASN.1 "SEQUENCE OF <tag>"
 */
int asn1_get_sequence_of( unsigned char **p,
                          const unsigned char *end,
                          asn1_sequence *cur,
                          int tag)
{
    int ret;
    size_t len;
    asn1_buf *buf;

    /* Get main sequence tag */
    if( ( ret = asn1_get_tag( p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
        return( ret );

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

    while( *p < end )
    {
        buf = &(cur->buf);
        buf->tag = **p;

        if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
            return( ret );

        buf->p = *p;
        *p += buf->len;

        /* Allocate and assign next pointer */
        if (*p < end)
        {
            cur->next = (asn1_sequence *) polarssl_malloc(
                 sizeof( asn1_sequence ) );

            if( cur->next == NULL )
                return( POLARSSL_ERR_ASN1_MALLOC_FAILED );

            memset( cur->next, 0, sizeof( asn1_sequence ) );

            cur = cur->next;
        }
    }

    /* Set final sequence entry's next pointer to NULL */
    cur->next = NULL;

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

    return( 0 );
}
Пример #17
0
int pkcs11_x509_cert_init( x509_crt *cert, pkcs11h_certificate_t pkcs11_cert )
{
    int ret = 1;
    unsigned char *cert_blob = NULL;
    size_t cert_blob_size = 0;

    if( cert == NULL )
    {
        ret = 2;
        goto cleanup;
    }

    if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL,
                                                &cert_blob_size ) != CKR_OK )
    {
        ret = 3;
        goto cleanup;
    }

    cert_blob = polarssl_malloc( cert_blob_size );
    if( NULL == cert_blob )
    {
        ret = 4;
        goto cleanup;
    }

    if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob,
                                                &cert_blob_size ) != CKR_OK )
    {
        ret = 5;
        goto cleanup;
    }

    if( 0 != x509_crt_parse( cert, cert_blob, cert_blob_size ) )
    {
        ret = 6;
        goto cleanup;
    }

    ret = 0;

cleanup:
    if( NULL != cert_blob )
        polarssl_free( cert_blob );

    return( ret );
}
Пример #18
0
/*
 * Parse one X.509 certificate in DER format from a buffer and add them to a
 * chained list
 */
int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf,
                        size_t buflen )
{
    int ret;
    x509_crt *crt = chain, *prev = NULL;

    /*
     * Check for valid input
     */
    if( crt == NULL || buf == NULL )
        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );

    while( crt->version != 0 && crt->next != NULL )
    {
        prev = crt;
        crt = crt->next;
    }

    /*
     * Add new certificate on the end of the chain if needed.
     */
    if ( crt->version != 0 && crt->next == NULL)
    {
        crt->next = (x509_crt *) polarssl_malloc( sizeof( x509_crt ) );

        if( crt->next == NULL )
            return( POLARSSL_ERR_X509_MALLOC_FAILED );

        prev = crt;
        crt = crt->next;
        x509_crt_init( crt );
    }

    if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
    {
        if( prev )
            prev->next = NULL;

        if( crt != chain )
            polarssl_free( crt );

        return( ret );
    }

    return( 0 );
}
Пример #19
0
/*
 * Get signature algorithm from alg OID and optional parameters
 */
int x509_get_sig_alg( const x509_buf *sig_oid, const x509_buf *sig_params,
                      md_type_t *md_alg, pk_type_t *pk_alg,
                      void **sig_opts )
{
    int ret;

    if( *sig_opts != NULL )
        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );

    if( ( ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
        return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );

#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
    if( *pk_alg == POLARSSL_PK_RSASSA_PSS )
    {
        pk_rsassa_pss_options *pss_opts;

        pss_opts = polarssl_malloc( sizeof( pk_rsassa_pss_options ) );
        if( pss_opts == NULL )
            return( POLARSSL_ERR_X509_MALLOC_FAILED );

        ret = x509_get_rsassa_pss_params( sig_params,
                                          md_alg,
                                          &pss_opts->mgf1_hash_id,
                                          &pss_opts->expected_salt_len );
        if( ret != 0 )
        {
            polarssl_free( pss_opts );
            return( ret );
        }

        *sig_opts = (void *) pss_opts;
    }
    else
#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
    {
        /* Make sure parameters are absent or NULL */
        if( ( sig_params->tag != ASN1_NULL && sig_params->tag != 0 ) ||
                sig_params->len != 0 )
            return( POLARSSL_ERR_X509_INVALID_ALG );
    }

    return( 0 );
}
Пример #20
0
char *debug_fmt( const char *format, ... )
{
    va_list argp;
#if defined(POLARSSL_THREADING_C)
    char *str = polarssl_malloc( DEBUG_BUF_SIZE );

    if( str == NULL )
        return( NULL );
#else
    static char str[DEBUG_BUF_SIZE];
#endif

    va_start( argp, format );
    vsnprintf( str, DEBUG_BUF_SIZE - 1, format, argp );
    va_end( argp );

    str[DEBUG_BUF_SIZE - 1] = '\0';
    return( str );
}
Пример #21
0
/*
 * Load all data from a file into a given buffer.
 */
static int load_file( const char *path, unsigned char **buf, size_t *n )
{
    FILE *f;
    long size;

    if( ( f = fopen( path, "rb" ) ) == NULL )
        return( -1 );

    fseek( f, 0, SEEK_END );
    if( ( size = ftell( f ) ) == -1 )
    {
        fclose( f );
        return( -1 );
    }
    fseek( f, 0, SEEK_SET );

    *n = (size_t) size;

    if( *n + 1 == 0 ||
        ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
    {
        fclose( f );
        return( -1 );
    }

    if( fread( *buf, 1, *n, f ) != *n )
    {
        fclose( f );
        free( *buf );
        *buf = NULL;
        return( -1 );
    }

    fclose( f );

    (*buf)[*n] = '\0';

    return( 0 );
}
Пример #22
0
/*
 * Load all data from a file into a given buffer.
 */
int x509_load_file( const char *path, unsigned char **buf, size_t *n )
{
    FILE *f;
    long size;

    if( ( f = fopen( path, "rb" ) ) == NULL )
        return( POLARSSL_ERR_X509_FILE_IO_ERROR );

    fseek( f, 0, SEEK_END );
    if( ( size = ftell( f ) ) == -1 )
    {
        fclose( f );
        return( POLARSSL_ERR_X509_FILE_IO_ERROR );
    }
    fseek( f, 0, SEEK_SET );

    *n = (size_t) size;

    if( *n + 1 == 0 ||
        ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
    {
        fclose( f );
        return( POLARSSL_ERR_X509_MALLOC_FAILED );
    }

    if( fread( *buf, 1, *n, f ) != *n )
    {
        fclose( f );
        polarssl_free( *buf );
        return( POLARSSL_ERR_X509_FILE_IO_ERROR );
    }

    fclose( f );

    (*buf)[*n] = '\0';

    return( 0 );
}
Пример #23
0
/*
 *  RelativeDistinguishedName ::=
 *    SET OF AttributeTypeAndValue
 *
 *  AttributeTypeAndValue ::= SEQUENCE {
 *    type     AttributeType,
 *    value    AttributeValue }
 *
 *  AttributeType ::= OBJECT IDENTIFIER
 *
 *  AttributeValue ::= ANY DEFINED BY AttributeType
 *
 *  We restrict RelativeDistinguishedName to be a set of 1 element. This is
 *  the most common case, and our x509_name structure currently can't handle
 *  more than that.
 */
int x509_get_name( unsigned char **p, const unsigned char *end,
                   x509_name *cur )
{
    int ret;
    size_t set_len;
    const unsigned char *end_set;

    /*
     * parse first SET, restricted to 1 element
     */
    if( ( ret = asn1_get_tag( p, end, &set_len,
            ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
        return( POLARSSL_ERR_X509_INVALID_NAME + ret );

    end_set  = *p + set_len;

    if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
        return( ret );

    if( *p != end_set )
        return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );

    /*
     * recurse until end of SEQUENCE is reached
     */
    if( *p == end )
        return( 0 );

    cur->next = (x509_name *) polarssl_malloc( sizeof( x509_name ) );

    if( cur->next == NULL )
        return( POLARSSL_ERR_X509_MALLOC_FAILED );

    memset( cur->next, 0, sizeof( x509_name ) );

    return( x509_get_name( p, end, cur->next ) );
}
Пример #24
0
static void * blowfish_ctx_alloc( void )
{
    return polarssl_malloc( sizeof( blowfish_context ) );
}
Пример #25
0
static void * sha384_ctx_alloc( void )
{
    return polarssl_malloc( sizeof( sha512_context ) );
}
Пример #26
0
static void * sha224_ctx_alloc( void )
{
    return polarssl_malloc( sizeof( sha256_context ) );
}
Пример #27
0
static void * md5_ctx_alloc( void )
{
    return polarssl_malloc( sizeof( md5_context ) );
}
Пример #28
0
/*
 * Parse one  CRLs in DER format and append it to the chained list
 */
int x509_crl_parse_der( x509_crl *chain,
                        const unsigned char *buf, size_t buflen )
{
    int ret;
    size_t len;
    unsigned char *p, *end;
    x509_buf sig_params1, sig_params2;
    x509_crl *crl = chain;

    /*
     * Check for valid input
     */
    if( crl == NULL || buf == NULL )
        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );

    memset( &sig_params1, 0, sizeof( x509_buf ) );
    memset( &sig_params2, 0, sizeof( x509_buf ) );

    /*
     * Add new CRL on the end of the chain if needed.
     */
    while( crl->version != 0 && crl->next != NULL )
        crl = crl->next;

    if( crl->version != 0 && crl->next == NULL )
    {
        crl->next = polarssl_malloc( sizeof( x509_crl ) );

        if( crl->next == NULL )
        {
            x509_crl_free( crl );
            return( POLARSSL_ERR_X509_MALLOC_FAILED );
        }

        x509_crl_init( crl->next );
        crl = crl->next;
    }

    /*
     * Copy raw DER-encoded CRL
     */
    if( ( p = polarssl_malloc( buflen ) ) == NULL )
        return( POLARSSL_ERR_X509_MALLOC_FAILED );

    memcpy( p, buf, buflen );

    crl->raw.p = p;
    crl->raw.len = buflen;

    end = p + buflen;

    /*
     * CertificateList  ::=  SEQUENCE  {
     *      tbsCertList          TBSCertList,
     *      signatureAlgorithm   AlgorithmIdentifier,
     *      signatureValue       BIT STRING  }
     */
    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT );
    }

    if( len != (size_t) ( end - p ) )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
    }

    /*
     * TBSCertList  ::=  SEQUENCE  {
     */
    crl->tbs.p = p;

    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
    }

    end = p + len;
    crl->tbs.len = end - crl->tbs.p;

    /*
     * Version  ::=  INTEGER  OPTIONAL {  v1(0), v2(1)  }
     *               -- if present, MUST be v2
     *
     * signature            AlgorithmIdentifier
     */
    if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
        ( ret = x509_get_alg( &p, end, &crl->sig_oid1, &sig_params1 ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    crl->version++;

    if( crl->version > 2 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
    }

    if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &sig_params1,
                                  &crl->sig_md, &crl->sig_pk,
                                  &crl->sig_opts ) ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG );
    }

    /*
     * issuer               Name
     */
    crl->issuer_raw.p = p;

    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
    }

    if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    crl->issuer_raw.len = p - crl->issuer_raw.p;

    /*
     * thisUpdate          Time
     * nextUpdate          Time OPTIONAL
     */
    if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
    {
        if( ret != ( POLARSSL_ERR_X509_INVALID_DATE +
                        POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
            ret != ( POLARSSL_ERR_X509_INVALID_DATE +
                        POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
        {
            x509_crl_free( crl );
            return( ret );
        }
    }

    /*
     * revokedCertificates    SEQUENCE OF SEQUENCE   {
     *      userCertificate        CertificateSerialNumber,
     *      revocationDate         Time,
     *      crlEntryExtensions     Extensions OPTIONAL
     *                                   -- if present, MUST be v2
     *                        } OPTIONAL
     */
    if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    /*
     * crlExtensions          EXPLICIT Extensions OPTIONAL
     *                              -- if present, MUST be v2
     */
    if( crl->version == 2 )
    {
        ret = x509_get_crl_ext( &p, end, &crl->crl_ext );

        if( ret != 0 )
        {
            x509_crl_free( crl );
            return( ret );
        }
    }

    if( p != end )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
    }

    end = crl->raw.p + crl->raw.len;

    /*
     *  signatureAlgorithm   AlgorithmIdentifier,
     *  signatureValue       BIT STRING
     */
    if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2, &sig_params2 ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    if( crl->sig_oid1.len != crl->sig_oid2.len ||
        memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 ||
        sig_params1.len != sig_params2.len ||
        ( sig_params1.len != 0 &&
          memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_SIG_MISMATCH );
    }

    if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    if( p != end )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
    }

    return( 0 );
}
Пример #29
0
/*
 * X.509 CRL Entries
 */
static int x509_get_entries( unsigned char **p,
                             const unsigned char *end,
                             x509_crl_entry *entry )
{
    int ret;
    size_t entry_len;
    x509_crl_entry *cur_entry = entry;

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

    if( ( ret = asn1_get_tag( p, end, &entry_len,
            ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
    {
        if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
            return( 0 );

        return( ret );
    }

    end = *p + entry_len;

    while( *p < end )
    {
        size_t len2;
        const unsigned char *end2;

        if( ( ret = asn1_get_tag( p, end, &len2,
                ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
        {
            return( ret );
        }

        cur_entry->raw.tag = **p;
        cur_entry->raw.p = *p;
        cur_entry->raw.len = len2;
        end2 = *p + len2;

        if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
            return( ret );

        if( ( ret = x509_get_time( p, end2,
                                   &cur_entry->revocation_date ) ) != 0 )
            return( ret );

        if( ( ret = x509_get_crl_entry_ext( p, end2,
                                            &cur_entry->entry_ext ) ) != 0 )
            return( ret );

        if( *p < end )
        {
            cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );

            if( cur_entry->next == NULL )
                return( POLARSSL_ERR_X509_MALLOC_FAILED );

            memset( cur_entry->next, 0, sizeof( x509_crl_entry ) );
            cur_entry = cur_entry->next;
        }
    }

    return( 0 );
}
Пример #30
0
/*
 * Parse a CSR
 */
int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen )
{
    int ret;
    size_t len;
    unsigned char *p, *end;
#if defined(POLARSSL_PEM_PARSE_C)
    size_t use_len;
    pem_context pem;
#endif

    /*
     * Check for valid input
     */
    if( csr == NULL || buf == NULL )
        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );

    x509_csr_init( csr );

#if defined(POLARSSL_PEM_PARSE_C)
    pem_init( &pem );
    ret = pem_read_buffer( &pem,
                           "-----BEGIN CERTIFICATE REQUEST-----",
                           "-----END CERTIFICATE REQUEST-----",
                           buf, NULL, 0, &use_len );

    if( ret == 0 )
    {
        /*
         * Was PEM encoded
         */
        buflen -= use_len;
        buf += use_len;

        /*
         * Steal PEM buffer
         */
        p = pem.buf;
        pem.buf = NULL;
        len = pem.buflen;
        pem_free( &pem );
    }
    else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
    {
        pem_free( &pem );
        return( ret );
    }
    else
#endif
    {
        /*
         * nope, copy the raw DER data
         */
        p = (unsigned char *) polarssl_malloc( len = buflen );

        if( p == NULL )
            return( POLARSSL_ERR_X509_MALLOC_FAILED );

        memcpy( p, buf, buflen );

        buflen = 0;
    }

    csr->raw.p = p;
    csr->raw.len = len;
    end = p + len;

    /*
     *  CertificationRequest ::= SEQUENCE {
     *       certificationRequestInfo CertificationRequestInfo,
     *       signatureAlgorithm AlgorithmIdentifier,
     *       signature          BIT STRING
     *  }
     */
    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        x509_csr_free( csr );
        return( POLARSSL_ERR_X509_INVALID_FORMAT );
    }

    if( len != (size_t) ( end - p ) )
    {
        x509_csr_free( csr );
        return( POLARSSL_ERR_X509_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
    }

    /*
     *  CertificationRequestInfo ::= SEQUENCE {
     */
    csr->cri.p = p;

    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        x509_csr_free( csr );
        return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
    }

    end = p + len;
    csr->cri.len = end - csr->cri.p;

    /*
     *  Version  ::=  INTEGER {  v1(0) }
     */
    if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 )
    {
        x509_csr_free( csr );
        return( ret );
    }

    csr->version++;

    if( csr->version != 1 )
    {
        x509_csr_free( csr );
        return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
    }

    /*
     *  subject               Name
     */
    csr->subject_raw.p = p;

    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        x509_csr_free( csr );
        return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
    }

    if( ( ret = x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
    {
        x509_csr_free( csr );
        return( ret );
    }

    csr->subject_raw.len = p - csr->subject_raw.p;

    /*
     *  subjectPKInfo SubjectPublicKeyInfo
     */
    if( ( ret = pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 )
    {
        x509_csr_free( csr );
        return( ret );
    }

    /*
     *  attributes    [0] Attributes
     */
    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) ) != 0 )
    {
        x509_csr_free( csr );
        return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
    }
    // TODO Parse Attributes / extension requests

    p += len;

    end = csr->raw.p + csr->raw.len;

    /*
     *  signatureAlgorithm   AlgorithmIdentifier,
     *  signature            BIT STRING
     */
    if( ( ret = x509_get_alg_null( &p, end, &csr->sig_oid ) ) != 0 )
    {
        x509_csr_free( csr );
        return( ret );
    }

    if( ( ret = x509_get_sig_alg( &csr->sig_oid, &csr->sig_md,
                                  &csr->sig_pk ) ) != 0 )
    {
        x509_csr_free( csr );
        return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG );
    }

    if( ( ret = x509_get_sig( &p, end, &csr->sig ) ) != 0 )
    {
        x509_csr_free( csr );
        return( ret );
    }

    if( p != end )
    {
        x509_csr_free( csr );
        return( POLARSSL_ERR_X509_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
    }

    return( 0 );
}