/* * Encode PKCS#5 PBES2 parameters */ MemoryVector<byte> PBE_PKCS5v20::encode_params() const { return DER_Encoder() .start_cons(SEQUENCE) .encode( AlgorithmIdentifier("PKCS5.PBKDF2", DER_Encoder() .start_cons(SEQUENCE) .encode(salt, OCTET_STRING) .encode(iterations) .encode(key_length) .end_cons() .get_contents() ) ) .encode( AlgorithmIdentifier(block_cipher->name() + "/CBC", DER_Encoder() .encode(iv, OCTET_STRING) .get_contents() ) ) .end_cons() .get_contents(); }
std::unique_ptr<RSA_PrivateKey> make_openssl_rsa_private_key(RandomNumberGenerator& rng, size_t rsa_bits) { if (rsa_bits > INT_MAX) throw Internal_Error("rsa_bits overflow"); secure_vector<uint8_t> seed(BOTAN_SYSTEM_RNG_POLL_REQUEST); rng.randomize(seed.data(), seed.size()); RAND_seed(seed.data(), seed.size()); std::unique_ptr<BIGNUM, std::function<void (BIGNUM*)>> bn(BN_new(), BN_free); if(!bn) throw OpenSSL_Error("BN_new"); if(!BN_set_word(bn.get(), RSA_F4)) throw OpenSSL_Error("BN_set_word"); std::unique_ptr<RSA, std::function<void (RSA*)>> rsa(RSA_new(), RSA_free); if(!rsa) throw OpenSSL_Error("RSA_new"); if(!RSA_generate_key_ex(rsa.get(), rsa_bits, bn.get(), nullptr)) throw OpenSSL_Error("RSA_generate_key_ex"); uint8_t* der = nullptr; int bytes = i2d_RSAPrivateKey(rsa.get(), &der); if(bytes < 0) throw OpenSSL_Error("i2d_RSAPrivateKey"); const secure_vector<uint8_t> keydata(der, der + bytes); memset(der, 0, bytes); free(der); return std::unique_ptr<Botan::RSA_PrivateKey> (new RSA_PrivateKey(AlgorithmIdentifier(), keydata)); }
/* * Compress a message */ void CMS_Encoder::compress(const std::string& algo) { if(!CMS_Encoder::can_compress_with(algo)) throw Invalid_Argument("CMS_Encoder: Cannot compress with " + algo); Filter* compressor = 0; #if defined(BOTAN_HAS_COMPRESSOR_ZLIB) if(algo == "Zlib") compressor = new Zlib_Compression; #endif if(compressor == 0) throw Internal_Error("CMS: Couldn't get ahold of a compressor"); Pipe pipe(compressor); pipe.process_msg(data); SecureVector<byte> compressed = pipe.read_all(); DER_Encoder encoder; encoder.start_cons(SEQUENCE). encode(static_cast<size_t>(0)). encode(AlgorithmIdentifier("Compression." + algo, MemoryVector<byte>())). raw_bytes(make_econtent(compressed, type)). end_cons(); add_layer("CMS.CompressedData", encoder); }
AlgorithmIdentifier alg_id() const { key->affirm_init(); SecureVector<byte> params = encode_der_ec_dompar(key->domain_parameters(), key->m_param_enc); return AlgorithmIdentifier(key->get_oid(), params); }
AlgorithmIdentifier GOST_3410_PublicKey::algorithm_identifier() const { std::vector<byte> params = DER_Encoder().start_cons(SEQUENCE) .encode(OID(domain().get_oid())) .end_cons() .get_contents_unlocked(); return AlgorithmIdentifier(get_oid(), params); }
CertID::CertID(const X509_Certificate& issuer, const X509_Certificate& subject) { /* In practice it seems some responders, including, notably, ocsp.verisign.com, will reject anything but SHA-1 here */ std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-160")); m_hash_id = AlgorithmIdentifier(hash->name(), AlgorithmIdentifier::USE_NULL_PARAM); m_issuer_key_hash = unlock(hash->process(issuer.subject_public_key_bitstring())); m_issuer_dn_hash = unlock(hash->process(subject.raw_issuer_dn())); m_subject_serial = BigInt::decode(subject.serial_number()); }
AlgorithmIdentifier EC_PublicKey::algorithm_identifier() const { return AlgorithmIdentifier(get_oid(), DER_domain()); }
Result DigestAlgorithmIdentifier(Reader& input, /*out*/ DigestAlgorithm& algorithm) { return AlgorithmIdentifier(DigestAlgorithmOIDValue, input, algorithm); }
Result SignatureAlgorithmIdentifier(Reader& input, /*out*/ SignatureAlgorithm& algorithm) { return AlgorithmIdentifier(SignatureAlgorithmOIDValue, input, algorithm); }
AlgorithmIdentifier DL_Scheme_PublicKey::algorithm_identifier() const { return AlgorithmIdentifier(get_oid(), m_group.DER_encode(group_format())); }
AlgorithmIdentifier PKCS11_EC_PrivateKey::algorithm_identifier() const { return AlgorithmIdentifier(get_oid(), domain().DER_encode(EC_DOMPAR_ENC_EXPLICIT)); }
secure_vector<uint8_t> pbes2_decrypt(const secure_vector<uint8_t>& key_bits, const std::string& passphrase, const std::vector<uint8_t>& params) { AlgorithmIdentifier kdf_algo, enc_algo; BER_Decoder(params) .start_cons(SEQUENCE) .decode(kdf_algo) .decode(enc_algo) .end_cons(); AlgorithmIdentifier prf_algo; if(kdf_algo.oid != OIDS::lookup("PKCS5.PBKDF2")) throw Decoding_Error("PBE-PKCS5 v2.0: Unknown KDF algorithm " + kdf_algo.oid.as_string()); secure_vector<uint8_t> salt; size_t iterations = 0, key_length = 0; BER_Decoder(kdf_algo.parameters) .start_cons(SEQUENCE) .decode(salt, OCTET_STRING) .decode(iterations) .decode_optional(key_length, INTEGER, UNIVERSAL) .decode_optional(prf_algo, SEQUENCE, CONSTRUCTED, AlgorithmIdentifier("HMAC(SHA-160)", AlgorithmIdentifier::USE_NULL_PARAM)) .end_cons(); const std::string cipher = OIDS::lookup(enc_algo.oid); const std::vector<std::string> cipher_spec = split_on(cipher, '/'); if(cipher_spec.size() != 2) throw Decoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher); if(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM") throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); if(salt.size() < 8) throw Decoding_Error("PBE-PKCS5 v2.0: Encoded salt is too small"); secure_vector<uint8_t> iv; BER_Decoder(enc_algo.parameters).decode(iv, OCTET_STRING).verify_end(); const std::string prf = OIDS::lookup(prf_algo.oid); std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); std::unique_ptr<Cipher_Mode> dec(get_cipher_mode(cipher, DECRYPTION)); if(!dec) throw Decoding_Error("PBE-PKCS5 cannot decrypt no cipher " + cipher); if(key_length == 0) key_length = dec->key_spec().maximum_keylength(); dec->set_key(pbkdf->pbkdf_iterations(key_length, passphrase, salt.data(), salt.size(), iterations)); dec->start(iv); secure_vector<uint8_t> buf = key_bits; dec->finish(buf); return buf; }
AlgorithmIdentifier Curve25519_PublicKey::algorithm_identifier() const { return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_NULL_PARAM); }