int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size ) { int ret; unsigned char *c; size_t len = 0, par_len = 0, oid_len; const char *oid; c = buf + size; ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, key ) ); if( c - buf < 1 ) { return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); } /* * SubjectPublicKeyInfo ::= SEQUENCE { * algorithm AlgorithmIdentifier, * subjectPublicKey BIT STRING } */ *--c = 0; len += 1; ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); /* If we return here (do not write OID) * the result will look OK... */ /* return len; */ if( ( ret = oid_get_oid_by_pk_alg( pk_get_type( key ), &oid, &oid_len ) ) != 0 ) { return( ret ); } #if defined(POLARSSL_ECP_C) if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) { ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, pk_ec( *key ) ) ); } #endif ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, oid, oid_len, par_len ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); return( (int) len ); }
int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) { int ret; unsigned char *c; size_t len = 0, par_len = 0, oid_len; const char *oid; c = buf + size; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) ); if( c - buf < 1 ) return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); /* * SubjectPublicKeyInfo ::= SEQUENCE { * algorithm AlgorithmIdentifier, * subjectPublicKey BIT STRING } */ *--c = 0; len += 1; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ), &oid, &oid_len ) ) != 0 ) { return( ret ); } #if defined(MBEDTLS_ECP_C) if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) { MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) ); } #endif MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len, par_len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); return( (int) len ); }
int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size ) { int ret; unsigned char *c = buf + size; size_t len = 0; #if defined(POLARSSL_RSA_C) if( pk_get_type( key ) == POLARSSL_PK_RSA ) { rsa_context *rsa = pk_rsa( *key ); ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) ); ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) ); ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) ); ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) ); ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) ); ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) ); ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) ); ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) ); ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); } else #endif /* POLARSSL_RSA_C */ #if defined(POLARSSL_ECP_C) if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) { ecp_keypair *ec = pk_ec( *key ); size_t pub_len = 0, par_len = 0; /* * 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 * } */ /* publicKey */ ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); if( c - buf < 1 ) return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); *--c = 0; pub_len += 1; ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) ); ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) ); ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ); len += pub_len; /* parameters */ ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); ASN1_CHK_ADD( par_len, asn1_write_len( &c, buf, par_len ) ); ASN1_CHK_ADD( par_len, asn1_write_tag( &c, buf, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ); len += par_len; /* privateKey: write as MPI then fix tag */ ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &ec->d ) ); *c = ASN1_OCTET_STRING; /* version */ ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 1 ) ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); } else #endif /* POLARSSL_ECP_C */ #if defined(__TTS__) if( pk_get_type( key ) == OUR_PK_TTS ) { len += TTS_SECKEY_SIZE_BYTE + TTS_PUBKEY_SIZE_BYTE; if( c - buf < (int) len ) return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); c -= len; memcpy( c, &pk_tts( *key )->sk, TTS_SECKEY_SIZE_BYTE ); memcpy( c + TTS_SECKEY_SIZE_BYTE, &pk_tts( *key )->pk, TTS_PUBKEY_SIZE_BYTE ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); return (int) len; } else #endif /* __TTS__ */ #if defined(__TTS_2__) if( pk_get_type( key ) == OUR_PK_TTS2 ) { len += TTS2_SECKEY_SIZE_BYTE + TTS2_PUBKEY_SIZE_BYTE; if( c - buf < (int) len ) return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); c -= len; memcpy( c, &pk_tts2( *key )->sk, TTS2_SECKEY_SIZE_BYTE ); memcpy( c + TTS2_SECKEY_SIZE_BYTE, &pk_tts2( *key )->pk, TTS2_PUBKEY_SIZE_BYTE ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); return (int) len; } else #endif /* __TTS_2__ */ #if defined(__RAINBOW__) if( pk_get_type( key ) == OUR_PK_RAINBOW ) { len += RB_SECKEY_SIZE_BYTE + RB_PUBKEY_SIZE_BYTE; if( c - buf < (int) len ) return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); c -= len; memcpy( c, &pk_rainbow( *key )->sk, RB_SECKEY_SIZE_BYTE ); memcpy( c + RB_SECKEY_SIZE_BYTE, &pk_rainbow( *key )->pk, RB_PUBKEY_SIZE_BYTE ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); return (int) len; } else #endif /* __RAINBOW__ */ #if defined(__RAINBOW_2__) if( pk_get_type( key ) == OUR_PK_RAINBOW2 ) { len += RB2_SECKEY_SIZE_BYTE + RB2_PUBKEY_SIZE_BYTE; if( c - buf < (int) len ) return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); c -= len; memcpy( c, &pk_rainbow2( *key )->sk, RB2_SECKEY_SIZE_BYTE ); memcpy( c + RB2_SECKEY_SIZE_BYTE, &pk_rainbow2( *key )->pk, RB2_PUBKEY_SIZE_BYTE ); ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); return (int) len; } else #endif /* __RAINBOW_2__ */ return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); return( (int) len ); }
int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) { int ret; unsigned char *c = buf + size; size_t len = 0; #if defined(MBEDTLS_RSA_C) if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) { mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->QP ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DQ ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DP ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->Q ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->P ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->D ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->E ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->N ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); } else #endif /* MBEDTLS_RSA_C */ #if defined(MBEDTLS_ECP_C) if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) { mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key ); size_t pub_len = 0, par_len = 0; /* * 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 * } */ /* publicKey */ MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); if( c - buf < 1 ) return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); *--c = 0; pub_len += 1; MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ); len += pub_len; /* parameters */ MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) ); MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); len += par_len; /* privateKey: write as MPI then fix tag */ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &ec->d ) ); *c = MBEDTLS_ASN1_OCTET_STRING; /* version */ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); } else #endif /* MBEDTLS_ECP_C */ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); return( (int) len ); }