static bool generate_keys(ScopedEVP_PKEY &private_key_out, ScopedEVP_PKEY &public_key_out) { ScopedEVP_PKEY private_key(EVP_PKEY_new(), EVP_PKEY_free); ScopedEVP_PKEY public_key(EVP_PKEY_new(), EVP_PKEY_free); ScopedRSA rsa(RSA_new(), RSA_free); ScopedBIGNUM e(BN_new(), BN_free); if (!private_key) { LOGE("Failed to allocate private key"); openssl_log_errors(); return false; } if (!public_key) { LOGE("Failed to allocate public key"); openssl_log_errors(); return false; } if (!rsa) { LOGE("Failed to allocate RSA"); openssl_log_errors(); return false; } if (!e) { LOGE("Failed to allocate BIGNUM"); openssl_log_errors(); return false; } BN_set_word(e.get(), RSA_F4); if (RSA_generate_key_ex(rsa.get(), 2048, e.get(), nullptr) < 0) { LOGE("RSA_generate_key_ex() failed"); openssl_log_errors(); return false; } if (!EVP_PKEY_assign_RSA(private_key.get(), RSAPrivateKey_dup(rsa.get()))) { LOGE("EVP_PKEY_assign_RSA() failed for private key"); openssl_log_errors(); return false; } if (!EVP_PKEY_assign_RSA(public_key.get(), RSAPublicKey_dup(rsa.get()))) { LOGE("EVP_PKEY_assign_RSA() failed for public key"); openssl_log_errors(); return false; } private_key_out = std::move(private_key); public_key_out = std::move(public_key); return true; }
private_key private_key::generate() { EC_KEY* k = EC_KEY_new_by_curve_name( NID_secp256k1 ); if( !k ) FC_THROW_EXCEPTION( exception, "Unable to generate EC key" ); if( !EC_KEY_generate_key( k ) ) { FC_THROW_EXCEPTION( exception, "ecc key generation error" ); } return private_key( k ); }
TEST(SignTest, TestLoadValidPemKeys) { ScopedEVP_PKEY private_key(nullptr, EVP_PKEY_free); ScopedEVP_PKEY public_key(nullptr, EVP_PKEY_free); ScopedBIO bio_private_key_enc(BIO_new(BIO_s_mem()), BIO_free); ASSERT_TRUE(!!bio_private_key_enc); ScopedBIO bio_private_key_noenc(BIO_new(BIO_s_mem()), BIO_free); ASSERT_TRUE(!!bio_private_key_noenc); ScopedBIO bio_public_key(BIO_new(BIO_s_mem()), BIO_free); ASSERT_TRUE(!!bio_public_key); // Generate keys ASSERT_TRUE(generate_keys(private_key, public_key)); // Write keys ASSERT_TRUE(PEM_write_bio_PrivateKey(bio_private_key_enc.get(), private_key.get(), EVP_des_ede3_cbc(), nullptr, 0, nullptr, const_cast<char *>("testing"))); ASSERT_TRUE(PEM_write_bio_PrivateKey(bio_private_key_noenc.get(), private_key.get(), nullptr, nullptr, 0, nullptr, nullptr)); ASSERT_TRUE(PEM_write_bio_PUBKEY(bio_public_key.get(), public_key.get())); // Read back the keys ScopedEVP_PKEY private_key_enc_read(mb::sign::load_private_key( bio_private_key_enc.get(), mb::sign::KEY_FORMAT_PEM, "testing"), EVP_PKEY_free); ASSERT_TRUE(!!private_key_enc_read); ScopedEVP_PKEY private_key_noenc_read(mb::sign::load_private_key( bio_private_key_noenc.get(), mb::sign::KEY_FORMAT_PEM, nullptr), EVP_PKEY_free); ASSERT_TRUE(!!private_key_noenc_read); ScopedEVP_PKEY public_key_read(mb::sign::load_public_key( bio_public_key.get(), mb::sign::KEY_FORMAT_PEM, "testing"), EVP_PKEY_free); ASSERT_TRUE(!!public_key_read); // Compare keys ASSERT_EQ(EVP_PKEY_cmp(private_key.get(), private_key_enc_read.get()), 1); ASSERT_EQ(EVP_PKEY_cmp(private_key.get(), private_key_noenc_read.get()), 1); ASSERT_EQ(EVP_PKEY_cmp(public_key.get(), public_key_read.get()), 1); }
void key_agreement::generate_key_pair( size_t private_key_bytes ) { auto rnd = crypto::provider_factory.create_random(); // // generate private key. // byte_buffer private_key(private_key_bytes); rnd->get_random_bytes(private_key); _private_key = crypto::big_integer(private_key); // // generate public key. // _public_key = DH_G.mod_pow(DH_P, _private_key); }
TEST(SignTest, TestLoadValidPemKeysWithInvalidPassphrase) { ScopedEVP_PKEY private_key(nullptr, EVP_PKEY_free); ScopedEVP_PKEY public_key(nullptr, EVP_PKEY_free); ScopedBIO bio(BIO_new(BIO_s_mem()), BIO_free); ASSERT_TRUE(!!bio); // Generate keys ASSERT_TRUE(generate_keys(private_key, public_key)); // Write key ASSERT_TRUE(PEM_write_bio_PrivateKey(bio.get(), private_key.get(), EVP_des_ede3_cbc(), nullptr, 0, nullptr, const_cast<char *>("testing"))); // Read back the key using invalid password ScopedEVP_PKEY private_key_read(mb::sign::load_private_key( bio.get(), mb::sign::KEY_FORMAT_PEM, "gnitset"), EVP_PKEY_free); ASSERT_FALSE(private_key_read); }
TEST(SignTest, TestLoadInvalidPkcs12PrivateKey) { ScopedBIO bio_private_key(BIO_new(BIO_s_mem()), BIO_free); ASSERT_TRUE(!!bio_private_key); ScopedBIO bio_public_key(BIO_new(BIO_s_mem()), BIO_free); ASSERT_TRUE(!!bio_public_key); // Fill with garbage ASSERT_EQ(BIO_write(bio_private_key.get(), "abcdefghijklmnopqrstuvwxyz", 26), 26); ASSERT_EQ(BIO_write(bio_public_key.get(), "zyxwvutsrqponmlkjihgfedcba", 26), 26); ScopedEVP_PKEY private_key(mb::sign::load_private_key( bio_private_key.get(), mb::sign::KEY_FORMAT_PKCS12, nullptr), EVP_PKEY_free); ASSERT_FALSE(private_key); ScopedEVP_PKEY public_key(mb::sign::load_public_key( bio_public_key.get(), mb::sign::KEY_FORMAT_PKCS12, nullptr), EVP_PKEY_free); ASSERT_FALSE(public_key); }
/** decodes the big int as base64 string, or a number */ void from_variant( const variant& v, private_key& bi, uint32_t max_depth ) { bi = private_key( v.as<std::vector<char> >(max_depth) ); }
RefPtr<DtlsIdentity> DtlsIdentity::Generate() { UniquePK11SlotInfo slot(PK11_GetInternalSlot()); if (!slot) { return nullptr; } uint8_t random_name[16]; SECStatus rv = PK11_GenerateRandomOnSlot(slot.get(), random_name, sizeof(random_name)); if (rv != SECSuccess) return nullptr; std::string name; char chunk[3]; for (size_t i = 0; i < sizeof(random_name); ++i) { SprintfLiteral(chunk, "%.2x", random_name[i]); name += chunk; } std::string subject_name_string = "CN=" + name; UniqueCERTName subject_name(CERT_AsciiToName(subject_name_string.c_str())); if (!subject_name) { return nullptr; } unsigned char paramBuf[12]; // OIDs are small SECItem ecdsaParams = { siBuffer, paramBuf, sizeof(paramBuf) }; SECOidData* oidData = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1); if (!oidData || (oidData->oid.len > (sizeof(paramBuf) - 2))) { return nullptr; } ecdsaParams.data[0] = SEC_ASN1_OBJECT_ID; ecdsaParams.data[1] = oidData->oid.len; memcpy(ecdsaParams.data + 2, oidData->oid.data, oidData->oid.len); ecdsaParams.len = oidData->oid.len + 2; SECKEYPublicKey *pubkey; UniqueSECKEYPrivateKey private_key( PK11_GenerateKeyPair(slot.get(), CKM_EC_KEY_PAIR_GEN, &ecdsaParams, &pubkey, PR_FALSE, PR_TRUE, nullptr)); if (private_key == nullptr) return nullptr; UniqueSECKEYPublicKey public_key(pubkey); pubkey = nullptr; UniqueCERTSubjectPublicKeyInfo spki( SECKEY_CreateSubjectPublicKeyInfo(public_key.get())); if (!spki) { return nullptr; } UniqueCERTCertificateRequest certreq( CERT_CreateCertificateRequest(subject_name.get(), spki.get(), nullptr)); if (!certreq) { return nullptr; } // From 1 day before todayto 30 days after. // This is a sort of arbitrary range designed to be valid // now with some slack in case the other side expects // some before expiry. // // Note: explicit casts necessary to avoid // warning C4307: '*' : integral constant overflow static const PRTime oneDay = PRTime(PR_USEC_PER_SEC) * PRTime(60) // sec * PRTime(60) // min * PRTime(24); // hours PRTime now = PR_Now(); PRTime notBefore = now - oneDay; PRTime notAfter = now + (PRTime(30) * oneDay); UniqueCERTValidity validity(CERT_CreateValidity(notBefore, notAfter)); if (!validity) { return nullptr; } unsigned long serial; // Note: This serial in principle could collide, but it's unlikely rv = PK11_GenerateRandomOnSlot(slot.get(), reinterpret_cast<unsigned char *>(&serial), sizeof(serial)); if (rv != SECSuccess) { return nullptr; } UniqueCERTCertificate certificate( CERT_CreateCertificate(serial, subject_name.get(), validity.get(), certreq.get())); if (!certificate) { return nullptr; } PLArenaPool *arena = certificate->arena; rv = SECOID_SetAlgorithmID(arena, &certificate->signature, SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, 0); if (rv != SECSuccess) return nullptr; // Set version to X509v3. *(certificate->version.data) = SEC_CERTIFICATE_VERSION_3; certificate->version.len = 1; SECItem innerDER; innerDER.len = 0; innerDER.data = nullptr; if (!SEC_ASN1EncodeItem(arena, &innerDER, certificate.get(), SEC_ASN1_GET(CERT_CertificateTemplate))) { return nullptr; } SECItem *signedCert = PORT_ArenaZNew(arena, SECItem); if (!signedCert) { return nullptr; } rv = SEC_DerSignData(arena, signedCert, innerDER.data, innerDER.len, private_key.get(), SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE); if (rv != SECSuccess) { return nullptr; } certificate->derCert = *signedCert; RefPtr<DtlsIdentity> identity = new DtlsIdentity(Move(private_key), Move(certificate), ssl_kea_ecdh); return identity.forget(); }
int main() { ifstream common("common2.ecs"); /* construct file I/O streams */ ifstream private_key("private.ecs"); ifstream message; ofstream signature; char ifname[13],ofname[13]; EC2 G; Big a2,a6,q,x,y,h,r,s,d,k; long seed; int m,a,b,c,cf; miracl *mip=&precision; /* randomise */ cout << "Enter 9 digit random number seed = "; cin >> seed; irand(seed); /* get common data */ common >> m; mip->IOBASE=16; common >> a2 >> a6 >> q >> x >> y; mip->IOBASE=10; common >> a >> b >> c; /* calculate r - this can be done off-line, and hence amortized to almost nothing */ ecurve2(m,a,b,c,a2,a6,FALSE,MR_PROJECTIVE); G=EC2(x,y); k=rand(q); G*=k; /* see brick.cpp for technique to speed this up */ G.get(r); r%=q; /* get private key of recipient */ private_key >> d; /* get message */ cout << "file to be signed = " ; cin >> ifname; strcpy(ofname,ifname); strip(ofname); strcat(ofname,".ecs"); message.open(ifname,ios::binary|ios::in|ios::nocreate); if (!message) { cout << "Unable to open file " << ifname << "\n"; return 0; } h=hash(message); /* calculate s */ k=inverse(k,q); s=((h+d*r)*k)%q; signature.open(ofname); mip->IOBASE=10; signature << r << endl; signature << s << endl; return 0; }
/** decodes the big int as base64 string, or a number */ void from_variant( const variant& v, private_key& bi ) { bi = private_key( v.as<std::vector<char> >() ); }