/* * Get parameters from a keypair */ int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key, ecdh_side side ) { int ret; if( ( ret = ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ) return( ret ); /* If it's not our key, just import the public part as Qp */ if( side == POLARSSL_ECDH_THEIRS ) return( ecp_copy( &ctx->Qp, &key->Q ) ); /* Our key: import public (as Q) and private parts */ if( side != POLARSSL_ECDH_OURS ) return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); if( ( ret = ecp_copy( &ctx->Q, &key->Q ) ) != 0 || ( ret = mpi_copy( &ctx->d, &key->d ) ) != 0 ) return( ret ); return( 0 ); }
result_t PKey::copy(const pk_context &key) { pk_type_t type = pk_get_type(&key); int ret; if (type == POLARSSL_PK_RSA) { rsa_context *rsa = pk_rsa(key); ret = pk_init_ctx(&m_key, pk_info_from_type(POLARSSL_PK_RSA)); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); rsa_context *rsa1 = pk_rsa(m_key); ret = rsa_copy(rsa1, rsa); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); return 0; } if (type == POLARSSL_PK_ECKEY) { ecp_keypair *ecp = pk_ec(key); ret = pk_init_ctx(&m_key, pk_info_from_type(POLARSSL_PK_ECKEY)); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); ecp_keypair *ecp1 = pk_ec(m_key); ret = ecp_group_copy(&ecp1->grp, &ecp->grp); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); ret = mpi_copy(&ecp1->d, &ecp->d); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); ret = ecp_copy(&ecp1->Q, &ecp->Q); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); return 0; } return CHECK_ERROR(CALL_E_INVALID_CALL); }
result_t PKey::get_publicKey(obj_ptr<PKey_base> &retVal) { result_t hr; bool priv; hr = isPrivate(priv); if (hr < 0) return hr; if (!priv) return CALL_RETURN_NULL; pk_type_t type = pk_get_type(&m_key); int ret; if (type == POLARSSL_PK_RSA) { rsa_context *rsa = pk_rsa(m_key); obj_ptr<PKey> pk1 = new PKey(); ret = pk_init_ctx(&pk1->m_key, pk_info_from_type(POLARSSL_PK_RSA)); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); rsa_context *rsa1 = pk_rsa(pk1->m_key); rsa1->len = rsa->len; rsa1->padding = rsa->padding; rsa1->hash_id = rsa->hash_id; ret = mpi_copy(&rsa1->N, &rsa->N); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); ret = mpi_copy(&rsa1->E, &rsa->E); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); retVal = pk1; return 0; } if (type == POLARSSL_PK_ECKEY) { ecp_keypair *ecp = pk_ec(m_key); obj_ptr<PKey> pk1 = new PKey(); ret = pk_init_ctx(&pk1->m_key, pk_info_from_type(POLARSSL_PK_ECKEY)); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); ecp_keypair *ecp1 = pk_ec(pk1->m_key); ret = ecp_group_copy(&ecp1->grp, &ecp->grp); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); ret = ecp_copy(&ecp1->Q, &ecp->Q); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); retVal = pk1; return 0; } return CHECK_ERROR(CALL_E_INVALID_CALL); }
int main( int argc, char *argv[] ) { int ret; ecdsa_context ctx_sign, ctx_verify; entropy_context entropy; ctr_drbg_context ctr_drbg; unsigned char hash[] = "This should be the hash of a message."; unsigned char sig[512]; size_t sig_len; const char *pers = "ecdsa"; ((void) argv); ecdsa_init( &ctx_sign ); ecdsa_init( &ctx_verify ); memset(sig, 0, sizeof( sig ) ); ret = 1; if( argc != 1 ) { polarssl_printf( "usage: ecdsa\n" ); #if defined(_WIN32) polarssl_printf( "\n" ); #endif goto exit; } /* * Generate a key pair for signing */ polarssl_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); entropy_init( &entropy ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { polarssl_printf( " failed\n ! ctr_drbg_init returned %d\n", ret ); goto exit; } polarssl_printf( " ok\n . Generating key pair..." ); fflush( stdout ); if( ( ret = ecdsa_genkey( &ctx_sign, ECPARAMS, ctr_drbg_random, &ctr_drbg ) ) != 0 ) { polarssl_printf( " failed\n ! ecdsa_genkey returned %d\n", ret ); goto exit; } polarssl_printf( " ok (key size: %d bits)\n", (int) ctx_sign.grp.pbits ); dump_pubkey( " + Public key: ", &ctx_sign ); /* * Sign some message hash */ polarssl_printf( " . Signing message..." ); fflush( stdout ); if( ( ret = ecdsa_write_signature( &ctx_sign, hash, sizeof( hash ), sig, &sig_len, ctr_drbg_random, &ctr_drbg ) ) != 0 ) { polarssl_printf( " failed\n ! ecdsa_genkey returned %d\n", ret ); goto exit; } polarssl_printf( " ok (signature length = %u)\n", (unsigned int) sig_len ); dump_buf( " + Hash: ", hash, sizeof hash ); dump_buf( " + Signature: ", sig, sig_len ); /* * Signature is serialized as defined by RFC 4492 p. 20, * but one can also access 'r' and 's' directly from the context */ #ifdef POLARSSL_FS_IO mpi_write_file( " r = ", &ctx_sign.r, 16, NULL ); mpi_write_file( " s = ", &ctx_sign.s, 16, NULL ); #endif /* * Transfer public information to verifying context * * We could use the same context for verification and signatures, but we * chose to use a new one in order to make it clear that the verifying * context only needs the public key (Q), and not the private key (d). */ polarssl_printf( " . Preparing verification context..." ); fflush( stdout ); if( ( ret = ecp_group_copy( &ctx_verify.grp, &ctx_sign.grp ) ) != 0 ) { polarssl_printf( " failed\n ! ecp_group_copy returned %d\n", ret ); goto exit; } if( ( ret = ecp_copy( &ctx_verify.Q, &ctx_sign.Q ) ) != 0 ) { polarssl_printf( " failed\n ! ecp_copy returned %d\n", ret ); goto exit; } ret = 0; /* * Verify signature */ polarssl_printf( " ok\n . Verifying signature..." ); fflush( stdout ); if( ( ret = ecdsa_read_signature( &ctx_verify, hash, sizeof( hash ), sig, sig_len ) ) != 0 ) { polarssl_printf( " failed\n ! ecdsa_read_signature returned %d\n", ret ); goto exit; } polarssl_printf( " ok\n" ); exit: #if defined(_WIN32) polarssl_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif ecdsa_free( &ctx_verify ); ecdsa_free( &ctx_sign ); ctr_drbg_free( &ctr_drbg ); entropy_free( &entropy ); return( ret ); }