/* * SubjectPublicKeyInfo ::= SEQUENCE { * algorithm AlgorithmIdentifier, * subjectPublicKey BIT STRING } */ int pk_parse_subpubkey( unsigned char **p, const unsigned char *end, pk_context *pk ) { int ret; size_t len; asn1_buf alg_params; pk_type_t pk_alg = POLARSSL_PK_NONE; const pk_info_t *pk_info; if( ( ret = asn1_get_tag( p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); } end = *p + len; if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 ) return( ret ); if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 ) return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret ); if( *p + len != end ) return( POLARSSL_ERR_PK_INVALID_PUBKEY + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL ) return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG ); if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ) return( ret ); #if defined(POLARSSL_RSA_C) if( pk_alg == POLARSSL_PK_RSA ) { ret = pk_get_shrsapubkey( p, end, pk_rsa( *pk ) ); } else #endif /* POLARSSL_RSA_C */ #if defined(POLARSSL_ECP_C) if( pk_alg == POLARSSL_PK_ECKEY_DH || pk_alg == POLARSSL_PK_ECKEY ) { ret = pk_use_ecparams( &alg_params, &pk_ec( *pk )->grp ); if( ret == 0 ) ret = pk_get_ecpubkey( p, end, pk_ec( *pk ) ); } else #endif /* POLARSSL_ECP_C */ ret = POLARSSL_ERR_PK_UNKNOWN_PK_ALG; if( ret == 0 && *p != end ) ret = POLARSSL_ERR_PK_INVALID_PUBKEY POLARSSL_ERR_ASN1_LENGTH_MISMATCH; if( ret != 0 ) pk_free( pk ); return( ret ); }
int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig ) { int ret; size_t len; if( ( end - *p ) < 1 ) return( POLARSSL_ERR_X509_INVALID_SIGNATURE + POLARSSL_ERR_ASN1_OUT_OF_DATA ); sig->tag = **p; if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 ) return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret ); sig->len = len; sig->p = *p; *p += len; return( 0 ); }
/* * Parse a SEC1 encoded private EC key */ static int pk_parse_key_sec1_der( ecp_keypair *eck, const unsigned char *key, size_t keylen ) { int ret; int version, pubkey_done; size_t len; asn1_buf params; unsigned char *p = (unsigned char *) key; unsigned char *end = p + keylen; unsigned char *end2; /* * RFC 5915, or SEC1 Appendix C.4 * * ECPrivateKey ::= SEQUENCE { * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), * privateKey OCTET STRING, * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, * publicKey [1] BIT STRING OPTIONAL * } */ if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); } end = p + len; if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 ) return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); if( version != 1 ) return( POLARSSL_ERR_PK_KEY_INVALID_VERSION ); if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 ) return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); if( ( ret = shmpi_read_binary( &eck->d, p, len ) ) != 0 ) { ecp_keypair_free( eck ); return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); } p += len; pubkey_done = 0; if( p != end ) { /* * Is 'parameters' present? */ if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 ) { if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 || ( ret = pk_use_ecparams( ¶ms, &eck->grp ) ) != 0 ) { ecp_keypair_free( eck ); return( ret ); } } else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) { ecp_keypair_free( eck ); return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); } /* * Is 'publickey' present? If not, or if we can't read it (eg because it * is compressed), create it from the private key. */ if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 ) { end2 = p + len; if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 ) return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); if( p + len != end2 ) return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 ) pubkey_done = 1; else { /* * The only acceptable failure mode of pk_get_ecpubkey() above * is if the point format is not recognized. */ if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ) return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); } } else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) { ecp_keypair_free( eck ); return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); } } if( ! pubkey_done && ( ret = ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G, NULL, NULL ) ) != 0 ) { ecp_keypair_free( eck ); return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); } if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 ) { ecp_keypair_free( eck ); return( ret ); } return( 0 ); }