Beispiel #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 );
}
Beispiel #2
0
/*
 *  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 );
}
Beispiel #3
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;
}
Beispiel #4
0
/*
 * Parse an unencrypted PKCS#8 encoded private key
 */
static int pk_parse_key_pkcs8_unencrypted_der(
                                    mbedtls_pk_context *pk,
                                    const unsigned char* key,
                                    size_t keylen )
{
    int ret, version;
    size_t len;
    mbedtls_asn1_buf params;
    unsigned char *p = (unsigned char *) key;
    unsigned char *end = p + keylen;
    mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
    const mbedtls_pk_info_t *pk_info;

    /*
     * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
     *
     *    PrivateKeyInfo ::= SEQUENCE {
     *      version                   Version,
     *      privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
     *      privateKey                PrivateKey,
     *      attributes           [0]  IMPLICIT Attributes OPTIONAL }
     *
     *    Version ::= INTEGER
     *    PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
     *    PrivateKey ::= OCTET STRING
     *
     *  The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
     */

    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 = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );

    if( version != 0 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret );

    if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );

    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );

    if( len < 1 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
                MBEDTLS_ERR_ASN1_OUT_OF_DATA );

    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 )
    {
        if( ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), p, len ) ) != 0 )
        {
            mbedtls_pk_free( pk );
            return( ret );
        }
    } else
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_C)
    if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH )
    {
        if( ( ret = pk_use_ecparams( &params, &mbedtls_pk_ec( *pk )->grp ) ) != 0 ||
            ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len )  ) != 0 )
        {
            mbedtls_pk_free( pk );
            return( ret );
        }
    } else
#endif /* MBEDTLS_ECP_C */
        return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );

    return( 0 );
}
Beispiel #5
0
/**
 * Parse an unencrypted PKCS#8 encoded private key.
 * This function does not own the key buffer. It is the responsibility of the
 * caller to take care of zeroizing and freeing it after use.
 * The function is responsible for freeing the provided PK context on failure.
 */
static int
pk_parse_key_pkcs8_unencrypted_der(ttls_pk_context *pk,
				   const unsigned char *key, size_t keylen)
{
	int ret, version;
	size_t len;
	ttls_asn1_buf params;
	unsigned char *p = (unsigned char *)key;
	unsigned char *end = p + keylen;
	ttls_pk_type_t pk_alg = TTLS_PK_NONE;
	const ttls_pk_info_t *pk_info;

	/*
	 * This function parses the PrivateKeyInfo object
	 * (PKCS#8 v1.2 = RFC 5208).
	 *
	 *	PrivateKeyInfo ::= SEQUENCE {
	 *	  version		Version,
	 *	  privateKeyAlgorithm	PrivateKeyAlgorithmIdentifier,
	 *	  privateKey		PrivateKey,
	 *	  attributes		[0]  IMPLICIT Attributes OPTIONAL }
	 *
	 * Version ::= INTEGER
	 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
	 * PrivateKey ::= OCTET STRING
	 *
	 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
	 */
	ret = ttls_asn1_get_tag(&p, end, &len,
			      TTLS_ASN1_CONSTRUCTED | TTLS_ASN1_SEQUENCE);
	if (ret)
		return TTLS_ERR_PK_KEY_INVALID_FORMAT + ret;
	end = p + len;

	if ((ret = ttls_asn1_get_int(&p, end, &version)))
		return TTLS_ERR_PK_KEY_INVALID_FORMAT + ret;
	if (version)
		return TTLS_ERR_PK_KEY_INVALID_VERSION + ret;

	if ((ret = pk_get_pk_alg(&p, end, &pk_alg, &params)))
		return TTLS_ERR_PK_KEY_INVALID_FORMAT + ret;

	if ((ret = ttls_asn1_get_tag(&p, end, &len, TTLS_ASN1_OCTET_STRING)))
		return TTLS_ERR_PK_KEY_INVALID_FORMAT + ret;

	if (len < 1)
		return TTLS_ERR_PK_KEY_INVALID_FORMAT
		       + TTLS_ERR_ASN1_OUT_OF_DATA;

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

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

	if (pk_alg == TTLS_PK_RSA) {
		if ((ret = pk_parse_key_pkcs1_der(ttls_pk_rsa(*pk), p, len))) {
			ttls_pk_free(pk);
			return ret;
		}
	}
	else if (pk_alg == TTLS_PK_ECKEY || pk_alg == TTLS_PK_ECKEY_DH) {
		if ((ret = pk_use_ecparams(&params, &ttls_pk_ec(*pk)->grp))
		    || (ret = pk_parse_key_sec1_der(ttls_pk_ec(*pk), p, len)))
		{
			ttls_pk_free(pk);
			return ret;
		}
	}
	else {
		return TTLS_ERR_PK_UNKNOWN_PK_ALG;
	}

	return 0;
}