void go() override { std::unique_ptr<Botan::Private_Key> key( Botan::PKCS8::load_key( get_arg("key"), rng(), get_arg("passphrase"))); if(!key) { throw CLI_Error("Unable to load private key"); } const std::string sig_padding = get_arg_or("emsa", algo_default_emsa(key->algo_name())) + "(" + get_arg("hash") + ")"; Botan::PK_Signer signer(*key, rng(), sig_padding); auto onData = [&signer](const uint8_t b[], size_t l) { signer.update(b, l); }; this->read_file(get_arg("file"), onData); output() << Botan::base64_encode(signer.signature(rng())) << "\n"; }
Test::Result PK_Signature_Generation_Test::run_one_test(const std::string&, const VarMap& vars) { const std::vector<uint8_t> message = get_req_bin(vars, "Msg"); const std::vector<uint8_t> signature = get_req_bin(vars, "Signature"); const std::string padding = get_opt_str(vars, "Padding", default_padding(vars)); std::unique_ptr<Botan::RandomNumberGenerator> rng; if(vars.count("Nonce")) { rng.reset(new Fixed_Output_RNG(get_req_bin(vars, "Nonce"))); } Test::Result result(algo_name() + "/" + padding + " signature generation"); std::unique_ptr<Botan::Private_Key> privkey = load_private_key(vars); std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(Botan::X509::BER_encode(*privkey))); Botan::PK_Signer signer(*privkey, padding); Botan::PK_Verifier verifier(*pubkey, padding); const std::vector<uint8_t> generated_signature = signer.sign_message(message, rng ? *rng : Test::rng()); result.test_eq("generated signature matches KAT", generated_signature, signature); result.test_eq("generated signature valid", verifier.verify_message(message, generated_signature), true); check_invalid_signatures(result, verifier, message, signature); result.test_eq("correct signature valid", verifier.verify_message(message, signature), true); return result; }
void signStringWholeBlock( const char *inString ) { // source for our private key file FileSource privFile( "privateKey.txt", true, new HexDecoder ); // construct a hasher/signer using the private key RSASSA_PKCS1v15_SHA_Signer priv( privFile ); // RSASSA_PKCS1v15_SHA_Signer ignores the rng. // Use a real RNG for other signature schemes! NullRNG rng; // a filter based on this signer // should put result into signature file SignerFilter signer( rng, priv, new HexEncoder( new FileSink( signatureFileName ) ) ); // pass data blocks through filter as one large block int numBytes = strlen( inString ); signer.Put( (unsigned char *)inString, numBytes ); // unlimited propagate here to flush file signer.MessageEnd( -1 ); }
byte_seq Keystore::sign(const byte_seq& data) { // https://botan.randombit.net/manual/pubkey.html#signatures // EMSA3 for backward compability with PKCS1_15 Botan::PK_Signer signer(*private_key_, IncludeOS_RNG::get(), "EMSA3(SHA-256)"); auto signature = signer.sign_message((uint8_t*)data.data(), data.size(), IncludeOS_RNG::get()); //printf("Sign:\n%s\n", Botan::hex_encode(signature).c_str()); return signature; }
// check via cross products around A, B, and C with other vertices and Point // if Point lies in the triangle, the cross products (in a fixed right-hand rule orientation) should have the same sign bool isTriangle(vector<Point2f> triangle, double i, double j) { Point2f AB = triangle[1]-triangle[0]; Point2f AP = Point2f(i,j) - triangle[0]; Point2f BC = triangle[2] - triangle[1]; Point2f BP = Point2f(i,j) - triangle[1]; Point2f CA = triangle[0] - triangle[2]; Point2f CP = Point2f(i,j) - triangle[2]; int sABAP_ABAC = signer(AB.x, AB.y, AP.x, AP.y, -CA.x, -CA.y); int sBCBP_BCBA = signer(BC.x, BC.y, BP.x, BP.y, -AB.x, -AB.y); int sCACP_CACB = signer(CA.x, CA.y, CP.x, CP.y, -BC.x, -BC.y); if (sABAP_ABAC >= 0 && sBCBP_BCBA >= 0 && sCACP_CACB >= 0) return true; double crossABAP = cross2d(AB.x, AB.y, AP.x, AP.y); double crossBCBP = cross2d(BC.x, BC.y, BP.x, BP.y); double crossCACP = cross2d(CA.x, CA.y, CP.x, CP.y); // if two cross products are 0, inside if (((crossABAP >= -tEPSILON && crossABAP <= tEPSILON) && (crossBCBP >= -tEPSILON && crossBCBP <= tEPSILON)) || ((crossABAP >= -tEPSILON && crossABAP <= tEPSILON) && (crossCACP >= -tEPSILON && crossCACP <= tEPSILON)) || ((crossCACP >= -tEPSILON && crossCACP <= tEPSILON) && (crossBCBP >= -tEPSILON && crossBCBP <= tEPSILON))) return true; // if one cross product is 0, the other two equal each other, inside if (((crossABAP >= -tEPSILON && crossABAP <= tEPSILON) && (crossBCBP <= crossCACP + tEPSILON && crossBCBP >= crossCACP-tEPSILON)) || ((crossBCBP >= -tEPSILON && crossBCBP <= tEPSILON) && (crossABAP <= crossCACP + tEPSILON && crossABAP >= crossCACP-tEPSILON)) || ((crossCACP >= -tEPSILON && crossCACP <= tEPSILON) && (crossBCBP <= crossABAP + tEPSILON && crossBCBP >= crossABAP-tEPSILON))) return true; //if (i <= faceIm_0.rows || j <= faceIm_0.cols) // return true; return false; }
/* * Create a new self-signed X.509 certificate */ X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts, const Private_Key& key, const std::string& hash_fn, RandomNumberGenerator& rng) { AlgorithmIdentifier sig_algo; X509_DN subject_dn; AlternativeName subject_alt; // for now, only the padding option is used std::map<std::string,std::string> sig_opts = { {"padding",opts.padding_scheme} }; const std::vector<uint8_t> pub_key = X509::BER_encode(key); std::unique_ptr<PK_Signer> signer(choose_sig_format(key, sig_opts, rng, hash_fn, sig_algo)); load_info(opts, subject_dn, subject_alt); Extensions extensions = opts.extensions; Key_Constraints constraints; if(opts.is_CA) { constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN); } else { verify_cert_constraints_valid_for_key_type(key, opts.constraints); constraints = opts.constraints; } extensions.add_new( new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit), true); if(constraints != NO_CONSTRAINTS) { extensions.add_new(new Cert_Extension::Key_Usage(constraints), true); } std::unique_ptr<Cert_Extension::Subject_Key_ID> skid(new Cert_Extension::Subject_Key_ID(pub_key, hash_fn)); extensions.add_new(new Cert_Extension::Authority_Key_ID(skid->get_key_id())); extensions.add_new(skid.release()); extensions.add_new( new Cert_Extension::Subject_Alternative_Name(subject_alt)); extensions.add_new( new Cert_Extension::Extended_Key_Usage(opts.ex_constraints)); return X509_CA::make_cert(signer.get(), rng, sig_algo, pub_key, opts.start, opts.end, subject_dn, subject_dn, extensions); }
std::vector<uint8_t> TLS::Callbacks::tls_sign_message( const Private_Key& key, RandomNumberGenerator& rng, const std::string& emsa, Signature_Format format, const std::vector<uint8_t>& msg) { PK_Signer signer(key, rng, emsa, format); return signer.sign_message(msg, rng); }
///////////////////////////////////////////////////////////////////////////// // Use the secp256k1 curve to sign data of an arbitrary length. // Input: Data to sign (const SecureBinaryData&) // The private key used to sign the data (const BTC_PRIVKEY&) // A flag indicating if deterministic signing is used (const bool&) // Output: None // Return: The signature of the data (SecureBinaryData) SecureBinaryData CryptoECDSA::SignData(SecureBinaryData const & binToSign, BTC_PRIVKEY const & cppPrivKey, const bool& detSign) { // We trick the Crypto++ ECDSA module by passing it a single-hashed // message, it will do the second hash before it signs it. This is // exactly what we need. CryptoPP::SHA256 sha256; BTC_PRNG prng; // Execute the first sha256 op -- the signer will do the other one SecureBinaryData hashVal(32); sha256.CalculateDigest(hashVal.getPtr(), binToSign.getPtr(), binToSign.getSize()); // Do we want to use a PRNG or use deterministic signing (RFC 6979)? string signature; if(detSign) { BTC_DETSIGNER signer(cppPrivKey); CryptoPP::StringSource( hashVal.toBinStr(), true, new CryptoPP::SignerFilter( prng, signer, new CryptoPP::StringSink(signature))); } else { BTC_SIGNER signer(cppPrivKey); CryptoPP::StringSource( hashVal.toBinStr(), true, new CryptoPP::SignerFilter( prng, signer, new CryptoPP::StringSink(signature))); } return SecureBinaryData(signature); }
virtual void DoRun() { SignatureData result; { std::vector<BYTE> src(16); for (BYTE i = 0; i< 16; ++i) { src[i] = i * 11; } DataSigner signer(src); bool res = signer.Sign(&src[0], src.size(), result); LIVE_ASSERT(res); } { std::vector<BYTE> src(16); for (BYTE i = 0; i< 16; ++i) { src[i] = i * 11; } DataSigner signer(src); bool res = signer.Verify(&src[0], src.size(), result.data()); LIVE_ASSERT(res); } }
/* * Create a new self-signed X.509 certificate */ X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts, const Private_Key& key, const std::string& hash_fn, RandomNumberGenerator& rng) { AlgorithmIdentifier sig_algo; X509_DN subject_dn; AlternativeName subject_alt; std::vector<byte> pub_key = X509::BER_encode(key); std::unique_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo)); load_info(opts, subject_dn, subject_alt); Key_Constraints constraints; if(opts.is_CA) { constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN); } else { verify_cert_constraints_valid_for_key_type(key, opts.constraints); constraints = opts.constraints; } Extensions extensions; extensions.add( new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit), true); if(constraints != NO_CONSTRAINTS) { extensions.add(new Cert_Extension::Key_Usage(constraints), true); } extensions.add(new Cert_Extension::Subject_Key_ID(pub_key)); extensions.add( new Cert_Extension::Subject_Alternative_Name(subject_alt)); extensions.add( new Cert_Extension::Extended_Key_Usage(opts.ex_constraints)); return X509_CA::make_cert(signer.get(), rng, sig_algo, pub_key, opts.start, opts.end, subject_dn, subject_dn, extensions); }
bool Topology::authenticateRootTopology(const Dictionary &rt) { try { std::string signer(rt.signingIdentity()); if (!signer.length()) return false; Identity signerId(signer); std::map< Address,Identity >::const_iterator authority(ZT_DEFAULTS.rootTopologyAuthorities.find(signerId.address())); if (authority == ZT_DEFAULTS.rootTopologyAuthorities.end()) return false; if (signerId != authority->second) return false; return rt.verify(authority->second); } catch ( ... ) { return false; } }
/* * Create a new Certificate Verify message */ Certificate_Verify::Certificate_Verify(Handshake_IO& io, Handshake_State& state, const Policy& policy, RandomNumberGenerator& rng, const Private_Key* priv_key) { BOTAN_ASSERT_NONNULL(priv_key); std::pair<std::string, Signature_Format> format = state.choose_sig_format(*priv_key, m_hash_algo, m_sig_algo, true, policy); PK_Signer signer(*priv_key, rng, format.first, format.second); m_signature = signer.sign_message(state.hash().get_contents(), rng); state.hash().update(io.send(*this)); }
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident) { auto filename = i2p::fs::DataDirPath("family", (family + ".key")); std::string sig; SSL_CTX * ctx = SSL_CTX_new (TLS_method ()); int ret = SSL_CTX_use_PrivateKey_file (ctx, filename.c_str (), SSL_FILETYPE_PEM); if (ret) { SSL * ssl = SSL_new (ctx); EVP_PKEY * pkey = SSL_get_privatekey (ssl); EC_KEY * ecKey = EVP_PKEY_get1_EC_KEY (pkey); if (ecKey) { auto group = EC_KEY_get0_group (ecKey); if (group) { int curve = EC_GROUP_get_curve_name (group); if (curve == NID_X9_62_prime256v1) { uint8_t signingPrivateKey[32], buf[50], signature[64]; i2p::crypto::bn2buf (EC_KEY_get0_private_key (ecKey), signingPrivateKey, 32); i2p::crypto::ECDSAP256Signer signer (signingPrivateKey); size_t len = family.length (); memcpy (buf, family.c_str (), len); memcpy (buf + len, (const uint8_t *)ident, 32); len += 32; signer.Sign (buf, len, signature); len = Base64EncodingBufferSize (64); char * b64 = new char[len+1]; len = ByteStreamToBase64 (signature, 64, b64, len); b64[len] = 0; sig = b64; delete[] b64; } else LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported"); } } SSL_free (ssl); } else LogPrint (eLogError, "Family: Can't open keys file: ", filename); SSL_CTX_free (ctx); return sig; }
void InvertibleRSAFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) { int modulusSize = 2048; alg.GetIntValue(Name::ModulusSize(), modulusSize) || alg.GetIntValue(Name::KeySize(), modulusSize); assert(modulusSize >= 16); if (modulusSize < 16) throw InvalidArgument("InvertibleRSAFunction: specified modulus size is too small"); m_e = alg.GetValueWithDefault(Name::PublicExponent(), Integer(17)); assert(m_e >= 3); assert(!m_e.IsEven()); if (m_e < 3 || m_e.IsEven()) throw InvalidArgument("InvertibleRSAFunction: invalid public exponent"); RSAPrimeSelector selector(m_e); AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) (Name::PointerToPrimeSelector(), selector.GetSelectorPointer()); m_p.GenerateRandom(rng, primeParam); m_q.GenerateRandom(rng, primeParam); m_d = m_e.InverseMod(LCM(m_p-1, m_q-1)); assert(m_d.IsPositive()); m_dp = m_d % (m_p-1); m_dq = m_d % (m_q-1); m_n = m_p * m_q; m_u = m_q.InverseMod(m_p); if (FIPS_140_2_ComplianceEnabled()) { RSASS<PKCS1v15, SHA>::Signer signer(*this); RSASS<PKCS1v15, SHA>::Verifier verifier(signer); SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier); RSAES<OAEP<SHA> >::Decryptor decryptor(*this); RSAES<OAEP<SHA> >::Encryptor encryptor(decryptor); EncryptionPairwiseConsistencyTest_FIPS_140_Only(encryptor, decryptor); } }
int main() { ExpValidator exp; HS256Validator signer("secret"); // Now we use these validators to parse and verify the token we created // in the previous example std::string token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9." "eyJpc3MiOiJmb28iLCJleHAiOjE0ODMyMjg4MDB9." "u3JTUx1tJDo601olQv0rHk4kGkKadIj3cvy-DDZKVRo"; try { json header, payload; std::tie(header, payload) = JWT::Decode(token, &signer, &exp); std::cout << "You should not see this line" << std::endl; } catch (TokenFormatError &tfe) { // No data can be recovered.. } catch (InvalidTokenError &tfe) { json header, payload; std::tie(header, payload) = JWT::Decode(token); std::cout << "Payload: " << payload << std::endl; } }
static SECStatus VerifySignature(Context& context, ResponderIDType responderIDType, const SECItem& responderID, const SECItem* certs, size_t numCerts, const CERTSignedData& signedResponseData) { ScopedCERTCertificate signer( GetOCSPSignerCertificate(context.trustDomain, responderIDType, responderID, certs, numCerts, context.issuerCert, context.time)); if (!signer) { return SECFailure; } if (context.trustDomain.VerifySignedData(&signedResponseData, signer.get()) != SECSuccess) { if (PR_GetError() == SEC_ERROR_BAD_SIGNATURE) { PR_SetError(SEC_ERROR_OCSP_BAD_SIGNATURE, 0); } return SECFailure; } return SECSuccess; }
int main (int argc, const char* argv[]) { string toSign; FileSource(argv[1], true, new StringSink(toSign)); AutoSeededRandomPool rng; //Read private key CryptoPP::ByteQueue bytes; FileSource file(argv[2], true, new Base64Decoder); file.TransferTo(bytes); bytes.MessageEnd(); RSA::PrivateKey privateKey; privateKey.Load(bytes); //Sign message RSASSA_PKCS1v15_SHA_Signer signer(privateKey); SecByteBlock signature(signer.SignatureLength()); signer.SignMessage( rng, (byte const*) toSign.data(), toSign.size(), signature); //Print string of signature HexEncoder encoder; string signatureString; encoder.Put(signature.data(), signature.size()); encoder.MessageEnd(); word64 signatureSize = encoder.MaxRetrievable(); if (signatureSize) { signatureString.resize(signatureSize); encoder.Get((byte*) signatureString.data(), signatureString.size()); } cout << signatureString << endl; }
bool ValidateESIGN() { cout << "\nESIGN validation suite running...\n\n"; bool pass = true, fail; static const char plain[] = "test"; static const byte signature[] = "\xA3\xE3\x20\x65\xDE\xDA\xE7\xEC\x05\xC1\xBF\xCD\x25\x79\x7D\x99\xCD\xD5\x73\x9D\x9D\xF3\xA4\xAA\x9A\xA4\x5A\xC8\x23\x3D\x0D\x37\xFE\xBC\x76\x3F\xF1\x84\xF6\x59" "\x14\x91\x4F\x0C\x34\x1B\xAE\x9A\x5C\x2E\x2E\x38\x08\x78\x77\xCB\xDC\x3C\x7E\xA0\x34\x44\x5B\x0F\x67\xD9\x35\x2A\x79\x47\x1A\x52\x37\x71\xDB\x12\x67\xC1\xB6\xC6" "\x66\x73\xB3\x40\x2E\xD6\xF2\x1A\x84\x0A\xB6\x7B\x0F\xEB\x8B\x88\xAB\x33\xDD\xE4\x83\x21\x90\x63\x2D\x51\x2A\xB1\x6F\xAB\xA7\x5C\xFD\x77\x99\xF2\xE1\xEF\x67\x1A" "\x74\x02\x37\x0E\xED\x0A\x06\xAD\xF4\x15\x65\xB8\xE1\xD1\x45\xAE\x39\x19\xB4\xFF\x5D\xF1\x45\x7B\xE0\xFE\x72\xED\x11\x92\x8F\x61\x41\x4F\x02\x00\xF2\x76\x6F\x7C" "\x79\xA2\xE5\x52\x20\x5D\x97\x5E\xFE\x39\xAE\x21\x10\xFB\x35\xF4\x80\x81\x41\x13\xDD\xE8\x5F\xCA\x1E\x4F\xF8\x9B\xB2\x68\xFB\x28"; FileSource keys("TestData/esig1536.dat", true, new HexDecoder); ESIGN<SHA>::Signer signer(keys); ESIGN<SHA>::Verifier verifier(signer); fail = !SignatureValidate(signer, verifier); pass = pass && !fail; fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature, verifier.SignatureLength()); pass = pass && !fail; cout << (fail ? "FAILED " : "passed "); cout << "verification check against test vector\n"; cout << "Generating signature key from seed..." << endl; signer.AccessKey().GenerateRandom(GlobalRNG(), MakeParameters("Seed", ConstByteArrayParameter((const byte *)"test", 4))("KeySize", 3*512)); verifier = signer; fail = !SignatureValidate(signer, verifier); pass = pass && !fail; return pass; }
SecureBinaryData CryptoECDSA::SignData(SecureBinaryData const & binToSign, BTC_PRIVKEY const & cppPrivKey) { // We trick the Crypto++ ECDSA module by passing it a single-hashed // message, it will do the second hash before it signs it. This is // exactly what we need. static CryptoPP::SHA256 sha256; static BTC_PRNG prng; // Execute the first sha256 op -- the signer will do the other one SecureBinaryData hashVal(32); sha256.CalculateDigest(hashVal.getPtr(), binToSign.getPtr(), binToSign.getSize()); string signature; BTC_SIGNER signer(cppPrivKey); CryptoPP::StringSource( hashVal.toBinStr(), true, new CryptoPP::SignerFilter( prng, signer, new CryptoPP::StringSink(signature))); return SecureBinaryData(signature); }
packet_pubkey Addr::encodePubKey() { std::shared_lock<std::shared_timed_mutex> mlock(this->mutex_); packet_pubkey pubkey; time_t ltime = std::time(nullptr); this->lastPubKeyRequest = ltime; std::random_device rd; std::mt19937 engine(rd()); std::uniform_int_distribution<int> distribution(-300, 300); int random = distribution(engine); time_t TTL = 4 * 24 * 60 * 60 + random; //4 days +- 5 min ltime = ltime + TTL; pubkey.objectType = 1; pubkey.Time = ltime; pubkey.stream = this->getStream(); pubkey.version = 4; pubkey.encodePayload(); ustring plain; OID CURVE = secp256k1(); AutoSeededRandomPool rng; ECDH < ECP >::Domain dhA(CURVE); //generating ephemeral key pair SecByteBlock privA(dhA.PrivateKeyLength()), pubA(dhA.PublicKeyLength()); dhA.GenerateKeyPair(rng, privA, pubA); ustring pubEKey; pubEKey.append(pubA.data(), pubA.size()); ustring privEKey; privEKey.append(privA.data(), privA.size()); plain.appendInt32(1); //bitfiled 1 not yet integrated plain.append(this->pubSigningKey.c_str() + 1, 64); plain.append(this->pubEncryptionKey.c_str() + 1, 64); plain.appendVarInt_B(this->nonce_trials); plain.appendVarInt_B(this->extra_bytes); AutoSeededRandomPool prng; ECDSA<ECP, SHA1>::PrivateKey privateKey; Integer x; x.Decode(this->getPrivSigningKey().c_str(), this->getPrivSigningKey().size()); privateKey.Initialize(CURVE, x); ECDSA<ECP, SHA1>::Signer signer(privateKey); string signature; string mess; ustring mess1; unsigned int i = 8; mess1.appendInt64(pubkey.message_payload.getInt64(i)); mess1.appendInt32(pubkey.message_payload.getInt32(i)); mess1.appendVarInt_B(pubkey.message_payload.getVarInt_B(i)); mess1.appendVarInt_B(pubkey.message_payload.getVarInt_B(i)); mess1 += this->getTag(); mess += mess1.toString(); mess += plain.toString(); StringSource ss(mess, true /*pump all*/, new SignerFilter(prng, signer, new StringSink(signature) ) // SignerFilter ); // StringSource //DER encoding Integer r, s; StringStore store(signature); r.Decode(store, signature.size() / 2); s.Decode(store, signature.size() / 2); string sign; StringSink sink(sign); DERSequenceEncoder seq(sink); r.DEREncode(seq); s.DEREncode(seq); seq.MessageEnd(); //end conversion plain.appendVarInt_B(sign.size()); plain.append((unsigned char*)sign.c_str(), sign.size()); ECIES<ECP>::PrivateKey priv; ustring pubK = this->getPubOfPriv(this->getTagE()); //Integer e; //e.Decode(this->getTagE().c_str(), 32); //priv.Initialize(CURVE, e); //ECIES<ECP>::PublicKey pub; //priv.MakePublicKey(pub); //const ECP::Point& qq = pub.GetPublicElement(); //string pubS; //StringSink sinkK(pubS); //qq.x.Encode(sinkK, 32); //qq.y.Encode(sinkK, 32); //ustring pubK; //pubK += 0x04; //pubK.fromString(pubS); ustring encoded = this->encode(pubK, privEKey, pubEKey, plain); pubkey.tag = this->getTag(); pubkey.encrypted = encoded; pubkey.encodeObject(); return pubkey; }
void TestSignatureScheme(TestData &v) { std::string name = GetRequiredDatum(v, "Name"); std::string test = GetRequiredDatum(v, "Test"); member_ptr<PK_Signer> signer(ObjectFactoryRegistry<PK_Signer>::Registry().CreateObject(name.c_str())); member_ptr<PK_Verifier> verifier(ObjectFactoryRegistry<PK_Verifier>::Registry().CreateObject(name.c_str())); TestDataNameValuePairs pairs(v); if (test == "GenerateKey") { signer->AccessPrivateKey().GenerateRandom(GlobalRNG(), pairs); verifier->AccessPublicKey().AssignFrom(signer->AccessPrivateKey()); } else { std::string keyFormat = GetRequiredDatum(v, "KeyFormat"); if (keyFormat == "DER") verifier->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref()); else if (keyFormat == "Component") verifier->AccessMaterial().AssignFrom(pairs); if (test == "Verify" || test == "NotVerify") { VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN); PutDecodedDatumInto(v, "Signature", verifierFilter); PutDecodedDatumInto(v, "Message", verifierFilter); verifierFilter.MessageEnd(); if (verifierFilter.GetLastResult() == (test == "NotVerify")) SignalTestFailure(); return; } else if (test == "PublicKeyValid") { if (!verifier->GetMaterial().Validate(GlobalRNG(), 3)) SignalTestFailure(); return; } if (keyFormat == "DER") signer->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref()); else if (keyFormat == "Component") signer->AccessMaterial().AssignFrom(pairs); } if (test == "GenerateKey" || test == "KeyPairValidAndConsistent") { TestKeyPairValidAndConsistent(verifier->AccessMaterial(), signer->GetMaterial()); VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::THROW_EXCEPTION); verifierFilter.Put((const byte *)"abc", 3); StringSource ss("abc", true, new SignerFilter(GlobalRNG(), *signer, new Redirector(verifierFilter))); } else if (test == "Sign") { SignerFilter f(GlobalRNG(), *signer, new HexEncoder(new FileSink(cout))); StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f)); SignalTestFailure(); } else if (test == "DeterministicSign") { // This test is specialized for RFC 6979. The RFC is a drop-in replacement // for DSA and ECDSA, and access to the seed or secret is not needed. If // additional determinsitic signatures are added, then the test harness will // likely need to be extended. string signature; SignerFilter f(GlobalRNG(), *signer, new HexEncoder(new StringSink(signature))); StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f)); if (GetDecodedDatum(v, "Signature") != signature) SignalTestFailure(); return; } else if (test == "RandomSign") { SignalTestError(); assert(false); // TODO: implement } else { SignalTestError(); assert(false); } }
void TestSignatureScheme(TestData &v) { std::string name = GetRequiredDatum(v, "Name"); std::string test = GetRequiredDatum(v, "Test"); std::auto_ptr<PK_Signer> signer(ObjectFactoryRegistry<PK_Signer>::Registry().CreateObject(name.c_str())); std::auto_ptr<PK_Verifier> verifier(ObjectFactoryRegistry<PK_Verifier>::Registry().CreateObject(name.c_str())); TestDataNameValuePairs pairs(v); std::string keyFormat = GetRequiredDatum(v, "KeyFormat"); if (keyFormat == "DER") verifier->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref()); else if (keyFormat == "Component") verifier->AccessMaterial().AssignFrom(pairs); if (test == "Verify" || test == "NotVerify") { VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN); PutDecodedDatumInto(v, "Signature", verifierFilter); PutDecodedDatumInto(v, "Message", verifierFilter); verifierFilter.MessageEnd(); if (verifierFilter.GetLastResult() == (test == "NotVerify")) SignalTestFailure(); } else if (test == "PublicKeyValid") { if (!verifier->GetMaterial().Validate(GlobalRNG(), 3)) SignalTestFailure(); } else goto privateKeyTests; return; privateKeyTests: if (keyFormat == "DER") signer->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref()); else if (keyFormat == "Component") signer->AccessMaterial().AssignFrom(pairs); if (test == "KeyPairValidAndConsistent") { TestKeyPairValidAndConsistent(verifier->AccessMaterial(), signer->GetMaterial()); } else if (test == "Sign") { SignerFilter f(GlobalRNG(), *signer, new HexEncoder(new FileSink(cout))); StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f)); SignalTestFailure(); } else if (test == "DeterministicSign") { SignalTestError(); assert(false); // TODO: implement } else if (test == "RandomSign") { SignalTestError(); assert(false); // TODO: implement } else if (test == "GenerateKey") { SignalTestError(); assert(false); } else { SignalTestError(); assert(false); } }
/** * Create a new Server Key Exchange message */ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, Handshake_State& state, const Policy& policy, Credentials_Manager& creds, RandomNumberGenerator& rng, const Private_Key* signing_key) { const std::string hostname = state.client_hello()->sni_hostname(); const std::string kex_algo = state.ciphersuite().kex_algo(); if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") { std::string identity_hint = creds.psk_identity_hint("tls-server", hostname); append_tls_length_value(m_params, identity_hint, 2); } if(kex_algo == "DH" || kex_algo == "DHE_PSK") { std::unique_ptr<DH_PrivateKey> dh(new DH_PrivateKey(rng, DL_Group(policy.dh_group()))); append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_p()), 2); append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_g()), 2); append_tls_length_value(m_params, dh->public_value(), 2); m_kex_key.reset(dh.release()); } else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") { const std::vector<std::string>& curves = state.client_hello()->supported_ecc_curves(); if(curves.empty()) throw Internal_Error("Client sent no ECC extension but we negotiated ECDH"); const std::string curve_name = policy.choose_curve(curves); if(curve_name == "") throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Could not agree on an ECC curve with the client"); EC_Group ec_group(curve_name); std::unique_ptr<ECDH_PrivateKey> ecdh(new ECDH_PrivateKey(rng, ec_group)); const std::string ecdh_domain_oid = ecdh->domain().get_oid(); const std::string domain = OIDS::lookup(OID(ecdh_domain_oid)); if(domain == "") throw Internal_Error("Could not find name of ECDH domain " + ecdh_domain_oid); const u16bit named_curve_id = Supported_Elliptic_Curves::name_to_curve_id(domain); m_params.push_back(3); // named curve m_params.push_back(get_byte(0, named_curve_id)); m_params.push_back(get_byte(1, named_curve_id)); append_tls_length_value(m_params, ecdh->public_value(), 1); m_kex_key.reset(ecdh.release()); } #if defined(BOTAN_HAS_SRP6) else if(kex_algo == "SRP_SHA") { const std::string srp_identifier = state.client_hello()->srp_identifier(); std::string group_id; BigInt v; std::vector<byte> salt; const bool found = creds.srp_verifier("tls-server", hostname, srp_identifier, group_id, v, salt, policy.hide_unknown_users()); if(!found) throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY, "Unknown SRP user " + srp_identifier); m_srp_params.reset(new SRP6_Server_Session); BigInt B = m_srp_params->step1(v, group_id, "SHA-1", rng); DL_Group group(group_id); append_tls_length_value(m_params, BigInt::encode(group.get_p()), 2); append_tls_length_value(m_params, BigInt::encode(group.get_g()), 2); append_tls_length_value(m_params, salt, 1); append_tls_length_value(m_params, BigInt::encode(B), 2); } #endif else if(kex_algo != "PSK") throw Internal_Error("Server_Key_Exchange: Unknown kex type " + kex_algo); if(state.ciphersuite().sig_algo() != "") { BOTAN_ASSERT(signing_key, "Signing key was set"); std::pair<std::string, Signature_Format> format = state.choose_sig_format(*signing_key, m_hash_algo, m_sig_algo, false, policy); PK_Signer signer(*signing_key, format.first, format.second); signer.update(state.client_hello()->random()); signer.update(state.server_hello()->random()); signer.update(params()); m_signature = signer.signature(rng); } state.hash().update(io.send(*this)); }
void FIPS140_SampleApplication() { if (!FIPS_140_2_ComplianceEnabled()) { cerr << "FIPS 140-2 compliance was turned off at compile time.\n"; abort(); } // check self test status if (GetPowerUpSelfTestStatus() != POWER_UP_SELF_TEST_PASSED) { cerr << "Automatic power-up self test failed.\n"; abort(); } cout << "0. Automatic power-up self test passed.\n"; // simulate a power-up self test error SimulatePowerUpSelfTestFailure(); try { // trying to use a crypto algorithm after power-up self test error will result in an exception AES::Encryption aes; // should not be here cerr << "Use of AES failed to cause an exception after power-up self test error.\n"; abort(); } catch (SelfTestFailure &e) { cout << "1. Caught expected exception when simulating self test failure. Exception message follows: "; cout << e.what() << endl; } // clear the self test error state and redo power-up self test DoDllPowerUpSelfTest(); if (GetPowerUpSelfTestStatus() != POWER_UP_SELF_TEST_PASSED) { cerr << "Re-do power-up self test failed.\n"; abort(); } cout << "2. Re-do power-up self test passed.\n"; // encrypt and decrypt const byte key[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; const byte iv[] = {0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; const byte plaintext[] = { // "Now is the time for all " without tailing 0 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20}; byte ciphertext[24]; byte decrypted[24]; CFB_FIPS_Mode<DES_EDE3>::Encryption encryption_DES_EDE3_CFB; encryption_DES_EDE3_CFB.SetKeyWithIV(key, sizeof(key), iv); encryption_DES_EDE3_CFB.ProcessString(ciphertext, plaintext, 23); CFB_FIPS_Mode<DES_EDE3>::Decryption decryption_DES_EDE3_CFB; decryption_DES_EDE3_CFB.SetKeyWithIV(key, sizeof(key), iv); decryption_DES_EDE3_CFB.ProcessString(decrypted, ciphertext, 24); if (memcmp(plaintext, decrypted, 24) != 0) { cerr << "DES-EDE3-CFB Encryption/decryption failed.\n"; abort(); } cout << "3. DES-EDE3-CFB Encryption/decryption succeeded.\n"; // hash const byte message[] = {'a', 'b', 'c'}; const byte expectedDigest[] = {0xA9,0x99,0x3E,0x36,0x47,0x06,0x81,0x6A,0xBA,0x3E,0x25,0x71,0x78,0x50,0xC2,0x6C,0x9C,0xD0,0xD8,0x9D}; byte digest[20]; SHA1 sha; sha.Update(message, 3); sha.Final(digest); if (memcmp(digest, expectedDigest, 20) != 0) { cerr << "SHA-1 hash failed.\n"; abort(); } cout << "4. SHA-1 hash succeeded.\n"; // create auto-seeded X9.17 RNG object, if available #ifdef OS_RNG_AVAILABLE AutoSeededX917RNG<DES_EDE3> rng; #else // this is used to allow this function to compile on platforms that don't have auto-seeded RNGs RandomNumberGenerator &rng(NullRNG()); #endif // generate DSA key DSA::PrivateKey dsaPrivateKey; dsaPrivateKey.GenerateRandomWithKeySize(rng, 1024); DSA::PublicKey dsaPublicKey; dsaPublicKey.AssignFrom(dsaPrivateKey); if (!dsaPrivateKey.Validate(rng, 3) || !dsaPublicKey.Validate(rng, 3)) { cerr << "DSA key generation failed.\n"; abort(); } cout << "5. DSA key generation succeeded.\n"; // encode DSA key std::string encodedDsaPublicKey, encodedDsaPrivateKey; dsaPublicKey.DEREncode(StringSink(encodedDsaPublicKey).Ref()); dsaPrivateKey.DEREncode(StringSink(encodedDsaPrivateKey).Ref()); // decode DSA key DSA::PrivateKey decodedDsaPrivateKey; decodedDsaPrivateKey.BERDecode(StringStore(encodedDsaPrivateKey).Ref()); DSA::PublicKey decodedDsaPublicKey; decodedDsaPublicKey.BERDecode(StringStore(encodedDsaPublicKey).Ref()); if (!decodedDsaPrivateKey.Validate(rng, 3) || !decodedDsaPublicKey.Validate(rng, 3)) { cerr << "DSA key encode/decode failed.\n"; abort(); } cout << "6. DSA key encode/decode succeeded.\n"; // sign and verify byte signature[40]; DSA::Signer signer(dsaPrivateKey); assert(signer.SignatureLength() == 40); signer.SignMessage(rng, message, 3, signature); DSA::Verifier verifier(dsaPublicKey); if (!verifier.VerifyMessage(message, 3, signature, sizeof(signature))) { cerr << "DSA signature and verification failed.\n"; abort(); } cout << "7. DSA signature and verification succeeded.\n"; // try to verify an invalid signature signature[0] ^= 1; if (verifier.VerifyMessage(message, 3, signature, sizeof(signature))) { cerr << "DSA signature verification failed to detect bad signature.\n"; abort(); } cout << "8. DSA signature verification successfully detected bad signature.\n"; // try to use an invalid key length try { ECB_Mode<DES_EDE3>::Encryption encryption_DES_EDE3_ECB; encryption_DES_EDE3_ECB.SetKey(key, 5); // should not be here cerr << "DES-EDE3 implementation did not detect use of invalid key length.\n"; abort(); } catch (InvalidArgument &e) { cout << "9. Caught expected exception when using invalid key length. Exception message follows: "; cout << e.what() << endl; } cout << "\nFIPS 140-2 Sample Application completed normally.\n"; }
fostlib::nullable<fostlib::jwt::token> fostlib::jwt::token::load( f5::u8view t, const std::function<std::vector<f5::byte>(json, json)> &lambda) { const auto parts = split(t, "."); if (parts.size() != 3u) return fostlib::null; try { const static json jwt("JWT"); const static json hs256("HS256"); const static json eddsa("EdDSA"); const base64_string b64_header{parts[0]}; const auto v64_header = coerce<std::vector<unsigned char>>(b64_header); const auto u8_header = coerce<utf8_string>(v64_header); const auto str_header = coerce<string>(u8_header); const auto header = json::parse(str_header); if (header["typ"] != jwt) { log::warning(c_fost)("", "JWT type mismatch")("typ", header["typ"]); return fostlib::null; } const base64_string b64_payload(parts[1]); const auto v64_payload = coerce<std::vector<unsigned char>>(b64_payload); const auto u8_payload = coerce<utf8_string>(v64_payload); const auto str_payload = coerce<string>(u8_payload); const auto payload = json::parse(str_payload); const base64_string b64_signature(parts[2]); const auto v64_signature = coerce<std::vector<unsigned char>>(b64_signature); if (header["alg"] == hs256) { hmac signer(sha256, lambda(header, payload)); signer << parts[0] << "." << parts[1]; const auto signature = signer.digest(); if (not crypto_compare(signature, v64_signature)) { log::warning(c_fost)("", "JWT signature mismatch"); return fostlib::null; } } else if (header["alg"] == eddsa) { if (not fostlib::ed25519::verify( lambda(header, payload), (parts[0] + "." + parts[1]).data(), v64_signature)) { log::warning(c_fost)("", "EdDSA verification failed"); return fostlib::null; } } else { log::warning(c_fost)("", "JWT algorithm mismatch")( "alg", header["alg"]); return fostlib::null; } if (payload.has_key("exp")) { auto exp = c_epoch + fostlib::timediff(fostlib::seconds( fostlib::coerce<int64_t>(payload["exp"]))); if (exp < fostlib::timestamp::now()) { log::warning(c_fost)("", "JWT expired")("expires", exp); return fostlib::null; } } return fostlib::jwt::token{header, payload}; } catch (fostlib::exceptions::parse_error &e) { log::warning(c_fost)("", "JWT parse error")("error", e); return fostlib::null; } }
int send_rsa(bool server, std::string data, std::string& recieved, int sock) { CryptoPP::AutoSeededRandomPool rng; //Do RSA Encryption here std::string plain, encrypted, decrypted, signature, recovered, tdecoded; bool result; CryptoPP::RSAES_OAEP_SHA_Encryptor other_pub; CryptoPP::RSAES_OAEP_SHA_Encryptor my_pub; CryptoPP::RSAES_OAEP_SHA_Decryptor my_priv; if(server) { { CryptoPP::HexDecoder decoder; decoder.Put( (byte*)bank_priv, bank_priv_size ); decoder.MessageEnd(); my_priv.AccessKey().Load( decoder ); } { CryptoPP::HexDecoder decoder; decoder.Put( (byte*)atm_pub, atm_pub_size ); decoder.MessageEnd(); other_pub.AccessKey().Load( decoder ); } { CryptoPP::HexDecoder decoder; decoder.Put( (byte*)bank_pub, bank_pub_size); decoder.MessageEnd(); my_pub.AccessKey().Load( decoder ); } } else { { CryptoPP::HexDecoder decoder; decoder.Put( (byte*)atm_pub, atm_pub_size); decoder.MessageEnd(); my_pub.AccessKey().Load( decoder ); } { CryptoPP::HexDecoder decoder; decoder.Put( (byte*)bank_pub, bank_pub_size ); decoder.MessageEnd(); other_pub.AccessKey().Load( decoder ); } { CryptoPP::HexDecoder decoder; decoder.Put( (byte*)atm_priv, atm_priv_size ); decoder.MessageEnd(); my_priv.AccessKey().Load( decoder ); } } CryptoPP::RSASS<CryptoPP::PSSR, CryptoPP::SHA1>::Signer signer( my_priv ); //Run the data through the RSA encryption CryptoPP::StringSource( data, true, new CryptoPP::PK_EncryptorFilter( rng, other_pub, new CryptoPP::StringSink( encrypted ))); //Sign the encrypted data size_t length = signer.MaxSignatureLength(); byte sig_buff[length]; signer.SignMessage(rng, (byte *)encrypted.c_str(), encrypted.length(), sig_buff); signature.assign((char *)sig_buff, length); CryptoPP::RSASS<CryptoPP::PSSR, CryptoPP::SHA1>::Verifier verifiermine( my_pub); data.assign(std::to_string(signature.length())); data.append("|"); data.append(signature); data.append(encrypted); int err = send_socket(data, recieved, sock); if (err != 0) { return -1; } if (recieved.find("|") == recieved.npos) { return -1; } int sig_length = atoi(recieved.substr(0, recieved.find("|")).c_str()); if (sig_length == 0) { return -1; } if (recieved.length() < sig_length + recieved.find("|")+1) { return -1; } recieved = recieved.substr(recieved.find("|")+1, recieved.length()-recieved.find("|")-1); std::string other_signature = recieved.substr(0, sig_length); std::string other_encrypted = recieved.substr(sig_length, recieved.length() - sig_length); if (other_signature.length() != (unsigned int)sig_length) { return -1; } CryptoPP::RSASS<CryptoPP::PSSR, CryptoPP::SHA1>::Verifier verifier( other_pub ); result = verifier.VerifyMessage((byte *)other_encrypted.c_str(), other_encrypted.length(), (byte *)other_signature.c_str(), other_signature.length()); if (result == false) { return -1;//Signature failed if it returns -1 } CryptoPP::StringSource( other_encrypted, true, new CryptoPP::PK_DecryptorFilter( rng, my_priv, new CryptoPP::StringSink( decrypted ))); recieved.assign(decrypted); return 0; }
bool CREAMClient::createDelegation(const std::string& delegation_id, const std::string& proxy) { logger.msg(VERBOSE, "Creating delegation"); action = "getProxyReq"; PayloadSOAP req(cream_ns); req.NewChild("deleg:" + action).NewChild("delegationID") = delegation_id; XMLNode response; if (!process(req, response, "http://www.gridsite.org/namespaces/delegation-2/")) return false; std::string proxyRequestStr = (std::string)response["getProxyReqReturn"]; if (proxyRequestStr.empty()) { logger.msg(VERBOSE, "Malformed response: missing getProxyReqReturn"); return false; } //Sign the proxy certificate Credential signer(proxy, "", cadir, cafile); std::string signedCert; // TODO: Hardcoded time shift - VERY BAD approach Time start_time = Time() - Period(300); Time end_time = signer.GetEndTime(); if(end_time < start_time) { logger.msg(VERBOSE, "Delegatable credentials expired: %s",end_time.str()); return false; } // CREAM is picky about end time of delegated credentials, so // make sure it does not exceed end time of signer Credential proxy_cred(start_time,end_time-start_time); proxy_cred.InquireRequest(proxyRequestStr); proxy_cred.SetProxyPolicy("gsi2", "", "", -1); if (!(signer.SignRequest(&proxy_cred, signedCert))) { logger.msg(VERBOSE, "Failed signing certificate request"); return false; } std::string signedOutputCert, signedOutputCertChain; signer.OutputCertificate(signedOutputCert); signer.OutputCertificateChain(signedOutputCertChain); signedCert.append(signedOutputCert).append(signedOutputCertChain); action = "putProxy"; req = PayloadSOAP(cream_ns); XMLNode putProxyRequest = req.NewChild("deleg:" + action); putProxyRequest.NewChild("delegationID") = delegation_id; putProxyRequest.NewChild("proxy") = signedCert; response = XMLNode(); if (!process(req, response, "http://www.gridsite.org/namespaces/delegation-2/")) return false; if (!response) { logger.msg(VERBOSE, "Failed putting signed delegation certificate to service"); return false; } return true; }
/* * Create a PKCS #10 certificate request */ PKCS10_Request create_cert_req(const X509_Cert_Options& opts, const Private_Key& key, const std::string& hash_fn, RandomNumberGenerator& rng) { AlgorithmIdentifier sig_algo; X509_DN subject_dn; AlternativeName subject_alt; opts.sanity_check(); std::vector<byte> pub_key = X509::BER_encode(key); std::unique_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo)); load_info(opts, subject_dn, subject_alt); const size_t PKCS10_VERSION = 0; Extensions extensions; extensions.add( new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit)); extensions.add( new Cert_Extension::Key_Usage( opts.is_CA ? Key_Constraints(KEY_CERT_SIGN | CRL_SIGN) : find_constraints(key, opts.constraints) ) ); extensions.add( new Cert_Extension::Extended_Key_Usage(opts.ex_constraints)); extensions.add( new Cert_Extension::Subject_Alternative_Name(subject_alt)); DER_Encoder tbs_req; tbs_req.start_cons(SEQUENCE) .encode(PKCS10_VERSION) .encode(subject_dn) .raw_bytes(pub_key) .start_explicit(0); if(opts.challenge != "") { ASN1_String challenge(opts.challenge, DIRECTORY_STRING); tbs_req.encode( Attribute("PKCS9.ChallengePassword", DER_Encoder().encode(challenge).get_contents_unlocked() ) ); } tbs_req.encode( Attribute("PKCS9.ExtensionRequest", DER_Encoder() .start_cons(SEQUENCE) .encode(extensions) .end_cons() .get_contents_unlocked() ) ) .end_explicit() .end_cons(); const std::vector<byte> req = X509_Object::make_signed(signer.get(), rng, sig_algo, tbs_req.get_contents()); return PKCS10_Request(req); }
Botan::SecureVector<boost::uint8_t> RsaEncoderDecoder::signData(const boost::uint8_t *data, size_t size) { Botan::PK_Signer signer(*privKey_, "EMSA3(SHA-1)"); return signer.sign_message(data, size, rng_); }