diff options
-rw-r--r-- | src/cli/pubkey.cpp | 20 | ||||
-rw-r--r-- | src/lib/pubkey/pk_keys.cpp | 49 | ||||
-rw-r--r-- | src/lib/pubkey/pk_keys.h | 25 | ||||
-rw-r--r-- | src/lib/x509/certstor_sql/certstor_sql.cpp | 6 | ||||
-rw-r--r-- | src/lib/x509/x509cert.cpp | 17 |
5 files changed, 79 insertions, 38 deletions
diff --git a/src/cli/pubkey.cpp b/src/cli/pubkey.cpp index ef9585a19..a6f77fe0c 100644 --- a/src/cli/pubkey.cpp +++ b/src/cli/pubkey.cpp @@ -27,6 +27,26 @@ namespace Botan_CLI { +class PK_Fingerprint final : public Command + { + public: + PK_Fingerprint() : Command("fingerprint --algo=SHA-256 *keys") {} + + void go() override + { + const std::string hash_algo = get_arg("algo"); + + for(std::string key_file : get_arg_list("keys")) + { + std::unique_ptr<Botan::Public_Key> key(Botan::X509::load_key(key_file)); + + output() << key_file << ": " << key->fingerprint_public(hash_algo) << "\n"; + } + } + }; + +BOTAN_REGISTER_COMMAND("fingerprint", PK_Fingerprint); + class PK_Keygen final : public Command { public: diff --git a/src/lib/pubkey/pk_keys.cpp b/src/lib/pubkey/pk_keys.cpp index 52304eb03..cdf8ae8ff 100644 --- a/src/lib/pubkey/pk_keys.cpp +++ b/src/lib/pubkey/pk_keys.cpp @@ -14,6 +14,27 @@ namespace Botan { +std::string create_hex_fingerprint(const uint8_t bits[], + size_t bits_len, + const std::string& hash_name) + { + std::unique_ptr<HashFunction> hash_fn(HashFunction::create_or_throw(hash_name)); + const std::string hex_hash = hex_encode(hash_fn->process(bits, bits_len)); + + std::string fprint; + + for(size_t i = 0; i != hex_hash.size(); i += 2) + { + if(i != 0) + fprint.push_back(':'); + + fprint.push_back(hex_hash[i]); + fprint.push_back(hex_hash[i+1]); + } + + return fprint; + } + std::vector<uint8_t> Public_Key::subject_public_key() const { return DER_Encoder() @@ -52,27 +73,19 @@ secure_vector<uint8_t> Private_Key::private_key_info() const } /* -* Hash of the PKCS #8 encoding for this key object +* Hash of the X.509 subjectPublicKey encoding */ -std::string Private_Key::fingerprint(const std::string& alg) const +std::string Public_Key::fingerprint_public(const std::string& hash_algo) const { - secure_vector<uint8_t> buf = private_key_bits(); - std::unique_ptr<HashFunction> hash(HashFunction::create(alg)); - hash->update(buf); - const auto hex_print = hex_encode(hash->final()); - - std::string formatted_print; - - for(size_t i = 0; i != hex_print.size(); i += 2) - { - formatted_print.push_back(hex_print[i]); - formatted_print.push_back(hex_print[i+1]); - - if(i != hex_print.size() - 2) - formatted_print.push_back(':'); - } + return create_hex_fingerprint(subject_public_key(), hash_algo); + } - return formatted_print; +/* +* Hash of the PKCS #8 encoding for this key object +*/ +std::string Private_Key::fingerprint_private(const std::string& hash_algo) const + { + return create_hex_fingerprint(private_key_bits(), hash_algo); } std::unique_ptr<PK_Ops::Encryption> diff --git a/src/lib/pubkey/pk_keys.h b/src/lib/pubkey/pk_keys.h index f513cea6c..79254ea29 100644 --- a/src/lib/pubkey/pk_keys.h +++ b/src/lib/pubkey/pk_keys.h @@ -85,6 +85,11 @@ class BOTAN_PUBLIC_API(2,0) Public_Key */ std::vector<uint8_t> subject_public_key() const; + /** + * @return Hash of the subject public key + */ + std::string fingerprint_public(const std::string& alg = "SHA-256") const; + // Internal or non-public declarations follow /** @@ -192,7 +197,13 @@ class BOTAN_PUBLIC_API(2,0) Private_Key : public virtual Public_Key /** * @return Hash of the PKCS #8 encoding for this key object */ - std::string fingerprint(const std::string& alg = "SHA") const; + std::string fingerprint_private(const std::string& alg) const; + + BOTAN_DEPRECATED("Use fingerprint_private or fingerprint_public") + inline std::string fingerprint(const std::string& alg) const + { + return fingerprint_private(alg); // match behavior in previous versions + } /** * This is an internal library function exposed on key types. @@ -289,6 +300,18 @@ typedef PK_Key_Agreement_Key PK_KA_Key; typedef Public_Key X509_PublicKey; typedef Private_Key PKCS8_PrivateKey; +std::string BOTAN_PUBLIC_API(2,4) + create_hex_fingerprint(const uint8_t bits[], size_t len, + const std::string& hash_name); + +template<typename Alloc> +std::string create_hex_fingerprint(const std::vector<uint8_t, Alloc>& vec, + const std::string& hash_name) + { + return create_hex_fingerprint(vec.data(), vec.size(), hash_name); + } + + } #endif diff --git a/src/lib/x509/certstor_sql/certstor_sql.cpp b/src/lib/x509/certstor_sql/certstor_sql.cpp index 36acd6ce3..6acfed060 100644 --- a/src/lib/x509/certstor_sql/certstor_sql.cpp +++ b/src/lib/x509/certstor_sql/certstor_sql.cpp @@ -186,7 +186,7 @@ std::shared_ptr<const Private_Key> Certificate_Store_In_SQL::find_key(const X509 std::vector<std::shared_ptr<const X509_Certificate>> Certificate_Store_In_SQL::find_certs_for_key(const Private_Key& key) const { - auto fpr = key.fingerprint("SHA-256"); + auto fpr = key.fingerprint_private("SHA-256"); auto stmt = m_database->new_statement("SELECT certificate FROM " + m_prefix + "certificates WHERE priv_fingerprint == ?1"); stmt->bind(1,fpr); @@ -209,7 +209,7 @@ bool Certificate_Store_In_SQL::insert_key(const X509_Certificate& cert, const Pr return false; auto pkcs8 = PKCS8::BER_encode(key, m_rng, m_password); - auto fpr = key.fingerprint("SHA-256"); + auto fpr = key.fingerprint_private("SHA-256"); auto stmt1 = m_database->new_statement( "INSERT OR REPLACE INTO " + m_prefix + "keys ( fingerprint, key ) VALUES ( ?1, ?2 )"); @@ -230,7 +230,7 @@ bool Certificate_Store_In_SQL::insert_key(const X509_Certificate& cert, const Pr void Certificate_Store_In_SQL::remove_key(const Private_Key& key) { - auto fpr = key.fingerprint("SHA-256"); + auto fpr = key.fingerprint_private("SHA-256"); auto stmt = m_database->new_statement("DELETE FROM " + m_prefix + "keys WHERE fingerprint == ?1"); stmt->bind(1,fpr); diff --git a/src/lib/x509/x509cert.cpp b/src/lib/x509/x509cert.cpp index acd6b3362..1370d52b0 100644 --- a/src/lib/x509/x509cert.cpp +++ b/src/lib/x509/x509cert.cpp @@ -662,22 +662,7 @@ std::vector<std::string> X509_Certificate::policies() const std::string X509_Certificate::fingerprint(const std::string& hash_name) const { - std::unique_ptr<HashFunction> hash(HashFunction::create_or_throw(hash_name)); - hash->update(this->BER_encode()); - const std::string hex_print = hex_encode(hash->final()); - - std::string formatted_print; - - for(size_t i = 0; i != hex_print.size(); i += 2) - { - formatted_print.push_back(hex_print[i]); - formatted_print.push_back(hex_print[i+1]); - - if(i != hex_print.size() - 2) - formatted_print.push_back(':'); - } - - return formatted_print; + return create_hex_fingerprint(this->BER_encode(), hash_name); } bool X509_Certificate::matches_dns_name(const std::string& name) const |