コード例 #1
0
ファイル: key_utils.c プロジェクト: Kirill380/kaa
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;
}
コード例 #2
0
ファイル: pk.cpp プロジェクト: azadkuh/mbedcrypto
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
}
コード例 #3
0
ファイル: eckeygen.cpp プロジェクト: Babbleshack/firmware
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;
}
コード例 #4
0
ファイル: key_utils.c プロジェクト: Kirill380/kaa
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;
}
コード例 #5
0
ファイル: ecies_envelope.c プロジェクト: cfogelklou/mbedtls
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;
}
コード例 #6
0
ファイル: key_app_writer.c プロジェクト: chixsh/tempesta
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 );
}
コード例 #7
0
ファイル: key_utils.c プロジェクト: Kirill380/kaa
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;
}
コード例 #8
0
ファイル: pkwrite.c プロジェクト: Comojs/comojs
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 );
}
コード例 #9
0
ファイル: PKey.cpp プロジェクト: 540513310/fibjs
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;
}
コード例 #10
0
ファイル: mbedtls.c プロジェクト: aakashbhowmick/curl
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;
}
コード例 #11
0
ファイル: pk_wrap.c プロジェクト: MarceloSalazar/mbed-os
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 );
}
コード例 #12
0
ファイル: x509write_crt.c プロジェクト: Archcady/mbed-os
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 );
}
コード例 #13
0
ファイル: x509write_csr.c プロジェクト: 0buffer/polarssl
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 );
}
コード例 #14
0
ファイル: MbedTLS.cpp プロジェクト: jspark311/ManuvrOS
/*******************************************************************************
* 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;
}