kaa_error_t ext_get_sha1_base64_public(const uint8_t **sha1, size_t *length) { if (sha1 == NULL || length == NULL) { return KAA_ERR_BADPARAM; } static size_t sha1_base64_len = 0; /* Additional byte for NULL terminator */ static uint8_t sha1_base64_buffer[KAA_SHA1_PUB_BASE64_LEN + 1]; static int initialized = false; if (!initialized) { uint8_t pub_key[KAA_RSA_PUBLIC_KEY_LENGTH_MAX]; uint8_t sha1_public[KAA_SHA1_PUB_LEN]; int key_length = mbedtls_pk_write_pubkey_der(&pk_pub_context, pub_key, KAA_RSA_PUBLIC_KEY_LENGTH_MAX); if (key_length < 0) { return KAA_ERR_BADDATA; } sha1_from_public_key(pub_key, key_length, sha1_public); int error = sha1_to_base64(sha1_public, sizeof(sha1_public), sha1_base64_buffer, sizeof(sha1_base64_buffer), &sha1_base64_len); if (error) { return KAA_ERR_BADDATA; } initialized = true; } *sha1 = sha1_base64_buffer; *length = sha1_base64_len; return KAA_ERR_NONE; }
buffer_t export_public_key(context& d, key_format fmt) { #if defined(MBEDTLS_PK_WRITE_C) buffer_t output(K::DefaultExportBufferSize, '\0'); if (fmt == pk::pem_format) { mbedcrypto_c_call( mbedtls_pk_write_pubkey_pem, &d.pk_, to_ptr(output), K::DefaultExportBufferSize); output.resize(std::strlen(output.c_str())); finalize_pem(output); } else if (fmt == pk::der_format) { int ret = mbedtls_pk_write_pubkey_der( &d.pk_, to_ptr(output), K::DefaultExportBufferSize); if (ret < 0) throw exception{ret, __FUNCTION__}; size_t length = ret; output.erase(0, K::DefaultExportBufferSize - length); output.resize(length); } return output; #else // MBEDTLS_PK_WRITE_C throw exceptions::pk_export_missed{}; #endif // MBEDTLS_PK_WRITE_C }
int extract_public_ec_key_length(uint8_t* buffer, size_t max_length, const uint8_t* private_key, size_t private_key_len) { mbedtls_pk_context key; mbedtls_pk_init(&key); int error = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); if (!error) error = mbedtls_pk_parse_key(&key, private_key, private_key_len, nullptr, 0); if (!error) error = mbedtls_pk_write_pubkey_der(&key, buffer, max_length); mbedtls_pk_free(&key); return error; }
void ext_get_endpoint_public_key(const uint8_t **buffer, size_t *buffer_size) { if (buffer == NULL || buffer_size == 0) { return; } static int key_length; static int initialized = false; static uint8_t buff[KAA_RSA_PUBLIC_KEY_LENGTH_MAX]; if (!initialized) { key_length = mbedtls_pk_write_pubkey_der(&pk_pub_context, buff, sizeof(buff)); if (key_length < 0) { *buffer = NULL; *buffer_size = 0; return; } initialized = true; } *buffer = buff; *buffer_size = key_length; }
int mbedtls_ecies_write_originator(unsigned char **p, unsigned char *start, mbedtls_ecp_keypair *originator_keypair) { int result = 0; size_t len = 0; mbedtls_pk_context pk; if (originator_keypair == NULL) { return MBEDTLS_ERR_ECIES_BAD_INPUT_DATA; } pk.pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); pk.pk_ctx = originator_keypair; ACCUMULATE_AND_CHECK(result, len, mbedtls_pk_write_pubkey_der(&pk, start , *p - start) ); *p -= len; return (int)len; }
static int write_public_key( mbedtls_pk_context *key, const char *output_file ) { int ret; FILE *f; unsigned char output_buf[16000]; unsigned char *c = output_buf; size_t len = 0; memset(output_buf, 0, 16000); #if defined(MBEDTLS_PEM_WRITE_C) if( opt.output_format == OUTPUT_FORMAT_PEM ) { if( ( ret = mbedtls_pk_write_pubkey_pem( key, output_buf, 16000 ) ) != 0 ) return( ret ); len = strlen( (char *) output_buf ); } else #endif { if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf, 16000 ) ) < 0 ) return( ret ); len = ret; c = output_buf + sizeof(output_buf) - len - 1; } if( ( f = fopen( output_file, "w" ) ) == NULL ) return( -1 ); if( fwrite( c, 1, len, f ) != len ) { fclose( f ); return( -1 ); } fclose( f ); return( 0 ); }
void ext_get_sha1_public(uint8_t **sha1, size_t *length) { if (sha1 == NULL || length == NULL) { return; } static uint8_t sha1_public[KAA_SHA1_PUB_LEN]; static int initialized = false; if (!initialized) { uint8_t pub_key[KAA_RSA_PUBLIC_KEY_LENGTH_MAX]; int key_length = mbedtls_pk_write_pubkey_der(&pk_pub_context, pub_key, KAA_RSA_PUBLIC_KEY_LENGTH_MAX); if (key_length < 0) { *sha1 = NULL; *length = 0; return; } sha1_from_public_key(pub_key, key_length, sha1_public); initialized = true; } *length = KAA_SHA1_PUB_LEN; *sha1 = sha1_public; }
int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) { int ret; unsigned char output_buf[PUB_DER_MAX_BYTES]; size_t olen = 0; if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) { return( ret ); } if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, output_buf + sizeof(output_buf) - ret, ret, buf, size, &olen ) ) != 0 ) { return( ret ); } return( 0 ); }
result_t PKey::exportDer(obj_ptr<Buffer_base> &retVal) { result_t hr; bool priv; hr = isPrivate(priv); if (hr < 0) return hr; int32_t ret; std::string buf; buf.resize(8192); if (priv) ret = mbedtls_pk_write_key_der(&m_key, (unsigned char *)&buf[0], buf.length()); else ret = mbedtls_pk_write_pubkey_der(&m_key, (unsigned char *)&buf[0], buf.length()); if (ret < 0) return CHECK_ERROR(_ssl::setError(ret)); retVal = new Buffer(buf.substr(buf.length() - ret)); return 0; }
static CURLcode mbed_connect_step2(struct connectdata *conn, int sockindex) { int ret; struct SessionHandle *data = conn->data; struct ssl_connect_data* connssl = &conn->ssl[sockindex]; const mbedtls_x509_crt *peercert; #ifdef HAS_ALPN const char* next_protocol; #endif char errorbuf[128]; errorbuf[0] = 0; conn->recv[sockindex] = mbed_recv; conn->send[sockindex] = mbed_send; ret = mbedtls_ssl_handshake(&connssl->ssl); if(ret == MBEDTLS_ERR_SSL_WANT_READ) { connssl->connecting_state = ssl_connect_2_reading; return CURLE_OK; } else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) { connssl->connecting_state = ssl_connect_2_writing; return CURLE_OK; } else if(ret) { #ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* MBEDTLS_ERROR_C */ failf(data, "ssl_handshake returned - mbedTLS: (-0x%04X) %s", -ret, errorbuf); return CURLE_SSL_CONNECT_ERROR; } infof(data, "mbedTLS: Handshake complete, cipher is %s\n", mbedtls_ssl_get_ciphersuite(&conn->ssl[sockindex].ssl) ); ret = mbedtls_ssl_get_verify_result(&conn->ssl[sockindex].ssl); if(ret && data->set.ssl.verifypeer) { if(ret & MBEDTLS_X509_BADCERT_EXPIRED) failf(data, "Cert verify failed: BADCERT_EXPIRED"); if(ret & MBEDTLS_X509_BADCERT_REVOKED) { failf(data, "Cert verify failed: BADCERT_REVOKED"); return CURLE_SSL_CACERT; } if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH) failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED) failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); return CURLE_PEER_FAILED_VERIFICATION; } peercert = mbedtls_ssl_get_peer_cert(&connssl->ssl); if(peercert && data->set.verbose) { const size_t bufsize = 16384; char *buffer = malloc(bufsize); if(!buffer) return CURLE_OUT_OF_MEMORY; if(mbedtls_x509_crt_info(buffer, bufsize, "* ", peercert) > 0) infof(data, "Dumping cert info:\n%s\n", buffer); else infof(data, "Unable to dump certificate information.\n"); free(buffer); } if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) { int size; CURLcode result; mbedtls_x509_crt *p; unsigned char pubkey[PUB_DER_MAX_BYTES]; if(!peercert || !peercert->raw.p || !peercert->raw.len) { failf(data, "Failed due to missing peer certificate"); return CURLE_SSL_PINNEDPUBKEYNOTMATCH; } p = calloc(1, sizeof(*p)); if(!p) return CURLE_OUT_OF_MEMORY; mbedtls_x509_crt_init(p); /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der needs a non-const key, for now. https://github.com/ARMmbed/mbedtls/issues/396 */ if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) { failf(data, "Failed copying peer certificate"); mbedtls_x509_crt_free(p); free(p); return CURLE_SSL_PINNEDPUBKEYNOTMATCH; } size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES); if(size <= 0) { failf(data, "Failed copying public key from peer certificate"); mbedtls_x509_crt_free(p); free(p); return CURLE_SSL_PINNEDPUBKEYNOTMATCH; } /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */ result = Curl_pin_peer_pubkey(data, data->set.str[STRING_SSL_PINNEDPUBLICKEY], &pubkey[PUB_DER_MAX_BYTES - size], size); if(result) { mbedtls_x509_crt_free(p); free(p); return result; } mbedtls_x509_crt_free(p); free(p); } #ifdef HAS_ALPN if(conn->bits.tls_enable_alpn) { next_protocol = mbedtls_ssl_get_alpn_protocol(&connssl->ssl); if(next_protocol) { infof(data, "ALPN, server accepted to use %s\n", next_protocol); #ifdef USE_NGHTTP2 if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID, NGHTTP2_PROTO_VERSION_ID_LEN) && !next_protocol[NGHTTP2_PROTO_VERSION_ID_LEN]) { conn->negnpn = CURL_HTTP_VERSION_2; } else #endif if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH) && !next_protocol[ALPN_HTTP_1_1_LENGTH]) { conn->negnpn = CURL_HTTP_VERSION_1_1; } } else { infof(data, "ALPN, server did not agree to a protocol\n"); } } #endif connssl->connecting_state = ssl_connect_3; infof(data, "SSL connected\n"); return CURLE_OK; }
static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ) { int ret; psa_key_slot_t key_slot; psa_key_policy_t policy; psa_key_type_t psa_type; mbedtls_pk_context key; int key_len; /* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */ unsigned char buf[30 + 2 * MBEDTLS_ECP_MAX_BYTES]; unsigned char *p = (unsigned char*) sig; mbedtls_pk_info_t pk_info = mbedtls_eckey_info; psa_algorithm_t psa_sig_md, psa_md; psa_ecc_curve_t curve = mbedtls_psa_translate_ecc_group( ( (mbedtls_ecdsa_context *) ctx )->grp.id ); const size_t signature_part_size = ( ( (mbedtls_ecdsa_context *) ctx )->grp.nbits + 7 ) / 8; if( curve == 0 ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); /* mbedlts_pk_write_pubkey_der() expects a full PK context, * re-construct one to make it happy */ key.pk_info = &pk_info; key.pk_ctx = ctx; key_len = mbedtls_pk_write_pubkey_der( &key, buf, sizeof( buf ) ); if( key_len <= 0 ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); if( ( ret = mbedtls_psa_get_free_key_slot( &key_slot ) ) != PSA_SUCCESS ) return( mbedtls_psa_err_translate_pk( ret ) ); psa_md = mbedtls_psa_translate_md( md_alg ); if( psa_md == 0 ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); psa_sig_md = PSA_ALG_ECDSA( psa_md ); psa_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, psa_sig_md ); if( ( ret = psa_set_key_policy( key_slot, &policy ) ) != PSA_SUCCESS ) { ret = mbedtls_psa_err_translate_pk( ret ); goto cleanup; } if( psa_import_key( key_slot, psa_type, buf + sizeof( buf ) - key_len, key_len ) != PSA_SUCCESS ) { ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; goto cleanup; } /* We don't need the exported key anymore and can * reuse its buffer for signature extraction. */ if( 2 * signature_part_size > sizeof( buf ) ) { ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; goto cleanup; } if( ( ret = extract_ecdsa_sig( &p, sig + sig_len, buf, signature_part_size ) ) != 0 ) { goto cleanup; } if( psa_asymmetric_verify( key_slot, psa_sig_md, hash, hash_len, buf, 2 * signature_part_size ) != PSA_SUCCESS ) { ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; goto cleanup; } if( p != sig + sig_len ) { ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; goto cleanup; } ret = 0; cleanup: psa_destroy_key( key_slot ); return( ret ); }
int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; const char *sig_oid; size_t sig_oid_len = 0; unsigned char *c, *c2; unsigned char hash[64]; unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; unsigned char tmp_buf[2048]; size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; size_t len = 0; mbedtls_pk_type_t pk_alg; /* * Prepare data to be signed in tmp_buf */ c = tmp_buf + sizeof( tmp_buf ); /* Signature algorithm needed in TBS, and later for actual signature */ pk_alg = mbedtls_pk_get_type( ctx->issuer_key ); if( pk_alg == MBEDTLS_PK_ECKEY ) pk_alg = MBEDTLS_PK_ECDSA; if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, &sig_oid, &sig_oid_len ) ) != 0 ) { return( ret ); } /* * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension */ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ); /* * SubjectPublicKeyInfo */ MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->subject_key, tmp_buf, c - tmp_buf ) ); c -= pub_len; len += pub_len; /* * Subject ::= Name */ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) ); /* * Validity ::= SEQUENCE { * notBefore Time, * notAfter Time } */ sub_len = 0; MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after, MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); len += sub_len; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); /* * Issuer ::= Name */ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->issuer ) ); /* * Signature ::= AlgorithmIdentifier */ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, tmp_buf, sig_oid, strlen( sig_oid ), 0 ) ); /* * Serial ::= INTEGER */ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, tmp_buf, &ctx->serial ) ); /* * Version ::= INTEGER { v1(0), v2(1), v3(2) } */ sub_len = 0; MBEDTLS_ASN1_CHK_ADD( sub_len, mbedtls_asn1_write_int( &c, tmp_buf, ctx->version ) ); len += sub_len; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); /* * Make signature */ mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len, f_rng, p_rng ) ) != 0 ) { return( ret ); } /* * Write data to output buffer */ c2 = buf + size; MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, sig_oid, sig_oid_len, sig, sig_len ) ); if( len > (size_t)( c2 - buf ) ) return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); c2 -= len; memcpy( c2, c, len ); len += sig_and_oid_len; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); return( (int) len ); }
int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; const char *sig_oid; size_t sig_oid_len = 0; unsigned char *c, *c2; unsigned char hash[64]; unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; unsigned char tmp_buf[2048]; size_t pub_len = 0, sig_and_oid_len = 0, sig_len; size_t len = 0; mbedtls_pk_type_t pk_alg; /* * Prepare data to be signed in tmp_buf */ c = tmp_buf + sizeof( tmp_buf ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); if( len ) { MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ, MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); } MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ); MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key, tmp_buf, c - tmp_buf ) ); c -= pub_len; len += pub_len; /* * Subject ::= Name */ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) ); /* * Version ::= INTEGER { v1(0), v2(1), v3(2) } */ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); /* * Prepare signature */ mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); pk_alg = mbedtls_pk_get_type( ctx->key ); if( pk_alg == MBEDTLS_PK_ECKEY ) pk_alg = MBEDTLS_PK_ECDSA; if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, f_rng, p_rng ) ) != 0 || ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, &sig_oid, &sig_oid_len ) ) != 0 ) { return( ret ); } /* * Write data to output buffer */ c2 = buf + size; MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, sig_oid, sig_oid_len, sig, sig_len ) ); c2 -= len; memcpy( c2, c, len ); len += sig_and_oid_len; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); return( (int) len ); }
/******************************************************************************* * Asymmetric ciphers * *******************************************************************************/ int __attribute__((weak)) wrapped_asym_keygen(Cipher c, CryptoKey key_type, uint8_t* pub, size_t* pub_len, uint8_t* priv, size_t* priv_len) { if (keygen_deferred_handling(key_type)) { // If overriden by user implementation. return _keygen_overrides[key_type](c, key_type, pub, pub_len, priv, priv_len); } int ret = -1; mbedtls_pk_context key; mbedtls_pk_init(&key); uint32_t pers = randomInt(); mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_init(&ctr_drbg); ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const uint8_t*) &pers, 4 ); if (0 == ret) { switch (c) { #if defined(WRAPPED_ASYM_RSA) case Cipher::ASYM_RSA: { ret = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); if (0 == ret) { mbedtls_rsa_context* rsa = mbedtls_pk_rsa(key); ret = mbedtls_rsa_gen_key(rsa, mbedtls_ctr_drbg_random, &ctr_drbg, (int) key_type, 65537 ); if (0 == ret) { ret--; memset(pub, 0, *pub_len); memset(priv, 0, *priv_len); int written = mbedtls_pk_write_pubkey_der(&key, pub, *pub_len); if (0 < written) { *pub_len = written; written = mbedtls_pk_write_key_der(&key, priv, *priv_len); if (0 < written) { *priv_len = written; ret = 0; } } } } } break; #endif #if defined(MBEDTLS_ECDSA_C) case Cipher::ASYM_ECDSA: { ret = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); if (0 == ret) { mbedtls_ecp_keypair* ec_kp = mbedtls_pk_ec(key); ret = mbedtls_ecdsa_genkey(ec_kp, (mbedtls_ecp_group_id) key_type, mbedtls_ctr_drbg_random, &ctr_drbg ); if (0 == ret) { ret--; memset(pub, 0, *pub_len); memset(priv, 0, *priv_len); int written = mbedtls_pk_write_pubkey_der(&key, pub, *pub_len); if (0 < written) { *pub_len = written; written = mbedtls_pk_write_key_der(&key, priv, *priv_len); if (0 < written) { *priv_len = written; ret = 0; } } } } } break; #endif #if defined(MBEDTLS_ECP_C) case Cipher::ASYM_ECKEY: { ret = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); if (0 == ret) { mbedtls_ecp_keypair* ec_kp = mbedtls_pk_ec(key); ret = mbedtls_ecp_gen_key( (mbedtls_ecp_group_id) key_type, ec_kp, mbedtls_ctr_drbg_random, &ctr_drbg ); if (0 == ret) { ret--; memset(pub, 0, *pub_len); memset(priv, 0, *priv_len); int written = mbedtls_pk_write_pubkey_der(&key, pub, *pub_len); if (0 < written) { *pub_len = written; written = mbedtls_pk_write_key_der(&key, priv, *priv_len); if (0 < written) { *priv_len = written; ret = 0; } } } } } break; #endif default: break; } } mbedtls_pk_free(&key); mbedtls_ctr_drbg_free(&ctr_drbg); return ret; }