Example #1
0
/*
 *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
 *       algorithm            AlgorithmIdentifier,
 *       subjectPublicKey     BIT STRING }
 */
int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
                        mbedtls_pk_context *pk )
{
    int ret;
    size_t len;
    mbedtls_asn1_buf alg_params;
    mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
    const mbedtls_pk_info_t *pk_info;

    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
    {
        return( MBEDTLS_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 = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
        return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );

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

    if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
        return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );

    if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 )
        return( ret );

#if defined(MBEDTLS_RSA_C)
    if( pk_alg == MBEDTLS_PK_RSA )
    {
        ret = pk_get_rsapubkey( p, end, mbedtls_pk_rsa( *pk ) );
    } else
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_C)
    if( pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY )
    {
        ret = pk_use_ecparams( &alg_params, &mbedtls_pk_ec( *pk )->grp );
        if( ret == 0 )
            ret = pk_get_ecpubkey( p, end, mbedtls_pk_ec( *pk ) );
    } else
#endif /* MBEDTLS_ECP_C */
        ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;

    if( ret == 0 && *p != end )
        ret = MBEDTLS_ERR_PK_INVALID_PUBKEY
              MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;

    if( ret != 0 )
        mbedtls_pk_free( pk );

    return( ret );
}
Example #2
0
/**
 * Parse a SubjectPublicKeyInfo DER structure.
 *
 *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
 *	   algorithm			AlgorithmIdentifier,
 *	   subjectPublicKey	 BIT STRING }
 */
int
ttls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
			ttls_pk_context *pk)
{
	int ret;
	size_t len;
	ttls_asn1_buf alg_params;
	ttls_pk_type_t pk_alg = TTLS_PK_NONE;
	const ttls_pk_info_t *pk_info;

	if ((ret = ttls_asn1_get_tag(p, end, &len,
		TTLS_ASN1_CONSTRUCTED | TTLS_ASN1_SEQUENCE)) != 0)
	{
		return(TTLS_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 = ttls_asn1_get_bitstring_null(p, end, &len)) != 0)
		return(TTLS_ERR_PK_INVALID_PUBKEY + ret);

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

	if ((pk_info = ttls_pk_info_from_type(pk_alg)) == NULL)
		return(TTLS_ERR_PK_UNKNOWN_PK_ALG);

	if ((ret = ttls_pk_setup(pk, pk_info)) != 0)
		return ret;

	if (pk_alg == TTLS_PK_RSA)
	{
		ret = pk_get_rsapubkey(p, end, ttls_pk_rsa(*pk));
	}
	else if (pk_alg == TTLS_PK_ECKEY_DH || pk_alg == TTLS_PK_ECKEY)
	{
		ret = pk_use_ecparams(&alg_params, &ttls_pk_ec(*pk)->grp);
		if (ret == 0)
			ret = pk_get_ecpubkey(p, end, ttls_pk_ec(*pk));
	} else
		ret = TTLS_ERR_PK_UNKNOWN_PK_ALG;

	if (ret == 0 && *p != end)
		ret = TTLS_ERR_PK_INVALID_PUBKEY
			  TTLS_ERR_ASN1_LENGTH_MISMATCH;

	if (ret != 0)
		ttls_pk_free(pk);

	return ret;
}