mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
common_name -> friendly_name
This commit is contained in:
parent
df998fbf48
commit
2552864754
@ -165,7 +165,7 @@ AuthDialog(const wxString &cert_filename, const wxString &cert_dir) :
|
|||||||
_verify_result = -1;
|
_verify_result = -1;
|
||||||
|
|
||||||
read_cert_file(cert_filename);
|
read_cert_file(cert_filename);
|
||||||
get_common_name();
|
get_friendly_name();
|
||||||
verify_cert();
|
verify_cert();
|
||||||
layout();
|
layout();
|
||||||
}
|
}
|
||||||
@ -295,39 +295,52 @@ read_cert_file(const wxString &cert_filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: AuthDialog::get_common_name
|
// Function: AuthDialog::get_friendly_name
|
||||||
// Access: Private
|
// Access: Private
|
||||||
// Description: Extracts the common_name from the certificate.
|
// Description: Extracts the "friendly name" from the certificate:
|
||||||
|
// the common name or email name.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void AuthDialog::
|
void AuthDialog::
|
||||||
get_common_name() {
|
get_friendly_name() {
|
||||||
if (_cert == NULL) {
|
if (_cert == NULL) {
|
||||||
_common_name.clear();
|
_friendly_name.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A complex OpenSSL interface to extract out the common name in
|
|
||||||
// utf-8.
|
|
||||||
X509_NAME *xname = X509_get_subject_name(_cert);
|
|
||||||
if (xname != NULL) {
|
|
||||||
int pos = X509_NAME_get_index_by_NID(xname, NID_commonName, -1);
|
|
||||||
if (pos != -1) {
|
|
||||||
// We just get the first common name. I guess it's possible to
|
|
||||||
// have more than one; not sure what that means in this context.
|
|
||||||
X509_NAME_ENTRY *xentry = X509_NAME_get_entry(xname, pos);
|
|
||||||
if (xentry != NULL) {
|
|
||||||
ASN1_STRING *data = X509_NAME_ENTRY_get_data(xentry);
|
|
||||||
if (data != NULL) {
|
|
||||||
// We use "print" to dump the output to a memory BIO. Is
|
|
||||||
// there an easier way to decode the ASN1_STRING? Curse
|
|
||||||
// these incomplete docs.
|
|
||||||
BIO *mbio = BIO_new(BIO_s_mem());
|
|
||||||
ASN1_STRING_print_ex(mbio, data, ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB);
|
|
||||||
|
|
||||||
char *pp;
|
static const int nid_choices[] = {
|
||||||
long pp_size = BIO_get_mem_data(mbio, &pp);
|
NID_pkcs9_emailAddress,
|
||||||
_common_name = wxString(pp, wxConvUTF8, pp_size);
|
NID_commonName,
|
||||||
BIO_free(mbio);
|
-1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Choose the first NID that exists on the cert.
|
||||||
|
for (int ni = 0; nid_choices[ni] != -1; ++ni) {
|
||||||
|
int nid = nid_choices[ni];
|
||||||
|
|
||||||
|
// A complex OpenSSL interface to extract out the name in utf-8.
|
||||||
|
X509_NAME *xname = X509_get_subject_name(_cert);
|
||||||
|
if (xname != NULL) {
|
||||||
|
int pos = X509_NAME_get_index_by_NID(xname, nid, -1);
|
||||||
|
if (pos != -1) {
|
||||||
|
// We just get the first common name. I guess it's possible to
|
||||||
|
// have more than one; not sure what that means in this context.
|
||||||
|
X509_NAME_ENTRY *xentry = X509_NAME_get_entry(xname, pos);
|
||||||
|
if (xentry != NULL) {
|
||||||
|
ASN1_STRING *data = X509_NAME_ENTRY_get_data(xentry);
|
||||||
|
if (data != NULL) {
|
||||||
|
// We use "print" to dump the output to a memory BIO. Is
|
||||||
|
// there an easier way to decode the ASN1_STRING? Curse
|
||||||
|
// these incomplete docs.
|
||||||
|
BIO *mbio = BIO_new(BIO_s_mem());
|
||||||
|
ASN1_STRING_print_ex(mbio, data, ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB);
|
||||||
|
|
||||||
|
char *pp;
|
||||||
|
long pp_size = BIO_get_mem_data(mbio, &pp);
|
||||||
|
_friendly_name = wxString(pp, wxConvUTF8, pp_size);
|
||||||
|
BIO_free(mbio);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -388,7 +401,7 @@ verify_cert() {
|
|||||||
|
|
||||||
X509_STORE_free(store);
|
X509_STORE_free(store);
|
||||||
|
|
||||||
cerr << "Got certificate from " << _common_name
|
cerr << "Got certificate from " << _friendly_name
|
||||||
<< ", verify_result = " << _verify_result << "\n";
|
<< ", verify_result = " << _verify_result << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +474,7 @@ get_text(wxString &header, wxString &text) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
text.Printf(verified_cert_text, _common_name.c_str(), _common_name.c_str(), _common_name.c_str());
|
text.Printf(verified_cert_text, _friendly_name.c_str(), _friendly_name.c_str(), _friendly_name.c_str());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case X509_V_ERR_CERT_NOT_YET_VALID:
|
case X509_V_ERR_CERT_NOT_YET_VALID:
|
||||||
@ -469,12 +482,12 @@ get_text(wxString &header, wxString &text) {
|
|||||||
case X509_V_ERR_CRL_NOT_YET_VALID:
|
case X509_V_ERR_CRL_NOT_YET_VALID:
|
||||||
case X509_V_ERR_CRL_HAS_EXPIRED:
|
case X509_V_ERR_CRL_HAS_EXPIRED:
|
||||||
header = _T("Expired signature!");
|
header = _T("Expired signature!");
|
||||||
text.Printf(expired_cert_text, _common_name.c_str());
|
text.Printf(expired_cert_text, _friendly_name.c_str());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
|
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
|
||||||
header = _T("Unverified signature!");
|
header = _T("Unverified signature!");
|
||||||
text.Printf(unknown_auth_cert_text, _common_name.c_str());
|
text.Printf(unknown_auth_cert_text, _friendly_name.c_str());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
|
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
|
||||||
|
@ -67,7 +67,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void read_cert_file(const wxString &cert_filename);
|
void read_cert_file(const wxString &cert_filename);
|
||||||
void get_common_name();
|
void get_friendly_name();
|
||||||
void verify_cert();
|
void verify_cert();
|
||||||
|
|
||||||
void layout();
|
void layout();
|
||||||
@ -84,7 +84,7 @@ private:
|
|||||||
X509 *_cert;
|
X509 *_cert;
|
||||||
STACK *_stack;
|
STACK *_stack;
|
||||||
|
|
||||||
wxString _common_name;
|
wxString _friendly_name;
|
||||||
int _verify_result;
|
int _verify_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -224,17 +224,19 @@ help() {
|
|||||||
" generate slightly smaller files, but compression takes longer. The\n"
|
" generate slightly smaller files, but compression takes longer. The\n"
|
||||||
" default is -" << default_compression_level << ".\n\n"
|
" default is -" << default_compression_level << ".\n\n"
|
||||||
|
|
||||||
" -S file.crt,[chain.crt],file.key[,\"password\"]\n"
|
" -S file.crt[,chain.crt[,file.key[,\"password\"]]]\n"
|
||||||
" Sign the multifile. The signing certificate should be in PEM form in\n"
|
" Sign the multifile. The signing certificate should be in PEM form in\n"
|
||||||
" file.crt, with its private key in PEM form in file.key. If the key\n"
|
" file.crt, with its private key in PEM form in file.key. If the key\n"
|
||||||
" is encrypted on-disk, specify the decryption password as the third\n"
|
" is encrypted on-disk, specify the decryption password as the third\n"
|
||||||
" option. If a certificate chain is required, chain.crt should also\n"
|
" option. If a certificate chain is required, chain.crt should also\n"
|
||||||
" be specified; note that the commas should be supplied even if this\n"
|
" be specified; note that the separating commas should be supplied\n"
|
||||||
" optional filename is omitted.\n"
|
" even if this optional filename is omitted.\n"
|
||||||
|
" You may also provide a single composite file that contains the\n"
|
||||||
|
" certificate, chain, and key in the same file.\n"
|
||||||
" PEM form is the form accepted by the Apache web server. The\n"
|
" PEM form is the form accepted by the Apache web server. The\n"
|
||||||
" signature is written to the multifile to prove it is unchanged; any\n"
|
" signature is written to the multifile to prove it is unchanged; any\n"
|
||||||
" subsequent change to the multifile will invalidate the signature.\n"
|
" subsequent change to the multifile will invalidate the signature.\n"
|
||||||
" This parameter may be repeated to sign the multifile with different\n"
|
" This parameter may be repeated to sign the multifile with additional\n"
|
||||||
" certificates.\n\n";
|
" certificates.\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,7 +393,13 @@ add_files(const vector_string ¶ms) {
|
|||||||
|
|
||||||
bool okflag = do_add_files(multifile, filenames);
|
bool okflag = do_add_files(multifile, filenames);
|
||||||
|
|
||||||
if (multifile->needs_repack()) {
|
bool needs_repack = multifile->needs_repack();
|
||||||
|
if (append) {
|
||||||
|
// If we specified -r mode, we always repack.
|
||||||
|
needs_repack = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needs_repack) {
|
||||||
if (!multifile->repack()) {
|
if (!multifile->repack()) {
|
||||||
cerr << "Failed to write " << multifile_name << ".\n";
|
cerr << "Failed to write " << multifile_name << ".\n";
|
||||||
okflag = false;
|
okflag = false;
|
||||||
@ -529,27 +537,27 @@ sign_multifile() {
|
|||||||
vector_string::iterator si;
|
vector_string::iterator si;
|
||||||
for (si = sign_params.begin(); si != sign_params.end(); ++si) {
|
for (si = sign_params.begin(); si != sign_params.end(); ++si) {
|
||||||
const string ¶m = (*si);
|
const string ¶m = (*si);
|
||||||
|
Filename certificate, chain, pkey;
|
||||||
|
string password;
|
||||||
|
|
||||||
size_t comma1 = param.find(',');
|
size_t comma1 = param.find(',');
|
||||||
if (comma1 == string::npos) {
|
if (comma1 == string::npos) {
|
||||||
cerr << "Signing parameter requires two commas: " << param << "\n";
|
certificate = Filename::from_os_specific(param);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
size_t comma2 = param.find(',', comma1 + 1);
|
|
||||||
if (comma2 == string::npos) {
|
|
||||||
cerr << "Signing parameter requires two commas: " << param << "\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
size_t comma3 = param.find(',', comma2 + 1);
|
|
||||||
|
|
||||||
Filename certificate = Filename::from_os_specific(param.substr(0, comma1));
|
|
||||||
Filename chain = Filename::from_os_specific(param.substr(comma1 + 1, comma2 - comma1 - 1));
|
|
||||||
Filename pkey;
|
|
||||||
string password;
|
|
||||||
if (comma3 != string::npos) {
|
|
||||||
pkey = Filename::from_os_specific(param.substr(comma2 + 1, comma3 - comma2 - 1));
|
|
||||||
password = param.substr(comma3 + 1);
|
|
||||||
} else {
|
} else {
|
||||||
pkey = Filename::from_os_specific(param.substr(comma2 + 1));
|
certificate = Filename::from_os_specific(param.substr(0, comma1));
|
||||||
|
size_t comma2 = param.find(',', comma1 + 1);
|
||||||
|
if (comma2 == string::npos) {
|
||||||
|
chain = Filename::from_os_specific(param.substr(comma1 + 1));
|
||||||
|
} else {
|
||||||
|
chain = Filename::from_os_specific(param.substr(comma1 + 1, comma2 - comma1 - 1));
|
||||||
|
size_t comma3 = param.find(',', comma2 + 1);
|
||||||
|
if (comma3 == string::npos) {
|
||||||
|
pkey = Filename::from_os_specific(param.substr(comma2 + 1));
|
||||||
|
} else {
|
||||||
|
pkey = Filename::from_os_specific(param.substr(comma2 + 1, comma3 - comma2 - 1));
|
||||||
|
password = param.substr(comma3 + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!multifile->add_signature(certificate, chain, pkey, password)) {
|
if (!multifile->add_signature(certificate, chain, pkey, password)) {
|
||||||
@ -675,7 +683,7 @@ list_files(const vector_string ¶ms) {
|
|||||||
if (num_signatures != 0) {
|
if (num_signatures != 0) {
|
||||||
cout << "\n";
|
cout << "\n";
|
||||||
for (i = 0; i < num_signatures; ++i) {
|
for (i = 0; i < num_signatures; ++i) {
|
||||||
cout << "Signed by " << multifile->get_signature_common_name(i);
|
cout << "Signed by " << multifile->get_signature_friendly_name(i);
|
||||||
int verify_result = multifile->validate_signature_certificate(i);
|
int verify_result = multifile->validate_signature_certificate(i);
|
||||||
if (verify_result == 0) {
|
if (verify_result == 0) {
|
||||||
cout << " (certificate validated)\n";
|
cout << " (certificate validated)\n";
|
||||||
|
@ -568,3 +568,14 @@ INLINE Multifile::CertRecord::
|
|||||||
~CertRecord() {
|
~CertRecord() {
|
||||||
X509_free(_cert);
|
X509_free(_cert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Multifile::CertRecord::Copy Assignment
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void Multifile::CertRecord::
|
||||||
|
operator = (const Multifile::CertRecord &other) {
|
||||||
|
X509_free(_cert);
|
||||||
|
_cert = X509_dup(other._cert);
|
||||||
|
}
|
||||||
|
@ -598,6 +598,13 @@ add_signature(const Filename &certificate, const Filename &chain,
|
|||||||
const Filename &pkey, const string &password) {
|
const Filename &pkey, const string &password) {
|
||||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||||
|
|
||||||
|
if (chain.empty() && pkey.empty()) {
|
||||||
|
// If the second two filenames are empty, assume we're going for
|
||||||
|
// the composite mode, where everything's stuffed into the first
|
||||||
|
// file.
|
||||||
|
return add_signature(certificate, password);
|
||||||
|
}
|
||||||
|
|
||||||
CertChain cert_chain;
|
CertChain cert_chain;
|
||||||
|
|
||||||
// Read the certificate file from VFS. First, read the complete
|
// Read the certificate file from VFS. First, read the complete
|
||||||
@ -673,6 +680,98 @@ add_signature(const Filename &certificate, const Filename &chain,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif // HAVE_OPENSSL
|
#endif // HAVE_OPENSSL
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENSSL
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Multifile::add_signature
|
||||||
|
// Access: Published
|
||||||
|
// Description: Adds a new signature to the Multifile. This
|
||||||
|
// signature associates the indicated certificate with
|
||||||
|
// the current contents of the Multifile. When the
|
||||||
|
// Multifile is read later, the signature will still be
|
||||||
|
// present only if the Multifile is unchanged; any
|
||||||
|
// subsequent changes to the Multifile will
|
||||||
|
// automatically invalidate and remove the signature.
|
||||||
|
//
|
||||||
|
// This flavor of add_signature() reads the certificate,
|
||||||
|
// private key, and certificate chain from the same
|
||||||
|
// PEM-formatted file. It takes the first private key
|
||||||
|
// found as the intended key, and then uses the first
|
||||||
|
// certificate found that matches that key as the
|
||||||
|
// signing certificate. Any other certificates in the
|
||||||
|
// file are taken to be part of the chain.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Multifile::
|
||||||
|
add_signature(const Filename &composite, const string &password) {
|
||||||
|
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||||
|
|
||||||
|
// First, read the complete file into memory.
|
||||||
|
string composite_data;
|
||||||
|
if (!vfs->read_file(composite, composite_data, true)) {
|
||||||
|
express_cat.info()
|
||||||
|
<< "Could not read " << composite << ".\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the private key.
|
||||||
|
BIO *pkey_mbio = BIO_new_mem_buf((void *)composite_data.data(), composite_data.size());
|
||||||
|
EVP_PKEY *evp_pkey = PEM_read_bio_PrivateKey(pkey_mbio, NULL, NULL,
|
||||||
|
(void *)password.c_str());
|
||||||
|
BIO_free(pkey_mbio);
|
||||||
|
if (evp_pkey == NULL) {
|
||||||
|
express_cat.info()
|
||||||
|
<< "Could not read private key in " << composite << ".\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now read all of the certificates.
|
||||||
|
CertChain cert_chain;
|
||||||
|
|
||||||
|
BIO *chain_mbio = BIO_new_mem_buf((void *)composite_data.data(), composite_data.size());
|
||||||
|
X509 *c = PEM_read_bio_X509(chain_mbio, NULL, NULL, (void *)"");
|
||||||
|
while (c != NULL) {
|
||||||
|
cert_chain.push_back(c);
|
||||||
|
c = PEM_read_bio_X509(chain_mbio, NULL, NULL, (void *)"");
|
||||||
|
}
|
||||||
|
BIO_free(chain_mbio);
|
||||||
|
|
||||||
|
if (cert_chain.empty()) {
|
||||||
|
express_cat.info()
|
||||||
|
<< "Could not read certificates in " << composite << ".\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now find the certificate that matches the signature, and move it
|
||||||
|
// to the front of the chain.
|
||||||
|
size_t i;
|
||||||
|
bool found_match = false;
|
||||||
|
for (i = 0; i < cert_chain.size(); ++i) {
|
||||||
|
X509 *c = cert_chain[i]._cert;
|
||||||
|
if (X509_check_private_key(c, evp_pkey)) {
|
||||||
|
found_match = true;
|
||||||
|
if (i != 0) {
|
||||||
|
// Move this entry to the beginning.
|
||||||
|
cert_chain.insert(cert_chain.begin(), cert_chain[i]);
|
||||||
|
cert_chain.erase(cert_chain.begin() + i + 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_match) {
|
||||||
|
express_cat.info()
|
||||||
|
<< "No certificates in " << composite << " match key.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result = add_signature(cert_chain, evp_pkey);
|
||||||
|
|
||||||
|
EVP_PKEY_free(evp_pkey);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif // HAVE_OPENSSL
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Multifile::add_signature
|
// Function: Multifile::add_signature
|
||||||
@ -756,6 +855,24 @@ add_signature(const Multifile::CertChain &cert_chain, EVP_PKEY *pkey) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cert_chain.empty()) {
|
||||||
|
express_cat.info()
|
||||||
|
<< "No certificate given.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkey == NULL) {
|
||||||
|
express_cat.info()
|
||||||
|
<< "No private key given.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!X509_check_private_key(cert_chain[0]._cert, pkey)) {
|
||||||
|
express_cat.info()
|
||||||
|
<< "Private key does not match certificate.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Now encode that list of certs to a stream in DER form.
|
// Now encode that list of certs to a stream in DER form.
|
||||||
stringstream der_stream;
|
stringstream der_stream;
|
||||||
@ -871,42 +988,54 @@ get_signature_subject_name(int n) const {
|
|||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Multifile::get_signature_common_name
|
// Function: Multifile::get_signature_friendly_name
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns the "common name" for the nth signature found
|
// Description: Returns a "friendly name" for the nth signature found
|
||||||
// on the Multifile, encoded in utf-8. This is a subset
|
// on the Multifile. This attempts to extract out the
|
||||||
// of the subject_name, but it is probably a friendlier
|
// most meaningful part of the subject name. It returns
|
||||||
// string to present to a user. See the comments in
|
// the emailAddress, if it is defined; otherwise, it
|
||||||
// get_num_signatures().
|
// returns the commonName.
|
||||||
|
|
||||||
|
// See the comments in get_num_signatures().
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
string Multifile::
|
string Multifile::
|
||||||
get_signature_common_name(int n) const {
|
get_signature_friendly_name(int n) const {
|
||||||
const CertChain &cert_chain = get_signature(n);
|
const CertChain &cert_chain = get_signature(n);
|
||||||
nassertr(!cert_chain.empty(), string());
|
nassertr(!cert_chain.empty(), string());
|
||||||
|
|
||||||
// A complex OpenSSL interface to extract out the common name in
|
static const int nid_choices[] = {
|
||||||
// utf-8.
|
NID_pkcs9_emailAddress,
|
||||||
X509_NAME *xname = X509_get_subject_name(cert_chain[0]._cert);
|
NID_commonName,
|
||||||
if (xname != NULL) {
|
-1,
|
||||||
int pos = X509_NAME_get_index_by_NID(xname, NID_commonName, -1);
|
};
|
||||||
if (pos != -1) {
|
|
||||||
// We just get the first common name. I guess it's possible to
|
|
||||||
// have more than one; not sure what that means in this context.
|
|
||||||
X509_NAME_ENTRY *xentry = X509_NAME_get_entry(xname, pos);
|
|
||||||
if (xentry != NULL) {
|
|
||||||
ASN1_STRING *data = X509_NAME_ENTRY_get_data(xentry);
|
|
||||||
if (data != NULL) {
|
|
||||||
// We use "print" to dump the output to a memory BIO. Is
|
|
||||||
// there an easier way to decode the ASN1_STRING? Curse
|
|
||||||
// these incomplete docs.
|
|
||||||
BIO *mbio = BIO_new(BIO_s_mem());
|
|
||||||
ASN1_STRING_print_ex(mbio, data, ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB);
|
|
||||||
|
|
||||||
char *pp;
|
// Choose the first NID that exists on the cert.
|
||||||
long pp_size = BIO_get_mem_data(mbio, &pp);
|
for (int ni = 0; nid_choices[ni] != -1; ++ni) {
|
||||||
string name(pp, pp_size);
|
int nid = nid_choices[ni];
|
||||||
BIO_free(mbio);
|
|
||||||
return name;
|
// A complex OpenSSL interface to extract out the name in utf-8.
|
||||||
|
X509_NAME *xname = X509_get_subject_name(cert_chain[0]._cert);
|
||||||
|
if (xname != NULL) {
|
||||||
|
int pos = X509_NAME_get_index_by_NID(xname, nid, -1);
|
||||||
|
if (pos != -1) {
|
||||||
|
// We just get the first common name. I guess it's possible to
|
||||||
|
// have more than one; not sure what that means in this context.
|
||||||
|
X509_NAME_ENTRY *xentry = X509_NAME_get_entry(xname, pos);
|
||||||
|
if (xentry != NULL) {
|
||||||
|
ASN1_STRING *data = X509_NAME_ENTRY_get_data(xentry);
|
||||||
|
if (data != NULL) {
|
||||||
|
// We use "print" to dump the output to a memory BIO. Is
|
||||||
|
// there an easier way to decode the ASN1_STRING? Curse
|
||||||
|
// these incomplete docs.
|
||||||
|
BIO *mbio = BIO_new(BIO_s_mem());
|
||||||
|
ASN1_STRING_print_ex(mbio, data, ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB);
|
||||||
|
|
||||||
|
char *pp;
|
||||||
|
long pp_size = BIO_get_mem_data(mbio, &pp);
|
||||||
|
string name(pp, pp_size);
|
||||||
|
BIO_free(mbio);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2081,6 +2210,8 @@ clear_subfiles() {
|
|||||||
delete subfile;
|
delete subfile;
|
||||||
}
|
}
|
||||||
_cert_special.clear();
|
_cert_special.clear();
|
||||||
|
|
||||||
|
_signatures.clear();
|
||||||
#endif // HAVE_OPENSSL
|
#endif // HAVE_OPENSSL
|
||||||
|
|
||||||
Subfiles::iterator fi;
|
Subfiles::iterator fi;
|
||||||
|
@ -89,6 +89,7 @@ PUBLISHED:
|
|||||||
INLINE CertRecord(X509 *cert);
|
INLINE CertRecord(X509 *cert);
|
||||||
INLINE CertRecord(const CertRecord ©);
|
INLINE CertRecord(const CertRecord ©);
|
||||||
INLINE ~CertRecord();
|
INLINE ~CertRecord();
|
||||||
|
INLINE void operator = (const CertRecord &other);
|
||||||
X509 *_cert;
|
X509 *_cert;
|
||||||
};
|
};
|
||||||
typedef pvector<CertRecord> CertChain;
|
typedef pvector<CertRecord> CertChain;
|
||||||
@ -97,13 +98,15 @@ PUBLISHED:
|
|||||||
const Filename &chain,
|
const Filename &chain,
|
||||||
const Filename &pkey,
|
const Filename &pkey,
|
||||||
const string &password = "");
|
const string &password = "");
|
||||||
|
bool add_signature(const Filename &composite,
|
||||||
|
const string &password = "");
|
||||||
bool add_signature(X509 *certificate, STACK *chain, EVP_PKEY *pkey);
|
bool add_signature(X509 *certificate, STACK *chain, EVP_PKEY *pkey);
|
||||||
bool add_signature(const CertChain &chain, EVP_PKEY *pkey);
|
bool add_signature(const CertChain &chain, EVP_PKEY *pkey);
|
||||||
|
|
||||||
int get_num_signatures() const;
|
int get_num_signatures() const;
|
||||||
const CertChain &get_signature(int n) const;
|
const CertChain &get_signature(int n) const;
|
||||||
string get_signature_subject_name(int n) const;
|
string get_signature_subject_name(int n) const;
|
||||||
string get_signature_common_name(int n) const;
|
string get_signature_friendly_name(int n) const;
|
||||||
string get_signature_public_key(int n) const;
|
string get_signature_public_key(int n) const;
|
||||||
void write_signature_certificate(int n, ostream &out) const;
|
void write_signature_certificate(int n, ostream &out) const;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user