From 87776490b4b5a630037636757f24046185cab8c8 Mon Sep 17 00:00:00 2001 From: David Rose Date: Sun, 6 Sep 2009 22:32:05 +0000 Subject: [PATCH] get_signature_public_key() --- panda/src/express/multifile.I | 14 ++++++++ panda/src/express/multifile.cxx | 62 ++++++++++++++++++++++++++++----- panda/src/express/multifile.h | 3 ++ 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/panda/src/express/multifile.I b/panda/src/express/multifile.I index c43766723a..b1bfcc0d44 100644 --- a/panda/src/express/multifile.I +++ b/panda/src/express/multifile.I @@ -422,6 +422,20 @@ normalize_streampos(streampos fpos) const { return word_to_streampos(streampos_to_word(fpos)); } +//////////////////////////////////////////////////////////////////// +// Function: Multifile::tohex +// Access: Private, Static +// Description: Converts a single nibble to a hex digit. +//////////////////////////////////////////////////////////////////// +INLINE char Multifile:: +tohex(unsigned int nibble) { + nibble &= 0xf; + if (nibble < 10) { + return nibble + '0'; + } + return nibble - 10 + 'a'; +} + //////////////////////////////////////////////////////////////////// // Function: Multifile::Subfile::Constructor // Access: Public diff --git a/panda/src/express/multifile.cxx b/panda/src/express/multifile.cxx index af2d0c27ef..210ccf9519 100644 --- a/panda/src/express/multifile.cxx +++ b/panda/src/express/multifile.cxx @@ -795,13 +795,18 @@ add_signature(const Multifile::CertChain &cert_chain, EVP_PKEY *pkey) { //////////////////////////////////////////////////////////////////// // Function: Multifile::get_num_signatures // Access: Published -// Description: Returns the number of signatures found on the -// Multifile. This reports only the signatures that -// match the contents of the Multifile; signatures that -// have become invalidated by a change in the Multifile -// are not reported here. However, this does not verify -// that the certificates themselves are valid; only that -// they match the Multifile contents. +// Description: Returns the number of matching signatures found on +// the Multifile. These signatures may be iterated via +// get_signature() and related methods. +// +// A signature on this list is guaranteed to match the +// Multifile contents, proving that the Multifile has +// been unmodified since the signature was applied. +// However, this does not guarantee that the certificate +// itself is actually from who it says it is from; only +// that it matches the Multifile contents. See +// validate_signature_certificate() to authenticate a +// particular certificate. //////////////////////////////////////////////////////////////////// int Multifile:: get_num_signatures() const { @@ -832,8 +837,10 @@ get_signature(int n) const { // Description: Returns the "subject name" for the nth signature found // on the Multifile. This is a string formatted // according to RFC2253 that should more-or-less -// identify a particular certificate. See the comments -// in get_num_signatures(). +// identify a particular certificate; when paired with +// the public key (see get_signature_public_key()), it +// can uniquely identify a certificate. See the +// comments in get_num_signatures(). //////////////////////////////////////////////////////////////////// string Multifile:: get_signature_subject_name(int n) const { @@ -906,6 +913,43 @@ get_signature_common_name(int n) const { } #endif // HAVE_OPENSSL +#ifdef HAVE_OPENSSL +//////////////////////////////////////////////////////////////////// +// Function: Multifile::get_signature_public_key +// Access: Published +// Description: Returns the public key used for the nth signature +// found on the Multifile. This is encoded in DER form +// and returned as a string of hex digits. +// +// This can be used, in conjunction with the subject +// name (see get_signature_subject_name()), to uniquely +// identify a particular certificate and its subsequent +// reissues. See the comments in get_num_signatures(). +//////////////////////////////////////////////////////////////////// +string Multifile:: +get_signature_public_key(int n) const { + const CertChain &cert_chain = get_signature(n); + nassertr(!cert_chain.empty(), string()); + + EVP_PKEY *pkey = X509_get_pubkey(cert_chain[0]._cert); + if (pkey != NULL) { + int key_len = i2d_PublicKey(pkey, NULL); + unsigned char *key_buf = new unsigned char[key_len]; + unsigned char *p = key_buf; + i2d_PublicKey(pkey, &p); + string result; + for (int i = 0; i < key_len; ++i) { + result += tohex(key_buf[i] >> 4); + result += tohex(key_buf[i]); + } + delete[] key_buf; + return result; + } + + return string(); +} +#endif // HAVE_OPENSSL + #ifdef HAVE_OPENSSL //////////////////////////////////////////////////////////////////// // Function: Multifile::write_signature_certificate diff --git a/panda/src/express/multifile.h b/panda/src/express/multifile.h index 837f4bbe08..aa36288f15 100644 --- a/panda/src/express/multifile.h +++ b/panda/src/express/multifile.h @@ -104,6 +104,7 @@ PUBLISHED: const CertChain &get_signature(int n) const; string get_signature_subject_name(int n) const; string get_signature_common_name(int n) const; + string get_signature_public_key(int n) const; void write_signature_certificate(int n, ostream &out) const; int validate_signature_certificate(int n) const; @@ -209,6 +210,8 @@ private: void check_signatures(); + static INLINE char tohex(unsigned int nibble); + typedef ov_set > Subfiles; Subfiles _subfiles; typedef pvector PendingSubfiles;