From b9baa34b08dfb6c2136f6c9269b0138f6f1ae771 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Fri, 17 Jul 2015 17:49:46 -0700 Subject: [PATCH] Backed out 3 changesets (bug 1178988) for ocsp orange CLOSED TREE Backed out changeset 7fb6a9114916 (bug 1178988) Backed out changeset 2700ec4adc3e (bug 1178988) Backed out changeset 07b9c2331ac1 (bug 1178988) --- security/manager/ssl/tests/unit/moz.build | 1 - security/manager/ssl/tests/unit/pycert.py | 174 ++++++++--- security/manager/ssl/tests/unit/pykey.py | 282 ------------------ .../manager/ssl/tests/unit/test_ocsp_url.js | 8 +- .../tests/unit/test_ocsp_url/bad-scheme.der | Bin 0 -> 895 bytes .../test_ocsp_url/bad-scheme.pem.certspec | 3 - .../ssl/tests/unit/test_ocsp_url/ca.der | Bin 0 -> 845 bytes .../tests/unit/test_ocsp_url/ca.pem.certspec | 4 - .../ssl/tests/unit/test_ocsp_url/cert9.db | Bin 0 -> 43008 bytes .../tests/unit/test_ocsp_url/empty-port.der | Bin 0 -> 904 bytes .../test_ocsp_url/empty-port.pem.certspec | 3 - .../unit/test_ocsp_url/empty-scheme-url.der | Bin 0 -> 910 bytes .../empty-scheme-url.pem.certspec | 3 - .../ssl/tests/unit/test_ocsp_url/ftp-url.der | Bin 0 -> 903 bytes .../unit/test_ocsp_url/ftp-url.pem.certspec | 3 - .../ssl/tests/unit/test_ocsp_url/generate.py | 40 +++ .../ssl/tests/unit/test_ocsp_url/hTTp-url.der | Bin 0 -> 914 bytes .../unit/test_ocsp_url/hTTp-url.pem.certspec | 3 - .../tests/unit/test_ocsp_url/https-url.der | Bin 0 -> 917 bytes .../unit/test_ocsp_url/https-url.pem.certspec | 3 - .../ssl/tests/unit/test_ocsp_url/int.der | Bin 0 -> 845 bytes .../tests/unit/test_ocsp_url/int.key.keyspec | 0 .../tests/unit/test_ocsp_url/int.pem.certspec | 4 - .../ssl/tests/unit/test_ocsp_url/key4.db | Bin 0 -> 72704 bytes .../ssl/tests/unit/test_ocsp_url/moz.build | 42 --- .../unit/test_ocsp_url/negative-port.der | Bin 0 -> 908 bytes .../test_ocsp_url/negative-port.pem.certspec | 3 - .../tests/unit/test_ocsp_url/no-host-url.der | Bin 0 -> 894 bytes .../test_ocsp_url/no-host-url.pem.certspec | 3 - .../tests/unit/test_ocsp_url/no-path-url.der | Bin 0 -> 908 bytes .../test_ocsp_url/no-path-url.pem.certspec | 3 - .../test_ocsp_url/no-scheme-host-port.der | Bin 0 -> 889 bytes .../no-scheme-host-port.pem.certspec | 3 - .../unit/test_ocsp_url/no-scheme-url.der | Bin 0 -> 904 bytes .../test_ocsp_url/no-scheme-url.pem.certspec | 3 - .../ssl/tests/unit/test_ocsp_url/pkcs11.txt | 5 + .../unit/test_ocsp_url/unknown-scheme.der | Bin 0 -> 905 bytes .../test_ocsp_url/unknown-scheme.pem.certspec | 3 - .../tlsserver/cmd/GenerateOCSPResponse.cpp | 229 +------------- 39 files changed, 198 insertions(+), 627 deletions(-) delete mode 100755 security/manager/ssl/tests/unit/pykey.py create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ca.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/cert9.db create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-port.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-port.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem.certspec create mode 100755 security/manager/ssl/tests/unit/test_ocsp_url/generate.py create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/https-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.key.keyspec delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/key4.db delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/moz.build create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/negative-port.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/pkcs11.txt create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.der delete mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec diff --git a/security/manager/ssl/tests/unit/moz.build b/security/manager/ssl/tests/unit/moz.build index 2433f5b843f2..85bea2f51150 100644 --- a/security/manager/ssl/tests/unit/moz.build +++ b/security/manager/ssl/tests/unit/moz.build @@ -12,7 +12,6 @@ TEST_DIRS += [ 'test_cert_version', 'test_intermediate_basic_usage_constraints', 'test_pinning_dynamic', - 'test_ocsp_url', ] if not CONFIG['MOZ_NO_SMART_CARDS']: diff --git a/security/manager/ssl/tests/unit/pycert.py b/security/manager/ssl/tests/unit/pycert.py index 0da1e71b5516..bf8b7c8734d1 100755 --- a/security/manager/ssl/tests/unit/pycert.py +++ b/security/manager/ssl/tests/unit/pycert.py @@ -26,7 +26,6 @@ extKeyUsage:[serverAuth,clientAuth,codeSigning,emailProtection nsSGC, # Netscape Server Gated Crypto OCSPSigning,timeStamping] subjectAlternativeName:[,...] -authorityInformationAccess: Where: [] indicates an optional field or component of a field @@ -49,14 +48,14 @@ or as the subject public key information field, respectively. from pyasn1.codec.der import decoder from pyasn1.codec.der import encoder -from pyasn1.type import constraint, tag, univ, useful +from pyasn1.type import constraint, namedtype, tag, univ, useful from pyasn1_modules import rfc2459 import base64 +import binascii import datetime import hashlib import sys - -import pykey +import rsa class UnknownBaseError(Exception): """Base class for handling unexpected input in this module.""" @@ -100,6 +99,14 @@ class UnknownKeyPurposeTypeError(UnknownBaseError): self.category = 'keyPurpose' +class UnknownKeySpecificationError(UnknownBaseError): + """Helper exception type to handle unknown key specifications.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = 'key specification' + + class UnknownKeyTargetError(UnknownBaseError): """Helper exception type to handle unknown key targets.""" @@ -121,18 +128,6 @@ def getASN1Tag(asn1Type): type from the pyasn1 package""" return asn1Type.baseTagSet.getBaseTag().asTuple()[2] -def stringToAccessDescription(string): - """Helper function that takes a string representing a URI - presumably identifying an OCSP authority information access - location. Returns an AccessDescription usable by pyasn1.""" - accessMethod = rfc2459.id_ad_ocsp - accessLocation = rfc2459.GeneralName() - accessLocation.setComponentByName('uniformResourceIdentifier', string) - sequence = univ.Sequence() - sequence.setComponentByPosition(0, accessMethod) - sequence.setComponentByPosition(1, accessLocation) - return sequence - def stringToAlgorithmIdentifier(string): """Helper function that converts a description of an algorithm to a representation usable by the pyasn1 package""" @@ -171,10 +166,97 @@ def datetimeToTime(dt): time.setComponentByName('generalTime', useful.GeneralizedTime(dt.strftime('%Y%m%d%H%M%SZ'))) return time +def byteStringToHexifiedBitString(string): + """Takes a string of bytes and returns a hex string representing + those bytes for use with pyasn1.type.univ.BitString. It must be of + the form "''H", where the trailing 'H' indicates to + pyasn1 that the input is a hex string.""" + return "'%s'H" % binascii.hexlify(string) + +class RSAPublicKey(univ.Sequence): + """Helper type for encoding an RSA public key""" + componentType = namedtype.NamedTypes( + namedtype.NamedType('N', univ.Integer()), + namedtype.NamedType('E', univ.Integer())) + + class Certificate: """Utility class for reading a certificate specification and generating a signed x509 certificate""" + # For reference, when encoded as a subject public key info, the + # base64-encoded sha-256 hash of this key is + # VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8= + sharedRSA_N = long( + '00ba8851a8448e16d641fd6eb6880636103d3c13d9eae4354ab4ecf56857' + '6c247bc1c725a8e0d81fbdb19c069b6e1a86f26be2af5a756b6a6471087a' + 'a55aa74587f71cd5249c027ecd43fc1e69d038202993ab20c349e4dbb94c' + 'c26b6c0eed15820ff17ead691ab1d3023a8b2a41eea770e00f0d8dfd660b' + '2bb02492a47db988617990b157903dd23bc5e0b8481fa837d38843ef2716' + 'd855b7665aaa7e02902f3a7b10800624cc1c6c97ad96615bb7e29612c075' + '31a30c91ddb4caf7fcad1d25d309efb9170ea768e1b37b2f226f69e3b48a' + '95611dee26d6259dab91084e36cb1c24042cbf168b2fe5f18f991731b8b3' + 'fe4923fa7251c431d503acda180a35ed8d', 16) + sharedRSA_E = 65537L + sharedRSA_D = long( + '009ecbce3861a454ecb1e0fe8f85dd43c92f5825ce2e997884d0e1a949da' + 'a2c5ac559b240450e5ac9fe0c3e31c0eefa6525a65f0c22194004ee1ab46' + '3dde9ee82287cc93e746a91929c5e6ac3d88753f6c25ba5979e73e5d8fb2' + '39111a3cdab8a4b0cdf5f9cab05f1233a38335c64b5560525e7e3b92ad7c' + '7504cf1dc7cb005788afcbe1e8f95df7402a151530d5808346864eb370aa' + '79956a587862cb533791307f70d91c96d22d001a69009b923c683388c9f3' + '6cb9b5ebe64302041c78d908206b87009cb8cabacad3dbdb2792fb911b2c' + 'f4db6603585be9ae0ca3b8e6417aa04b06e470ea1a3b581ca03a6781c931' + '5b62b30e6011f224725946eec57c6d9441', 16) + sharedRSA_P = long( + '00dd6e1d4fffebf68d889c4d114cdaaa9caa63a59374286c8a5c29a717bb' + 'a60375644d5caa674c4b8bc7326358646220e4550d7608ac27d55b6db74f' + '8d8127ef8fa09098b69147de065573447e183d22fe7d885aceb513d9581d' + 'd5e07c1a90f5ce0879de131371ecefc9ce72e9c43dc127d238190de81177' + '3ca5d19301f48c742b', 16) + sharedRSA_Q = long( + '00d7a773d9ebc380a767d2fec0934ad4e8b5667240771acdebb5ad796f47' + '8fec4d45985efbc9532968289c8d89102fadf21f34e2dd4940eba8c09d6d' + '1f16dcc29729774c43275e9251ddbe4909e1fd3bf1e4bedf46a39b8b3833' + '28ef4ae3b95b92f2070af26c9e7c5c9b587fedde05e8e7d86ca57886fb16' + '5810a77b9845bc3127', 16) + # For reference, when encoded as a subject public key info, the + # base64-encoded sha-256 hash of this key is + # K+uamI+1JmrxMsBxEfGOoydEDJVMa5MY/eaTj+43Lzc= + alternateRSA_N = long( + '00cd6e66a71b9a104c7c5f270b5869da966a52e547f8a026eef128c4d51f' + 'a7d949b1df8a1e342c59cbad0fb6ef867427bd9e76f2e9bf0b582745c646' + '4446db7bdd4d0f2f361da724ff206d070b3d75ad87d690fa307dcccc2ad1' + '4283921f9621f2a564e7e9f708a98556194df12fb4b0a2f0b89f76ac7e59' + '668285aa50f14f310b6ebd8f001d0c115393bd27f3334f67780abfe0b19e' + '5ac3414c5b4a3819fbed39198050e1c660e44cacaf108cbe1671d5a14602' + '6090f371b2873d419eeb6de982fb493c3d4d33fb8a12bd65f1c59a3494dd' + 'd7e1131aa45e896d817bbb28e6fd4c2323ed17a26dc8e4e49281decc641e' + 'f7b7acfe65e7c0e5212fb2a9d472902c35', 16) + alternateRSA_E = 65537L + alternateRSA_D = long( + '6ae6e0946550aeda9e7e059b69ceebe90a3b490542e4545e53309bfd2c13' + 'f486dd012ea6b90fbb4aba2c4b4e29f1981c9cb1d986b9dbf56bba6b8b75' + '4c4a3b12d65ee87a88c3ca04d9a2e2df7e84166171cecfe31c13cecb194a' + '3b9d76c271b80b498f45b93fd0b78a2e70d8e9b26598e51bae1fdb7384a2' + '4b99b31f9bf351d9692c00d6f05c30424be4b4de55331ac77532c3fdaf74' + '95dbf7aef601b517ed227d0efa3de443d56d8b29e556f6be938eabf4c0e4' + '2e2fe38bec60cba5b5ff9192b68620ee4b629b9d0b64b9a8810809813b0b' + '04e485d97fdad2961c0982a589863643974e3900dd8a75112a0fffc59f4b' + '24c31307901dd04a848b02db32f61a01', 16) + alternateRSA_P = long( + '00feeacc987c0494cb5e9550eefb9dc56f9d957022a11539dae04c6361ab' + 'd5081dce2a6aec0905450886f5bb7e56e8bd2bef37cfa16fbda5ffc268ca' + 'e0499017552c37fa4a041341d67d4d69d093d8950f50672fb085b636560e' + '2446689474b29be7abeba358ab7bc4cde3fd065d46f762adeb5c4b54ccca' + '651a14b498311615b1', 16) + alternateRSA_Q = long( + '00ce4dca3fdda86b8c800c268082446633c8aaf0f20c729878092198585b' + 'd2ed134a7bdb2c93f829f99e6e9070db6598b3113627fd87bf6bc46cb2e5' + '121777cbea9c41e74c9c2c248931dbccb5ae8a1dccfad284784cc35b8329' + 'abc420ce95640085dbf325fa7f6a2a567d487c1ef67d07a56c6beade9404' + 'd039ba01adf328ebc5', 16) + def __init__(self, paramStream, now=datetime.datetime.utcnow()): self.versionValue = 2 # a value of 2 is X509v3 self.signature = 'sha256WithRSAEncryption' @@ -185,8 +267,13 @@ class Certificate: self.subject = 'Default Subject' self.signatureAlgorithm = 'sha256WithRSAEncryption' self.extensions = None - self.subjectKey = pykey.RSAKey() - self.issuerKey = pykey.RSAKey() + self.subjectRSA_N = self.sharedRSA_N + self.subjectRSA_E = self.sharedRSA_E + self.issuerRSA_N = self.sharedRSA_N + self.issuerRSA_E = self.sharedRSA_E + self.issuerRSA_D = self.sharedRSA_D + self.issuerRSA_P = self.sharedRSA_P + self.issuerRSA_Q = self.sharedRSA_Q self.decodeParams(paramStream) self.serialNumber = self.generateSerialNumber() @@ -260,18 +347,24 @@ class Certificate: self.addExtKeyUsage(value) elif extensionType == 'subjectAlternativeName': self.addSubjectAlternativeName(value) - elif extensionType == 'authorityInformationAccess': - self.addAuthorityInformationAccess(value) else: raise UnknownExtensionTypeError(extensionType) def setupKey(self, subjectOrIssuer, value): - if subjectOrIssuer == 'subject': - self.subjectKey = pykey.RSAKey(value) - elif subjectOrIssuer == 'issuer': - self.issuerKey = pykey.RSAKey(value) + if value == 'alternate': + if subjectOrIssuer == 'subject': + self.subjectRSA_N = self.alternateRSA_N + self.subjectRSA_E = self.alternateRSA_E + elif subjectOrIssuer == 'issuer': + self.issuerRSA_N = self.alternateRSA_N + self.issuerRSA_E = self.alternateRSA_E + self.issuerRSA_D = self.alternateRSA_D + self.issuerRSA_P = self.alternateRSA_P + self.issuerRSA_Q = self.alternateRSA_Q + else: + raise UnknownKeyTargetError(subjectOrIssuer) else: - raise UnknownKeyTargetError(subjectOrIssuer) + raise UnknownKeySpecificationError(value) def addExtension(self, extensionType, extensionValue): if not self.extensions: @@ -336,12 +429,6 @@ class Certificate: count += 1 self.addExtension(rfc2459.id_ce_subjectAltName, subjectAlternativeName) - def addAuthorityInformationAccess(self, ocspURI): - sequence = univ.Sequence() - accessDescription = stringToAccessDescription(ocspURI) - sequence.setComponentByPosition(0, accessDescription) - self.addExtension(rfc2459.id_pe_authorityInfoAccess, sequence) - def getVersion(self): return rfc2459.Version(self.versionValue).subtype( explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)) @@ -373,6 +460,21 @@ class Certificate: def getSignatureAlgorithm(self): return stringToAlgorithmIdentifier(self.signature) + def getSubjectPublicKey(self): + rsaKey = RSAPublicKey() + rsaKey.setComponentByName('N', univ.Integer(self.subjectRSA_N)) + rsaKey.setComponentByName('E', univ.Integer(self.subjectRSA_E)) + return univ.BitString(byteStringToHexifiedBitString(encoder.encode(rsaKey))) + + def getSubjectPublicKeyInfo(self): + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier.setComponentByName('algorithm', rfc2459.rsaEncryption) + algorithmIdentifier.setComponentByName('parameters', univ.Null()) + spki = rfc2459.SubjectPublicKeyInfo() + spki.setComponentByName('algorithm', algorithmIdentifier) + spki.setComponentByName('subjectPublicKey', self.getSubjectPublicKey()) + return spki + def toDER(self): tbsCertificate = rfc2459.TBSCertificate() tbsCertificate.setComponentByName('version', self.getVersion()) @@ -381,8 +483,7 @@ class Certificate: tbsCertificate.setComponentByName('issuer', self.getIssuer()) tbsCertificate.setComponentByName('validity', self.getValidity()) tbsCertificate.setComponentByName('subject', self.getSubject()) - tbsCertificate.setComponentByName('subjectPublicKeyInfo', - self.subjectKey.asSubjectPublicKeyInfo()) + tbsCertificate.setComponentByName('subjectPublicKeyInfo', self.getSubjectPublicKeyInfo()) if self.extensions: extensions = rfc2459.Extensions().subtype( explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)) @@ -391,11 +492,14 @@ class Certificate: extensions.setComponentByPosition(count, extension) count += 1 tbsCertificate.setComponentByName('extensions', extensions) + tbsDER = encoder.encode(tbsCertificate) + rsaPrivateKey = rsa.PrivateKey(self.issuerRSA_N, self.issuerRSA_E, self.issuerRSA_D, + self.issuerRSA_P, self.issuerRSA_Q) + signature = rsa.sign(tbsDER, rsaPrivateKey, 'SHA-256') certificate = rfc2459.Certificate() certificate.setComponentByName('tbsCertificate', tbsCertificate) certificate.setComponentByName('signatureAlgorithm', self.getSignatureAlgorithm()) - tbsDER = encoder.encode(tbsCertificate) - certificate.setComponentByName('signatureValue', self.issuerKey.sign(tbsDER)) + certificate.setComponentByName('signatureValue', byteStringToHexifiedBitString(signature)) return encoder.encode(certificate) def toPEM(self): diff --git a/security/manager/ssl/tests/unit/pykey.py b/security/manager/ssl/tests/unit/pykey.py deleted file mode 100755 index 3d701791a358..000000000000 --- a/security/manager/ssl/tests/unit/pykey.py +++ /dev/null @@ -1,282 +0,0 @@ -#!/usr/bin/env python -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -""" -Reads a key specification from stdin or a file and outputs a -PKCS #8 file representing the (private) key. Also provides -methods for signing data and representing the key as a subject -public key info for use with pyasn1. - -The key specification format is currently very simple. If it is -empty, one RSA key is used. If it consists of the string -'alternate', a different RSA key is used. In the future it will -be possible to specify other properties of the key (type, -strength, signature algorithm, etc.). -""" - -from pyasn1.codec.der import encoder -from pyasn1.type import univ, namedtype -from pyasn1_modules import rfc2459 -import base64 -import binascii -import rsa -import sys - -def byteStringToHexifiedBitString(string): - """Takes a string of bytes and returns a hex string representing - those bytes for use with pyasn1.type.univ.BitString. It must be of - the form "''H", where the trailing 'H' indicates to - pyasn1 that the input is a hex string.""" - return "'%s'H" % binascii.hexlify(string) - -class UnknownBaseError(Exception): - """Base class for handling unexpected input in this module.""" - def __init__(self, value): - self.value = value - self.category = 'input' - - def __str__(self): - return 'Unknown %s type "%s"' % (self.category, repr(self.value)) - - -class UnknownKeySpecificationError(UnknownBaseError): - """Helper exception type to handle unknown key specifications.""" - - def __init__(self, value): - UnknownBaseError.__init__(self, value) - self.category = 'key specification' - - -class RSAPublicKey(univ.Sequence): - """Helper type for encoding an RSA public key""" - componentType = namedtype.NamedTypes( - namedtype.NamedType('N', univ.Integer()), - namedtype.NamedType('E', univ.Integer())) - - -class RSAPrivateKey(univ.Sequence): - """Helper type for encoding an RSA private key""" - componentType = namedtype.NamedTypes( - namedtype.NamedType('version', univ.Integer()), - namedtype.NamedType('modulus', univ.Integer()), - namedtype.NamedType('publicExponent', univ.Integer()), - namedtype.NamedType('privateExponent', univ.Integer()), - namedtype.NamedType('prime1', univ.Integer()), - namedtype.NamedType('prime2', univ.Integer()), - namedtype.NamedType('exponent1', univ.Integer()), - namedtype.NamedType('exponent2', univ.Integer()), - namedtype.NamedType('coefficient', univ.Integer()), - ) - - -class PrivateKeyInfo(univ.Sequence): - """Helper type for encoding a PKCS #8 private key info""" - componentType = namedtype.NamedTypes( - namedtype.NamedType('version', univ.Integer()), - namedtype.NamedType('privateKeyAlgorithm', rfc2459.AlgorithmIdentifier()), - namedtype.NamedType('privateKey', univ.OctetString()) - ) - - -class RSAKey: - # For reference, when encoded as a subject public key info, the - # base64-encoded sha-256 hash of this key is - # VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8= - sharedRSA_N = long( - '00ba8851a8448e16d641fd6eb6880636103d3c13d9eae4354ab4ecf56857' - '6c247bc1c725a8e0d81fbdb19c069b6e1a86f26be2af5a756b6a6471087a' - 'a55aa74587f71cd5249c027ecd43fc1e69d038202993ab20c349e4dbb94c' - 'c26b6c0eed15820ff17ead691ab1d3023a8b2a41eea770e00f0d8dfd660b' - '2bb02492a47db988617990b157903dd23bc5e0b8481fa837d38843ef2716' - 'd855b7665aaa7e02902f3a7b10800624cc1c6c97ad96615bb7e29612c075' - '31a30c91ddb4caf7fcad1d25d309efb9170ea768e1b37b2f226f69e3b48a' - '95611dee26d6259dab91084e36cb1c24042cbf168b2fe5f18f991731b8b3' - 'fe4923fa7251c431d503acda180a35ed8d', 16) - sharedRSA_E = 65537L - sharedRSA_D = long( - '009ecbce3861a454ecb1e0fe8f85dd43c92f5825ce2e997884d0e1a949da' - 'a2c5ac559b240450e5ac9fe0c3e31c0eefa6525a65f0c22194004ee1ab46' - '3dde9ee82287cc93e746a91929c5e6ac3d88753f6c25ba5979e73e5d8fb2' - '39111a3cdab8a4b0cdf5f9cab05f1233a38335c64b5560525e7e3b92ad7c' - '7504cf1dc7cb005788afcbe1e8f95df7402a151530d5808346864eb370aa' - '79956a587862cb533791307f70d91c96d22d001a69009b923c683388c9f3' - '6cb9b5ebe64302041c78d908206b87009cb8cabacad3dbdb2792fb911b2c' - 'f4db6603585be9ae0ca3b8e6417aa04b06e470ea1a3b581ca03a6781c931' - '5b62b30e6011f224725946eec57c6d9441', 16) - sharedRSA_P = long( - '00dd6e1d4fffebf68d889c4d114cdaaa9caa63a59374286c8a5c29a717bb' - 'a60375644d5caa674c4b8bc7326358646220e4550d7608ac27d55b6db74f' - '8d8127ef8fa09098b69147de065573447e183d22fe7d885aceb513d9581d' - 'd5e07c1a90f5ce0879de131371ecefc9ce72e9c43dc127d238190de81177' - '3ca5d19301f48c742b', 16) - sharedRSA_Q = long( - '00d7a773d9ebc380a767d2fec0934ad4e8b5667240771acdebb5ad796f47' - '8fec4d45985efbc9532968289c8d89102fadf21f34e2dd4940eba8c09d6d' - '1f16dcc29729774c43275e9251ddbe4909e1fd3bf1e4bedf46a39b8b3833' - '28ef4ae3b95b92f2070af26c9e7c5c9b587fedde05e8e7d86ca57886fb16' - '5810a77b9845bc3127', 16) - sharedRSA_exp1 = long( - '0096472b41a610c0ade1af2266c1600e3671355ba42d4b5a0eb4e9d7eb35' - '81400ba5dd132cdb1a5e9328c7bbc0bbb0155ea192972edf97d12751d8fc' - 'f6ae572a30b1ea309a8712dd4e33241db1ee455fc093f5bc9b592d756e66' - '21474f32c07af22fb275d340792b32ba2590bbb261aefb95a258eea53765' - '5315be9c24d191992d', 16) - sharedRSA_exp2 = long( - '28b450a7a75a856413b2bda6f7a63e3d964fb9ecf50e3823ef6cc8e8fa26' - 'ee413f8b9d1205540f12bbe7a0c76828b7ba65ad83cca4d0fe2a220114e1' - 'b35d03d5a85bfe2706bd50fce6cfcdd571b46ca621b8ed47d605bbe765b0' - 'aa4a0665ac25364da20154032e1204b8559d3e34fb5b177c9a56ff93510a' - '5a4a6287c151de2d', 16) - sharedRSA_coef = long( - '28067b9355801d2ef52dfa96d8adb589673cf8ee8a9c6ff72aeeabe9ef6b' - 'e58a4f4abf05f788947dc851fdaa34542147a71a246bfb054ee76aa346ab' - 'cd2692cfc9e44c51e6f069c735e073ba019f6a7214961c91b26871caeabf' - '8f064418a02690e39a8d5ff3067b7cdb7f50b1f53418a703966c4fc774bf' - '7402af6c43247f43', 16) - - # For reference, when encoded as a subject public key info, the - # base64-encoded sha-256 hash of this key is - # MQj2tt1yGAfwFpWETYUCVrZxk2CD2705NKBQUlAaKJI= - alternateRSA_N = long( - '00c175c65266099f77082a6791f1b876c37f5ce538b06c4acd22b1cbd46f' - 'a65ada2add41c8c2498ac4a3b3c1f61487f41b698941bd80a51c3c120244' - 'c584a4c4483305e5138c0106cf08be9a862760bae6a2e8f36f23c5d98313' - 'b9dfaf378345dace51d4d6dcd2a6cb3cc706ebcd3070ec98cce40aa591d7' - '295a7f71c5be66691d2b2dfec84944590bc5a3ea49fd93b1d753405f1773' - '7699958666254797ed426908880811422069988a43fee48ce68781dd22b6' - 'a69cd28375131f932b128ce286fa7d251c062ad27ef016f187cdd54e832b' - '35b8930f74ba90aa8bc76167242ab1fd6d62140d18c4c0b8c68fc3748457' - '324ad7de86e6552f1d1e191d712168d3bb', 16) - alternateRSA_E = 65537L - alternateRSA_D = long( - '7e3f6d7cb839ef66ae5d7dd92ff5410bb341dc14728d39034570e1a37079' - '0f30f0681355fff41e2ad4e9a9d9fcebfbd127bdfab8c00affb1f3cea732' - '7ead47aa1621f2ac1ee14ca02f04b3b2786017980b181a449d03b03e69d1' - '12b83571e55434f012056575d2832ed6731dce799e37c83f6d51c55ab71e' - 'b58015af05e1af15c747603ef7f27d03a6ff049d96bbf854c1e4e50ef5b0' - '58d0fb08180e0ac7f7be8f2ff1673d97fc9e55dba838077bbf8a7cff2962' - '857785269cd9d5bad2b57469e4afcd33c4ca2d2f699f11e7c8fbdcd484f0' - '8d8efb8a3cb8a972eb24bed972efaae4bb712093e48fe94a46eb629a8750' - '78c4021a9a2c93c9a70390e9d0a54401', 16) - alternateRSA_P = long( - '00e63fc725a6ba76925a7ff8cb59c4f56dd7ec83fe85bf1f53e11cac9a81' - '258bcfc0ae819077b0f2d1477aaf868de6a8ecbeaf7bb22b196f2a9ad82d' - '3286f0d0cc29de719e5f2be8e509b7284d5963edd362f927887a4c4a8979' - '9d340d51b301ac7601ab27179024fcaadd38bf6522af63eb16461ec02a7f' - '27b06fe09ddda7c0a1', 16) - alternateRSA_Q = long( - '00d718b1fe9f8f99f00e832ae1fbdc6fe2ab27f34e049c498010fa0eb708' - '4852182346083b5c96c3eee5592c014a410c6b930b165c13b5c26aa32eac' - '6e7c925a8551c25134f2f4a72c6421f19a73148a0edfaba5d3a6888b35cb' - 'a18c00fd38ee5aaf0b545731d720761bbccdee744a52ca415e98e4de01cd' - 'fe764c1967b3e8cadb', 16) - alternateRSA_exp1 = long( - '01e5aca266c94a88d22e13c2b92ea247116c657a076817bdfd30db4b3a9d' - '3095b9a4b6749647e2f84e7a784fc7838b08c85971cf7a036fa30e3b91c3' - 'c4d0df278f80c1b6e859d8456adb137defaa9f1f0ac5bac9a9184fd4ea27' - '9d722ea626f160d78aad7bc83845ccb29df115c83f61b7622b99bd439c60' - '9b5790a63c595181', 16) - alternateRSA_exp2 = long( - '0080cc45d10d2484ee0d1297fc07bf80b3beff461ea27e1f38f371789c3a' - 'f66b4a0edd2192c227791db4f1c77ae246bf342f31856b0f56581b58a95b' - '1131c0c5396db2a8c3c6f39ea2e336bc205ae6a2a0b36869fca98cbba733' - 'cf01319a6f9bb26b7ca23d3017fc551cd8da8afdd17f6fa2e30d34868798' - '1cd6234d571e90b7df', 16) - alternateRSA_coef = long( - '6f77c0c1f2ae7ac169561cca499c52bdfbe04cddccdbdc12aec5a85691e8' - '594b7ee29908f30e7b96aa6254b80ed4aeec9b993782bdfc79b69d8d58c6' - '8870fa4be1bc0c3527288c5c82bb4aebaf15edff110403fc78e6ace6a828' - '27bf42f0cfa751e507651c5638db9393dd23dd1f6b295151de44b77fe55a' - '7b0df271e19a65c0', 16) - - def __init__(self, specification = None): - if not specification: - self.RSA_N = self.sharedRSA_N - self.RSA_E = self.sharedRSA_E - self.RSA_D = self.sharedRSA_D - self.RSA_P = self.sharedRSA_P - self.RSA_Q = self.sharedRSA_Q - self.RSA_exp1 = self.sharedRSA_exp1 - self.RSA_exp2 = self.sharedRSA_exp2 - self.RSA_coef = self.sharedRSA_coef - elif specification == 'alternate': - self.RSA_N = self.alternateRSA_N - self.RSA_E = self.alternateRSA_E - self.RSA_D = self.alternateRSA_D - self.RSA_P = self.alternateRSA_P - self.RSA_Q = self.alternateRSA_Q - self.RSA_exp1 = self.alternateRSA_exp1 - self.RSA_exp2 = self.alternateRSA_exp2 - self.RSA_coef = self.alternateRSA_coef - else: - raise UnknownKeySpecificationError(specification) - - def toDER(self): - privateKeyInfo = PrivateKeyInfo() - privateKeyInfo.setComponentByName('version', 0) - algorithmIdentifier = rfc2459.AlgorithmIdentifier() - algorithmIdentifier.setComponentByName('algorithm', rfc2459.rsaEncryption) - algorithmIdentifier.setComponentByName('parameters', univ.Null()) - privateKeyInfo.setComponentByName('privateKeyAlgorithm', algorithmIdentifier) - rsaPrivateKey = RSAPrivateKey() - rsaPrivateKey.setComponentByName('version', 0) - rsaPrivateKey.setComponentByName('modulus', self.RSA_N) - rsaPrivateKey.setComponentByName('publicExponent', self.RSA_E) - rsaPrivateKey.setComponentByName('privateExponent', self.RSA_D) - rsaPrivateKey.setComponentByName('prime1', self.RSA_P) - rsaPrivateKey.setComponentByName('prime2', self.RSA_Q) - rsaPrivateKey.setComponentByName('exponent1', self.RSA_exp1) - rsaPrivateKey.setComponentByName('exponent2', self.RSA_exp2) - rsaPrivateKey.setComponentByName('coefficient', self.RSA_coef) - rsaPrivateKeyEncoded = encoder.encode(rsaPrivateKey) - privateKeyInfo.setComponentByName('privateKey', univ.OctetString(rsaPrivateKeyEncoded)) - return encoder.encode(privateKeyInfo) - - def toPEM(self): - output = '-----BEGIN PRIVATE KEY-----' - der = self.toDER() - b64 = base64.b64encode(der) - while b64: - output += '\n' + b64[:64] - b64 = b64[64:] - output += '\n-----END PRIVATE KEY-----' - return output - - def asSubjectPublicKeyInfo(self): - """Returns a subject public key info representing - this key for use by pyasn1.""" - algorithmIdentifier = rfc2459.AlgorithmIdentifier() - algorithmIdentifier.setComponentByName('algorithm', rfc2459.rsaEncryption) - algorithmIdentifier.setComponentByName('parameters', univ.Null()) - spki = rfc2459.SubjectPublicKeyInfo() - spki.setComponentByName('algorithm', algorithmIdentifier) - rsaKey = RSAPublicKey() - rsaKey.setComponentByName('N', univ.Integer(self.RSA_N)) - rsaKey.setComponentByName('E', univ.Integer(self.RSA_E)) - subjectPublicKey = univ.BitString(byteStringToHexifiedBitString(encoder.encode(rsaKey))) - spki.setComponentByName('subjectPublicKey', subjectPublicKey) - return spki - - def sign(self, data): - """Returns a hexified bit string representing a - signature by this key over the specified data. - Intended for use with pyasn1.type.univ.BitString""" - rsaPrivateKey = rsa.PrivateKey(self.RSA_N, self.RSA_E, self.RSA_D, self.RSA_P, self.RSA_Q) - signature = rsa.sign(data, rsaPrivateKey, 'SHA-256') - return byteStringToHexifiedBitString(signature) - - -# The build harness will call this function with an output file-like -# object and a path to a file containing a specification. This will -# read the specification and output the key as ASCII-encoded PKCS #8. -def main(output, inputPath): - with open(inputPath) as configStream: - output.write(RSAKey(configStream.read()).toPEM()) - -# When run as a standalone program, this will read a specification from -# stdin and output the certificate as PEM to stdout. -if __name__ == '__main__': - print RSAKey(sys.stdin.read()).toPEM() diff --git a/security/manager/ssl/tests/unit/test_ocsp_url.js b/security/manager/ssl/tests/unit/test_ocsp_url.js index b731a1bcf6be..385f568f853e 100644 --- a/security/manager/ssl/tests/unit/test_ocsp_url.js +++ b/security/manager/ssl/tests/unit/test_ocsp_url.js @@ -25,14 +25,14 @@ function start_ocsp_responder(expectedCertNames, expectedPaths) { } function check_cert_err(cert_name, expected_error) { - let cert = constructCertFromFile("test_ocsp_url/" + cert_name + ".pem"); + let cert = constructCertFromFile("test_ocsp_url/" + cert_name + ".der"); return checkCertErrorGeneric(certdb, cert, expected_error, certificateUsageSSLServer); } function run_test() { - addCertFromFile(certdb, "test_ocsp_url/ca.pem", 'CTu,CTu,CTu'); - addCertFromFile(certdb, "test_ocsp_url/int.pem", ',,'); + addCertFromFile(certdb, "test_ocsp_url/ca.der", 'CTu,CTu,CTu'); + addCertFromFile(certdb, "test_ocsp_url/int.der", ',,'); // Enabled so that we can force ocsp failure responses. Services.prefs.setBoolPref("security.OCSP.require", true); @@ -44,7 +44,7 @@ function run_test() { add_test(function() { clearOCSPCache(); let ocspResponder = failingOCSPResponder(); - check_cert_err("bad-scheme", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + check_cert_err("bad-scheme",SEC_ERROR_CERT_BAD_ACCESS_LOCATION); ocspResponder.stop(run_next_test); }); diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.der b/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.der new file mode 100644 index 0000000000000000000000000000000000000000..0b26ef20e5e0a87faff02dc708b53b85ac45fc9d GIT binary patch literal 895 zcmXqLVy-r5VoF}X%*4pV#B32OV!+GBsnzDu_MMlJk(HIfAkL86fRl|ml!Z;0DKywn z*gz1(;SlC>PRz+n%P-2yOf(cT5CI9Y3-kKsm*$luX67k`Wu}%JiWmri#JPmI1A=`O zLQ;!MGV{_6c?`HfqRhg~nRz7!a^k#(CI+TPhKA(s( z%(nlt=PP1=|txjUzD<3 z8?LmSUZwM!^BzA(m4g1+4uh52*V{xHxa{v05EQ>siq?bfi~wsdnnEzZ7vU?v3cjUa^Wvh**6^Xe8IjMTd`MKbvBP-0pWWazNyugG7 z3|>Zto=dYM#P_aSz4+Z1>+ADkxLyhUozfk%XStA4jMdxe(P69pu-z3k(C|O<-e=B~ z483=1Ultu$n_+*(ccZR@q-!hNpJVqfHdnpf6|qU9onQIW=Oz1&DX&+G%Rj;As?F+? ze#l&f=i%EqTPJHQc1+OL@^|b0@j5@D_QJXIS#2Fjx1U|y|3`A~Ve1EX*NWchl3jIL zcCq32ov-6}&i+?&{E6!M#kXq~b5HRRdpk3qIsLVlrI7%*4pV#L6(=wnyH8myJ`a&7D}zC-A-4f18*?ZNn=n&o zu%WPlAc(^u%;lVzlbM!Zl$V)kC}to65@Z+V_02EMD@n}EQwYmUEjJV~5CVyF33CSo z`znN_7MEn^rNhi)7G_FLG>{YLH8e3WH8M0bH#Radj1uQHLgv!i`X)vtWDhg4GB7tW z@-rATF>*0AF)}i&HC!mv()#Vg%KZ!L`4zr5XReb{T_tpA#3qUYbU-nPS7VE)hKOjW@c=Qq+~{u@?>aLjio_q0*{X(Cr=@oCo5=|5*|-fO~d zE^Dl5>foPQ8d}8_H08d9@*Wsyy?`eA<_@4ln? z)#$#1xBdEHzxx;F-zhZW#Bmwq9zKuwU}Wue2(!2Dwmp6skmvVU9rLR!pm=BE_d zcaHDabIYU66fzUGb@Nv*{XJOw5c7jEe;f_zZY}F)1s|!fL?G$oL;Q%z%jm7-ozN zen($2ay)r`e$@`!!RPVFqL`g+Eh%?CqoZNIrx(m_sXp@;pkJjs+jE@9U3Gu@n0=Npz) z^4$~sUwPqJDBGWt(Mk25t%84_v7F7mQ>Of}|I0C5rKdCRH*R`(`jWe&+UN8d&In(1 zKigl8VPBs+{L+`{x^hG^Gkq54r#o9)l?zSf#Rr9bKueVp^# Q@c;hxvw8(nmg)Wk0Q$W{i2wiq literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec deleted file mode 100644 index d809dbd635d4..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec +++ /dev/null @@ -1,4 +0,0 @@ -issuer:ca -subject:ca -extension:basicConstraints:cA, -extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/cert9.db b/security/manager/ssl/tests/unit/test_ocsp_url/cert9.db new file mode 100644 index 0000000000000000000000000000000000000000..ddfac8e73aa0f843fdd5466edc19b1dd1d138b65 GIT binary patch literal 43008 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 literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.der b/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.der new file mode 100644 index 0000000000000000000000000000000000000000..8293d79b2ab6b1309ea348fb0458dde0d3c659cf GIT binary patch literal 904 zcmXqLVs0^LV#-;-%*4pV#KI{2MAd+ojZ>@5qwPB{BO@y-gF&1jw*e;`b0`a&FjHu- zp|F7NzBYs2+K?@Hxw}t0*P}8a|Zfqr`cQkhun_RJR}M1!iHc z)ZBuSO5K9|q7s89MkQpQGqN%;H!<=v0L8hOniv@w9<{v-)~+iwDmj1UeM!)?+lQ{N z<#(E@Dp9xW#{c>I1ve@OuAH)R>YC}Rie4}JV|P2pAc1???v=;uGnnNrYMj5n>gr8{ zx|MO4A8$D&JN=qv{;oSu|1f^moH}s|Q>1fyaM{N)87ZQ>uz}mnTIq7GPeoYDK{ur_KO6{|zg}YxX+31vC2sII64L;~+x~sDP_wuNf^P>OT zS?H9{^$Bh6zSlKpmxcD!;C6=zT`J5rUuqBRx{{fEQ0SfKMp4tMZ|>Pl%!~|-i=7P| z4NTZLwAp}3gPoC)MZ-YNKn2D(U~H4fC@Cqh($_C9FV{=0NX#wBN!3fv&$ZGACm~s3 z7A6A* z=kY2lWxAmub!&=D-+XzctMxLbx>G|OuerZ@^UWb^&GJM4*moVcaK^fN=fj;JJhJCq znY=kui|@k1trCar)?}vt+EQELCv$o4D$Kc`TFh#IvE{c)3mTpTA+Ay}!)_7r)Cm>=bLG z9#q!w&aEZEVPo;j7x(uaZ8Q7v@V;f@>lD*RuX|d4#0G6FrjsO4v literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.pem.certspec deleted file mode 100644 index 4f3e296f9c91..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/empty-port.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:empty-port -extension:authorityInformationAccess:http://www.example.com:/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.der new file mode 100644 index 0000000000000000000000000000000000000000..599c6ca54ee9a7712dc85aa6eb5818cc0cc9643b GIT binary patch literal 910 zcmXqLV(v0%Vk%m|%*4pV#KO2lO~`@5qwPB{BO@y-gF&1jw*e;`b0`a&FjHu- zp|F7NzBYs2+K?@Hxw}t0*P}8a|Z$hd3@xyS+*6TeJ|9p=pNw49S%%x!Qie>tqvn!lo%Er6wXKc}7%sSx`az zl17uAAN|igv6ht5{2g{zFS)F+XW!n8%^QL)7MHl6UdcC0wQ+G__I<7VkWCMl^6fk- zqV}@jx8^aapg#wN?eY(|p1ad%>T|n;U$uE-7}w*EmMy~5w~X-a7Q0gl~#zH4u*U%5Pwk%^g+ zfpM|3fun&58;3R9<>lpisTGO21v#mD$@#ff7C@j6 zPDrxCEKCLr$iWOuX24)(WU%{iI&9jG`pNef^;_P&zSBzf596hG-?n>nRL$-dzp#DJ zBT~Mo-^4VRQXkBi3_Ig`^cYH`Q)Z-C;6M{QWZ~D~6EY>5_h@%$pCb z`SEGrCW&2l*w>t!c(8#@l#5L^ZpFd?*2!KvhbKnU8 zb+KKu%Wrn@{nQg)9ygP-U`~?_7t5`*{*PPrek{Aer+)sI3%9-VoSy8h8rwVymMLv! z6cym@@7;1Ran|#6x2rF=gty%buI7mnX6T8v;L8kIc*p;~8e2w*VP5M?qqCXKu};^2 f{n|8ljX}rV8YPwg5i1&QWbWlH{L^Th`m7lM7R^o` literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec deleted file mode 100644 index e8959653f3c1..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:empty-scheme-url -extension:authorityInformationAccess:://www.example.com:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.der new file mode 100644 index 0000000000000000000000000000000000000000..efa716a4b2a620b65ecd0d316f44456fd21d89c8 GIT binary patch literal 903 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

=h`h!ceN7%}uSptrb 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 literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/moz.build b/security/manager/ssl/tests/unit/test_ocsp_url/moz.build deleted file mode 100644 index 5cf49a7f9946..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/moz.build +++ /dev/null @@ -1,42 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -test_certificates = ( - 'bad-scheme.pem', - 'ca.pem', - 'empty-port.pem', - 'empty-scheme-url.pem', - 'ftp-url.pem', - 'hTTp-url.pem', - 'https-url.pem', - 'int.pem', - 'negative-port.pem', - 'no-host-url.pem', - 'no-path-url.pem', - 'no-scheme-host-port.pem', - 'no-scheme-url.pem', - 'unknown-scheme.pem', -) - -for test_certificate in test_certificates: - input_file = test_certificate + '.certspec' - GENERATED_FILES += [test_certificate] - props = GENERATED_FILES[test_certificate] - props.script = '../pycert.py' - props.inputs = [input_file, '!/config/buildid'] - TEST_HARNESS_FILES.xpcshell.security.manager.ssl.tests.unit.test_ocsp_url += ['!%s' % test_certificate] - -test_keys = ( - 'int.key', -) - -for test_key in test_keys: - input_file = test_key + '.keyspec' - GENERATED_FILES += [test_key] - props = GENERATED_FILES[test_key] - props.script = '../pykey.py' - props.inputs = [input_file] - TEST_HARNESS_FILES.xpcshell.security.manager.ssl.tests.unit.test_ocsp_url += ['!%s' % test_key] diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.der b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.der new file mode 100644 index 0000000000000000000000000000000000000000..2e334b682eac577b0203cc5153c32ba269dc99f9 GIT binary patch literal 908 zcmXqLV(u_#Vk%g`%*4pV#KQ3J#{mOgHcqWJkGAi;jEt#>@(l2>B(G)ZYY{<^3wnYp~axu40>Kt@k6Wa+!B+a^nK{4d=3cFK*0{HdP`tM&8$ z4|n*he#_{4WFm3$_iD#KGmNtICB7_i zc(%_zD2T10VuvPU-D&|Zz59#rN@VR@XZb*vHH1^gUnM8}$(kHPx#i7gbML3h@(aIV zRN5i>U;4Y{7;V5vxx{|6Ml!&bgR8IV_j|yL9dEUI@AO&pbNu-~r}et9{=sL9ib_Ab``BJzn`x#r zyDC|lXO@Igw`Z-nxO(yTTLC_WH~M?DKkn01KbgT&?04|eZ_zK8(`|!&B7O$!$laCl ze_zEx&amqH9^d!f<-S;@bhANxrHCR^)im)(f2J?by&C@EhMe$g!|A;@RbPaKm)Tbu dUEg%0T3NhS;CT(l6MmsAUs)&H&Ed1GbOBNzO6~vv literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec deleted file mode 100644 index 4abc0720519f..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:negative-port -extension:authorityInformationAccess:http://www.example.com:-1 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.der new file mode 100644 index 0000000000000000000000000000000000000000..236dd8186cb5db9bc51f0758d76d3b5e10c410ad GIT binary patch literal 894 zcmXqLVy-f1VoF-T%*4pV#KN#OCC7l5jZ>@5qwPB{BO@y-gF&1jw*e;`b0`a&FjHu- zp|F7NzBYs2+K?@Hxw}t0*P}8a|Z=qr`cQkhunFRJR}MDrRBs zynNk^{NfVb(xM!LCPpP>uQReTFgG#sGXTZ8n3@YMc#+$3tD})# z1r}>ggn8U5+fmi=@J`xf3452B>U$)vA9=yxAkRAnn{z4V>#4_N7#`0uUzlLf z)iisXbBy=7JG);TQ`63wpliPTQ{tMM%01`Q4v9}V9Gh47UBs-5%f&T|@9AE)iC_4aY`%Q(^ZMbX;8bZO5)ZZCtm`iCl>hUbNnc zgQdxH^3&(5WKW&Xn>;D>_yfh44J!}s3n;zAzO+>J%>BH#pD$lf-6j2+B|Gu8j?jr0 SWmV_*pVU4T!7??O-x&bGu1^;L literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec deleted file mode 100644 index 4ac76e7eb33a..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:no-host-url -extension:authorityInformationAccess:http://:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.der new file mode 100644 index 0000000000000000000000000000000000000000..2333b33a1f837eeccd2f654daa90b7033e48e02b GIT binary patch literal 908 zcmXqLV(u_#Vk%g`%*4pV#KL&~^cMqOHcqWJkGAi;jEth&j1wXVrpV!WO#g!akZanaLIC;Qwu9IOP;=; z;Ls|6C51V^`u&Nx>j_$OX6sInbia1+NRX^_kD2D(n#Z3K)wjg|*ITi4qrJ@#=CMP2?l)IQX#_49~ zWQAFn3>c6@8kop{A%v}Afq$oc?^l1f zH^s-(Ui5U!b*H8ln;ZL19P6K-7uYT!@~8d|e+KtER_TnH+iZdw?$+0x*9&Axbo}%n zmgnvBX@~25%>q7q8RxR?;&ShgPi=eoZMsYX=f=h9RiDiq`9(PwINo3X;eMa3$BMPK z@5JrW{>VSuk#_ga^6hQA`A+XSaiU)1b2=NpwC9Omi&p%Jc6|_P-ML-!-1!8i^!-zG zzV81jrgG-#6_L;HnO^M;@mz6j&)uvmCtU*XUy7Z+_vz~XB}UGNFSZqDEK7X%t4@Dw e@S(KkIZ|A+Wg8pWC0OFUbgt(6ADLRv8x8>IJyX;G literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec deleted file mode 100644 index 497bb287967c..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:no-path-url -extension:authorityInformationAccess:http://www.example.com:8888 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.der b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.der new file mode 100644 index 0000000000000000000000000000000000000000..f6e0179a6e48f016bcb4c2c82e50b5dfe482cb61 GIT binary patch literal 889 zcmXqLVlFjkVv1eB%*4pV#2lCU*?^agQ>)FR?K>|cBP%O|L7XAC0Vf-CC<~h~Q)sZE zuz?_m!y(M&oS2iDmS2>YnP@0xAOaF(7v}ZNFU>1S%*;~=%SdZ*}iC|G%;0yW+(i+9kg#q(ur>M|cy^k3-zuw{Qc)7?ATA=9UPdA?_&OX889$vRW+IEGEInCz;^a^b<&i#sHq z+B9Z4T$po$^EFqk!NuTX9T!vkRHY{DVtkq&#eCYMVn@^i|FbKdOFwwrbnH(1dwcQ= z+szG|nH-d)&R6oxOlxFe+|hX_uX+EQKZoZ05>R>X)3#?V+gG-a>}QjA#HpOrDO=O$ z9{ohvoX_Hq+p%3%PA~OOKHDynZ6bd1D*w)vg0X=gToyQemJ?e1FOK{9&)GIl@6T?{ zWnyMzU|g(Ypk*M-#-YsyOe5@!j4Xl%{J>Cy@(mc<81=!4Mpl@G$$$YlJb_6H7@mv_ zYSG1|*D~F5EMt!EULUE$$U6PdYmB z_Pe*UPB3Mg#_gT>s=F}zV9f(=+rUJT0^zIMcY2>;S-^29XlL}-=)`kD-*2=h`xUN} zzJ7b@Z!>`@vrPUP+D9&Cj(p;>!+)vfG>0!g1v1hevL$Vr@chiKRhxI5PO6dXaQwkt zX}*7I(FDaileRf0d?xW{g#5NZ^Z(T34J7e;F zE+<2t!h?tGy|?etkvIEuar*wv&wHJ2E)bJWU2#d_cEl7W`~6x*MeWkNX5^}>{doDl O)Zv|-`^w|j97_SJmQM-* literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec deleted file mode 100644 index 42a555e411b5..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:no-scheme-host-port -extension:authorityInformationAccess:/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.der b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.der new file mode 100644 index 0000000000000000000000000000000000000000..0bab0213518ee7fff702f6164df06837cb81f73c GIT binary patch literal 904 zcmXqLVs0^LV#-;-%*4pV#KLIUKf!>PjZ>@5qwPB{BO@y-gF&1jw*e;`b0`a&FjHu- zp|F7NzBYs2+K?@Hxw}t0*P}8a|ZgqQrTPkhumKRJR}MT4rJ1 zynNl_PFeE>6mX5>!4 zOUo~0Z2Zpr_PX7a{?k#uN2Wb2>dG{pRx0qDX@%&cOY>_ukImWnXwMb7ZxajKEccri zw(`dO@LwwPBG-SH%_4itMLnBkROfO&5pVxgEs!x&)-h}Q=k+~XGpB?bNPC%iCFPf$ zcVR#A>fAiz&(C>Iw9aGM_ot=h-DG|F++FjTbf@uui+ao&&Sb5ZWpbhW)GW5gjC)R< zzL!+#-YsyOdafuj4Y}K$_9!sz5!#KXnA?LUTQ^RZb43}UUGh}l?4#!gOiY~Fbk6b z19BJx6Bsaz85vqj_Aq2ToVoV&y|fG#Z@;GZE9+*9I8{DQdUWHKroLf-xW^WQ)m+ED zh4i1#@U`5%khy3@vDO)u&a-roJjxG-^;Oc zkK}t%xeafwG3Fh=^z3>3tOX7HXSPl;WuJY+$l(z~vH6p7-N!A@ z)tL`HbXI#C$gH`4qrRdX&!&e}zy5CQjh}HVAUH12<<9S{8QsPyr`F$)b6#d^b%*4pV#KQ3V{5b<&HcqWJkGAi;jEtMI-j zTQ@f?Iu$fUOqca|=BcmmjZ@y8{qRt^|FqrxLxNG7N3JSwk$APeZtHEqA5sEk>3a-% zmNb_M_DxJZc+Rq9&db*i%|A)p^*f&T;;1&y#`hbQ=i9z^oO?p<+_rU_x}Lma{p@}w zsHgY8+3d+Fi{`#>ZVB>#x=s6SXlLA{h!^v`KX6SJm6=>Op~^@3mG0%uKeZB$E}lK@ z!;WJG$0NTQ8hV-XZ7R{&AADbLR+vNS8q3SS%+FX|xOINt|C*?NvsBN&`Q9;cCHrn& zk-Xu(ApP|DGk22L-AL@7Zu)cQwdzGH4;e_GtlhJG*QHd^{o1`-n_AgKf3AMqy^x8S zk%4isgMpoaAsdG_8!&mWGcvNM8Ymkm!uSS^ZK5S51y=g{<>lpisTGO21v#mD$@#h9 zG$bp`!eqdJ9LB&D1`K0H2Fv$1+}dWayUcyu{hgJ!L@ctYeaEHws!eGn7OeALy*bMK z_QPLA3BMNZZ||pvPPn(-)A){oyo!8;zH-<)yNz3yMU*#N zzv%RNtL4Au?Qd7UWVvo;zx0}F>Ap}8hX-5b>aUrd&Aznlqt&Wa-oNZm{=8oLv;79g zHaJ gG1cX8nyApE+DFG4^BHa$U%Kt&%eug%t}CJv0BJj6PXGV_ literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec deleted file mode 100644 index a5e62b3e6e65..000000000000 --- a/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec +++ /dev/null @@ -1,3 +0,0 @@ -issuer:int -subject:unknown-scheme-url -extension:authorityInformationAccess:ttp://www.example.com diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp index 219f97377121..8bb54bcbce6a 100644 --- a/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp @@ -10,13 +10,9 @@ */ #include -#include -#include #include "mozilla/ArrayUtils.h" -#include "base64.h" -#include "cert.h" #include "nspr.h" #include "nss.h" #include "plarenas.h" @@ -70,8 +66,9 @@ const static OCSPResponseName kOCSPResponseNameList[] = { // two years old }; + bool -StringToOCSPResponseType(const char* respText, +stringToOCSPResponseType(const char* respText, /*out*/ OCSPResponseType* OCSPType) { if (!OCSPType) { @@ -110,216 +107,7 @@ WriteResponse(const char* filename, const SECItem* item) return true; } -template -SECStatus -ReadFileToBuffer(const char* basePath, const char* filename, char (&buf)[N]) -{ - static_assert(N > 0, "input buffer too small for ReadFileToBuffer"); - if (PR_snprintf(buf, N - 1, "%s/%s", basePath, filename) == 0) { - PrintPRError("PR_snprintf failed"); - return SECFailure; - } - ScopedPRFileDesc fd(PR_OpenFile(buf, PR_RDONLY, 0)); - if (!fd) { - PrintPRError("PR_Open failed"); - return SECFailure; - } - int32_t fileSize = PR_Available(fd); - if (fileSize < 0) { - PrintPRError("PR_Available failed"); - return SECFailure; - } - if (static_cast(fileSize) > N - 1) { - PR_fprintf(PR_STDERR, "file too large - not reading\n"); - return SECFailure; - } - int32_t bytesRead = PR_Read(fd, buf, fileSize); - if (bytesRead != fileSize) { - PrintPRError("PR_Read failed"); - return SECFailure; - } - buf[bytesRead] = 0; - return SECSuccess; -} -namespace mozilla { - -MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRDir, PRDir, PR_CloseDir); -MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPORTString, unsigned char, PORT_Free); - -}; - -void -AddKeyFromFile(const char* basePath, const char* filename) -{ - const char* PRIVATE_KEY_HEADER = "-----BEGIN PRIVATE KEY-----"; - const char* PRIVATE_KEY_FOOTER = "-----END PRIVATE KEY-----"; - - char buf[16384] = { 0 }; - SECStatus rv = ReadFileToBuffer(basePath, filename, buf); - if (rv != SECSuccess) { - return; - } - if (strncmp(buf, PRIVATE_KEY_HEADER, strlen(PRIVATE_KEY_HEADER)) != 0) { - PR_fprintf(PR_STDERR, "invalid key - not importing\n"); - return; - } - const char* bufPtr = buf + strlen(PRIVATE_KEY_HEADER); - size_t bufLen = strlen(buf); - char base64[16384] = { 0 }; - char* base64Ptr = base64; - while (bufPtr < buf + bufLen) { - if (strncmp(bufPtr, PRIVATE_KEY_FOOTER, strlen(PRIVATE_KEY_FOOTER)) == 0) { - break; - } - if (*bufPtr != '\r' && *bufPtr != '\n') { - *base64Ptr = *bufPtr; - base64Ptr++; - } - bufPtr++; - } - - unsigned int binLength; - ScopedPORTString bin(ATOB_AsciiToData(base64, &binLength)); - if (!bin || binLength == 0) { - PrintPRError("ATOB_AsciiToData failed"); - return; - } - ScopedSECItem secitem(SECITEM_AllocItem(nullptr, nullptr, binLength)); - if (!secitem) { - PrintPRError("SECITEM_AllocItem failed"); - return; - } - memcpy(secitem->data, bin, binLength); - ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); - if (!slot) { - PrintPRError("PK11_GetInternalKeySlot failed"); - return; - } - if (PK11_NeedUserInit(slot)) { - if (PK11_InitPin(slot, nullptr, nullptr) != SECSuccess) { - PrintPRError("PK11_InitPin failed"); - return; - } - } - SECKEYPrivateKey* privateKey; - if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, secitem, nullptr, nullptr, - true, false, KU_ALL, - &privateKey, nullptr) - != SECSuccess) { - PrintPRError("PK11_ImportDERPrivateKeyInfoAndReturnKey failed"); - return; - } - SECKEY_DestroyPrivateKey(privateKey); -} - -SECStatus -DecodeCertCallback(void* arg, SECItem** certs, int numcerts) -{ - if (numcerts != 1) { - PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); - return SECFailure; - } - SECItem* certDEROut = static_cast(arg); - return SECITEM_CopyItem(nullptr, certDEROut, *certs); -} - -void -AddCertificateFromFile(const char* basePath, const char* filename) -{ - char buf[16384] = { 0 }; - SECStatus rv = ReadFileToBuffer(basePath, filename, buf); - if (rv != SECSuccess) { - return; - } - SECItem certDER; - rv = CERT_DecodeCertPackage(buf, strlen(buf), DecodeCertCallback, &certDER); - if (rv != SECSuccess) { - PrintPRError("CERT_DecodeCertPackage failed"); - return; - } - ScopedCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(), - &certDER, nullptr, false, - true)); - PORT_Free(certDER.data); - if (!cert) { - PrintPRError("CERT_NewTempCertificate failed"); - return; - } - const char* extension = strstr(filename, ".pem"); - if (!extension) { - PR_SetError(SEC_ERROR_INVALID_ARGS, 0); - return; - } - size_t nicknameLength = extension - filename; - memset(buf, 0, sizeof(buf)); - memcpy(buf, filename, nicknameLength); - buf[nicknameLength] = 0; - ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); - if (!slot) { - PrintPRError("PK11_GetInternalKeySlot failed"); - return; - } - rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, buf, false); - if (rv != SECSuccess) { - PrintPRError("PK11_ImportCert failed"); - } -} - -SECStatus -InitializeNSS(const char* nssCertDBDir) -{ - // First attempt to initialize NSS in read-only mode, in case the specified - // directory contains NSS DBs that are tracked by revision control. - // If this succeeds, we're done. - if (NSS_Initialize(nssCertDBDir, "", "", SECMOD_DB, NSS_INIT_READONLY) - == SECSuccess) { - return SECSuccess; - } - // Otherwise, create a new read-write DB and load all .pem and .key files. - if (NSS_Initialize(nssCertDBDir, "", "", SECMOD_DB, 0) != SECSuccess) { - PrintPRError("NSS_Initialize failed"); - return SECFailure; - } - const char* basePath = nssCertDBDir; - // The NSS cert DB path could have been specified as "sql:path". Trim off - // the leading "sql:" if so. - if (strncmp(basePath, "sql:", 4) == 0) { - basePath = basePath + 4; - } - ScopedPRDir fdDir(PR_OpenDir(basePath)); - if (!fdDir) { - PrintPRError("PR_OpenDir failed"); - return SECFailure; - } - // On the B2G ICS emulator, operations taken in AddCertificateFromFile or - // AddKeyFromFile appear to interact poorly with PR_ReadDir (more - // specifically, something is causing PR_ReadDir to never return null - it - // indefinitely loops through every file in the directory, which causes - // timeouts). Rather than waste more time chasing this down, loading - // certificates and keys happens in two phases: filename collection and then - // loading. - std::vector certificates; - std::vector keys; - for (PRDirEntry* dirEntry = PR_ReadDir(fdDir, PR_SKIP_BOTH); dirEntry; - dirEntry = PR_ReadDir(fdDir, PR_SKIP_BOTH)) { - size_t nameLength = strlen(dirEntry->name); - if (nameLength > 4) { - if (strncmp(dirEntry->name + nameLength - 4, ".pem", 4) == 0) { - certificates.push_back(dirEntry->name); - } else if (strncmp(dirEntry->name + nameLength - 4, ".key", 4) == 0) { - keys.push_back(dirEntry->name); - } - } - } - for (std::string& certificate : certificates) { - AddCertificateFromFile(basePath, certificate.c_str()); - } - for (std::string& key : keys) { - AddKeyFromFile(basePath, key.c_str()); - } - return SECSuccess; -} int main(int argc, char* argv[]) @@ -332,9 +120,12 @@ main(int argc, char* argv[]) argv[0]); exit(EXIT_FAILURE); } - SECStatus rv = InitializeNSS(argv[1]); + const char* dbdir = argv[1]; + + SECStatus rv; + rv = NSS_Init(dbdir); if (rv != SECSuccess) { - PR_fprintf(PR_STDERR, "Failed to initialize NSS\n"); + PrintPRError("Failed to initialize NSS"); exit(EXIT_FAILURE); } PLArenaPool* arena = PORT_NewArena(256 * argc); @@ -350,15 +141,15 @@ main(int argc, char* argv[]) const char* filename = argv[i + 3]; OCSPResponseType ORT; - if (!StringToOCSPResponseType(ocspTypeText, &ORT)) { + if (!stringToOCSPResponseType(ocspTypeText, &ORT)) { PR_fprintf(PR_STDERR, "Cannot generate OCSP response of type %s\n", ocspTypeText); exit(EXIT_FAILURE); } - ScopedCERTCertificate cert(PK11_FindCertFromNickname(certNick, nullptr)); + ScopedCERTCertificate cert; + cert = PK11_FindCertFromNickname(certNick, nullptr); if (!cert) { - PrintPRError("PK11_FindCertFromNickname failed"); PR_fprintf(PR_STDERR, "Failed to find certificate with nick '%s'\n", certNick); exit(EXIT_FAILURE);