x509_certificate_model_nss.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/net/x509_certificate_model.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cert.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cms.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <hasht.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <keyhi.h> // SECKEY_DestroyPrivateKey 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <keythi.h> // SECKEYPrivateKey 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pk11pub.h> // PK11_FindKeyByAnyCert 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <seccomon.h> // SECItem 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sechash.h> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_number_conversions.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/nss_util.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/scoped_nss_types.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/x509_certificate.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/third_party/mozilla_security_manager/nsNSSCertificate.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/third_party/mozilla_security_manager/nsUsageArrayHelper.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace psm = mozilla_security_manager; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert a char* return value from NSS into a std::string and free the NSS 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// memory. If the arg is NULL, an empty string will be returned instead. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Stringize(char* nss_text, const std::string& alternative_text) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!nss_text) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return alternative_text; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string s = nss_text; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Free(nss_text); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Hash a certificate using the given algorithm, return the result as a 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// colon-seperated hex string. The len specified is the number of bytes 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// required for storing the raw fingerprint. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (It's a bit redundant that the caller needs to specify len in addition to the 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// algorithm, but given the limited uses, not worth fixing.) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string HashCert(CERTCertificate* cert, HASH_HashType algorithm, int len) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char fingerprint[HASH_LENGTH_MAX]; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(NULL != cert->derCert.data); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(0U, cert->derCert.len); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(len, HASH_LENGTH_MAX); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(fingerprint, 0, len); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv = HASH_HashBuf(algorithm, fingerprint, cert->derCert.data, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert->derCert.len); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(rv, SECSuccess); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return x509_certificate_model::ProcessRawBytes(fingerprint, len); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ProcessSecAlgorithmInternal(SECAlgorithmID* algorithm_id) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return psm::GetOIDText(&algorithm_id->algorithm); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ProcessExtension( 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& critical_label, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& non_critical_label, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERTCertExtension* extension) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string criticality = 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension->critical.data && extension->critical.data[0] ? 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) critical_label : non_critical_label; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return criticality + "\n" + 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psm::ProcessExtensionData(SECOID_FindOIDTag(&extension->id), 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &extension->value); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NSS certificate export functions. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FreeNSSCMSMessage { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void operator()(NSSCMSMessage* x) const { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSS_CMSMessage_Destroy(x); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef scoped_ptr_malloc<NSSCMSMessage, FreeNSSCMSMessage> 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedNSSCMSMessage; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FreeNSSCMSSignedData { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void operator()(NSSCMSSignedData* x) const { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSS_CMSSignedData_Destroy(x); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef scoped_ptr_malloc<NSSCMSSignedData, FreeNSSCMSSignedData> 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedNSSCMSSignedData; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace x509_certificate_model { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::X509Certificate; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::string; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetCertNameOrNickname(X509Certificate::OSCertHandle cert_handle) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string name = ProcessIDN(Stringize(CERT_GetCommonName(&cert_handle->subject), 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "")); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!name.empty()) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return name; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetNickname(cert_handle); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetNickname(X509Certificate::OSCertHandle cert_handle) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string name; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cert_handle->nickname) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = cert_handle->nickname; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hack copied from mozilla: Cut off text before first :, which seems to 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // just be the token name. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t colon_pos = name.find(':'); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (colon_pos != string::npos) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = name.substr(colon_pos + 1); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return name; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetTokenName(X509Certificate::OSCertHandle cert_handle) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return psm::GetCertTokenName(cert_handle); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetVersion(X509Certificate::OSCertHandle cert_handle) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the version field is omitted from the certificate, the default 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // value is v1(0). 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long version = 0; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cert_handle->version.len == 0 || 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SEC_ASN1DecodeInteger(&cert_handle->version, &version) == SECSuccess) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::UintToString(version + 1); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ""; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::CertType GetType(X509Certificate::OSCertHandle cert_handle) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return psm::GetCertType(cert_handle); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetEmailAddress(X509Certificate::OSCertHandle cert_handle) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cert_handle->emailAddr) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cert_handle->emailAddr; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ""; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetUsageStrings(X509Certificate::OSCertHandle cert_handle, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<string>* usages) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psm::GetCertUsageStrings(cert_handle, usages); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetKeyUsageString(X509Certificate::OSCertHandle cert_handle) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem key_usage; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_usage.data = NULL; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string key_usage_str; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CERT_FindKeyUsageExtension(cert_handle, &key_usage) == SECSuccess) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_usage_str = psm::ProcessKeyUsageBitString(&key_usage, ','); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Free(key_usage.data); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return key_usage_str; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetSerialNumberHexified(X509Certificate::OSCertHandle cert_handle, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& alternative_text) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Stringize(CERT_Hexify(&cert_handle->serialNumber, true), 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alternative_text); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetIssuerCommonName(X509Certificate::OSCertHandle cert_handle, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& alternative_text) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Stringize(CERT_GetCommonName(&cert_handle->issuer), alternative_text); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetIssuerOrgName(X509Certificate::OSCertHandle cert_handle, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& alternative_text) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Stringize(CERT_GetOrgName(&cert_handle->issuer), alternative_text); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetIssuerOrgUnitName(X509Certificate::OSCertHandle cert_handle, 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& alternative_text) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Stringize(CERT_GetOrgUnitName(&cert_handle->issuer), alternative_text); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetSubjectOrgName(X509Certificate::OSCertHandle cert_handle, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& alternative_text) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Stringize(CERT_GetOrgName(&cert_handle->subject), alternative_text); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetSubjectOrgUnitName(X509Certificate::OSCertHandle cert_handle, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& alternative_text) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Stringize(CERT_GetOrgUnitName(&cert_handle->subject), 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alternative_text); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetSubjectCommonName(X509Certificate::OSCertHandle cert_handle, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& alternative_text) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Stringize(CERT_GetCommonName(&cert_handle->subject), alternative_text); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetTimes(X509Certificate::OSCertHandle cert_handle, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time* issued, base::Time* expires) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRTime pr_issued, pr_expires; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CERT_GetCertTimes(cert_handle, &pr_issued, &pr_expires) == SECSuccess) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *issued = crypto::PRTimeToBaseTime(pr_issued); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *expires = crypto::PRTimeToBaseTime(pr_expires); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetTitle(X509Certificate::OSCertHandle cert_handle) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return psm::GetCertTitle(cert_handle); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetIssuerName(X509Certificate::OSCertHandle cert_handle) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return psm::ProcessName(&cert_handle->issuer); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetSubjectName(X509Certificate::OSCertHandle cert_handle) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return psm::ProcessName(&cert_handle->subject); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetEmailAddresses(X509Certificate::OSCertHandle cert_handle, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<string>* email_addresses) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const char* addr = CERT_GetFirstEmailAddress(cert_handle); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr; addr = CERT_GetNextEmailAddress(cert_handle, addr)) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first email addr (from Subject) may be duplicated in Subject 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Alternative Name, so check subsequent addresses are not equal to the 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // first one before adding to the list. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!email_addresses->size() || (*email_addresses)[0] != addr) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) email_addresses->push_back(addr); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetNicknameStringsFromCertList( 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<scoped_refptr<X509Certificate> >& certs, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& cert_expired, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& cert_not_yet_valid, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<string>* nick_names) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERTCertList* cert_list = CERT_NewCertList(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < certs.size(); ++i) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERT_AddCertToListTail( 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_list, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERT_DupCertificate(certs[i]->os_cert_handle())); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Would like to use CERT_GetCertNicknameWithValidity on each cert 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // individually instead of having to build a CERTCertList for this, but that 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function is not exported. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERTCertNicknames* cert_nicknames = CERT_NicknameStringsFromCertList( 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_list, 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_cast<char*>(cert_expired.c_str()), 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_cast<char*>(cert_not_yet_valid.c_str())); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(cert_nicknames->numnicknames, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(certs.size())); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < cert_nicknames->numnicknames; ++i) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nick_names->push_back(cert_nicknames->nicknames[i]); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERT_FreeNicknames(cert_nicknames); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERT_DestroyCertList(cert_list); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For background see this discussion on dev-tech-crypto.lists.mozilla.org: 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://web.archiveorange.com/archive/v/6JJW7E40sypfZGtbkzxX 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTE: This function relies on the convention that the same PKCS#11 ID 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is shared between a certificate and its associated private and public 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// keys. I tried to implement this with PK11_GetLowLevelKeyIDForCert(), 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but that always returns NULL on Chrome OS for me. 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetPkcs11Id(net::X509Certificate::OSCertHandle cert_handle) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string pkcs11_id; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECKEYPrivateKey *priv_key = PK11_FindKeyByAnyCert(cert_handle, 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL /* wincx */); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (priv_key) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the CKA_ID attribute for a key. 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem* sec_item = PK11_GetLowLevelKeyIDForPrivateKey(priv_key); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sec_item) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pkcs11_id = base::HexEncode(sec_item->data, sec_item->len); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECITEM_FreeItem(sec_item, PR_TRUE); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECKEY_DestroyPrivateKey(priv_key); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pkcs11_id; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetExtensions( 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& critical_label, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& non_critical_label, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) X509Certificate::OSCertHandle cert_handle, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extensions* extensions) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cert_handle->extensions) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; cert_handle->extensions[i] != NULL; ++i) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension extension; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension.name = psm::GetOIDText(&cert_handle->extensions[i]->id); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension.value = ProcessExtension( 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) critical_label, non_critical_label, cert_handle->extensions[i]); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions->push_back(extension); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string HashCertSHA256(X509Certificate::OSCertHandle cert_handle) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HashCert(cert_handle, HASH_AlgSHA256, SHA256_LENGTH); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string HashCertSHA1(X509Certificate::OSCertHandle cert_handle) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HashCert(cert_handle, HASH_AlgSHA1, SHA1_LENGTH); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetCertChainFromCert(X509Certificate::OSCertHandle cert_handle, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) X509Certificate::OSCertHandles* cert_handles) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERTCertList* cert_list = 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERT_GetCertChainFromCert(cert_handle, PR_Now(), certUsageSSLServer); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERTCertListNode* node; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (node = CERT_LIST_HEAD(cert_list); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !CERT_LIST_END(node, cert_list); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = CERT_LIST_NEXT(node)) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_handles->push_back(CERT_DupCertificate(node->cert)); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERT_DestroyCertList(cert_list); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DestroyCertChain(X509Certificate::OSCertHandles* cert_handles) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (X509Certificate::OSCertHandles::iterator i(cert_handles->begin()); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != cert_handles->end(); ++i) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERT_DestroyCertificate(*i); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_handles->clear(); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetDerString(X509Certificate::OSCertHandle cert_handle) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return string(reinterpret_cast<const char*>(cert_handle->derCert.data), 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_handle->derCert.len); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string GetCMSString(const X509Certificate::OSCertHandles& cert_chain, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t start, size_t end) { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crypto::ScopedPLArenaPool arena(PORT_NewArena(1024)); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(arena.get()); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedNSSCMSMessage message(NSS_CMSMessage_Create(arena.get())); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(message.get()); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First, create SignedData with the certificate only (no chain). 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedNSSCMSSignedData signed_data(NSS_CMSSignedData_CreateCertsOnly( 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.get(), cert_chain[start], PR_FALSE)); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!signed_data.get()) { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "NSS_CMSSignedData_Create failed"; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ""; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the rest of the chain (if any). 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = start + 1; i < end; ++i) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NSS_CMSSignedData_AddCertificate(signed_data.get(), cert_chain[i]) != 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECSuccess) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "NSS_CMSSignedData_AddCertificate failed on " << i; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ""; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSSCMSContentInfo *cinfo = NSS_CMSMessage_GetContentInfo(message.get()); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NSS_CMSContentInfo_SetContent_SignedData( 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.get(), cinfo, signed_data.get()) == SECSuccess) { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_result(signed_data.release()); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "NSS_CMSMessage_GetContentInfo failed"; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ""; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem cert_p7 = { siBuffer, NULL, 0 }; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSSCMSEncoderContext *ecx = NSS_CMSEncoder_Start(message.get(), NULL, NULL, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &cert_p7, arena.get(), NULL, 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL, NULL, NULL, 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ecx) { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "NSS_CMSEncoder_Start failed"; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ""; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NSS_CMSEncoder_Finish(ecx) != SECSuccess) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "NSS_CMSEncoder_Finish failed"; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ""; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return string(reinterpret_cast<const char*>(cert_p7.data), cert_p7.len); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string ProcessSecAlgorithmSignature(X509Certificate::OSCertHandle cert_handle) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProcessSecAlgorithmInternal(&cert_handle->signature); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string ProcessSecAlgorithmSubjectPublicKey( 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) X509Certificate::OSCertHandle cert_handle) { 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProcessSecAlgorithmInternal( 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &cert_handle->subjectPublicKeyInfo.algorithm); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string ProcessSecAlgorithmSignatureWrap( 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) X509Certificate::OSCertHandle cert_handle) { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProcessSecAlgorithmInternal( 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &cert_handle->signatureWrap.signatureAlgorithm); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string ProcessSubjectPublicKeyInfo(X509Certificate::OSCertHandle cert_handle) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return psm::ProcessSubjectPublicKeyInfo(&cert_handle->subjectPublicKeyInfo); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string ProcessRawBitsSignatureWrap(X509Certificate::OSCertHandle cert_handle) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProcessRawBits(cert_handle->signatureWrap.signature.data, 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_handle->signatureWrap.signature.len); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RegisterDynamicOids() { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psm::RegisterDynamicOids(); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace x509_certificate_model 417