зеркало из https://github.com/mozilla/gecko-dev.git
Back out 2 changesets (bug 1178988) for b2g emulator opt xpcshell failure in test_ocsp_url.js
CLOSED TREE Backed out changeset 2c5d5eb434b9 (bug 1178988) Backed out changeset 936d991c4cbc (bug 1178988)
This commit is contained in:
Родитель
516b82d211
Коммит
6565c918a7
|
@ -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']:
|
||||
|
|
|
@ -26,7 +26,6 @@ extKeyUsage:[serverAuth,clientAuth,codeSigning,emailProtection
|
|||
nsSGC, # Netscape Server Gated Crypto
|
||||
OCSPSigning,timeStamping]
|
||||
subjectAlternativeName:[<dNSName>,...]
|
||||
authorityInformationAccess:<OCSP URI>
|
||||
|
||||
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 "'<hex bytes>'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):
|
||||
|
|
|
@ -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 "'<hex bytes>'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()
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
Двоичный файл не отображается.
|
@ -1,3 +0,0 @@
|
|||
issuer:int
|
||||
subject:bad-scheme
|
||||
extension:authorityInformationAccess:/www.example.com
|
Двоичный файл не отображается.
|
@ -1,4 +0,0 @@
|
|||
issuer:ca
|
||||
subject:ca
|
||||
extension:basicConstraints:cA,
|
||||
extension:keyUsage:keyCertSign,cRLSign
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -1,3 +0,0 @@
|
|||
issuer:int
|
||||
subject:empty-port
|
||||
extension:authorityInformationAccess:http://www.example.com:/
|
Двоичный файл не отображается.
|
@ -1,3 +0,0 @@
|
|||
issuer:int
|
||||
subject:empty-scheme-url
|
||||
extension:authorityInformationAccess:://www.example.com:8888/
|
Двоичный файл не отображается.
|
@ -1,3 +0,0 @@
|
|||
issuer:int
|
||||
subject:ftp-url
|
||||
extension:authorityInformationAccess:ftp://www.example.com:8888/
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import tempfile, os, sys
|
||||
|
||||
libpath = os.path.abspath('../psm_common_py')
|
||||
sys.path.append(libpath)
|
||||
import CertUtils
|
||||
|
||||
srcdir = os.getcwd()
|
||||
db = tempfile.mkdtemp()
|
||||
|
||||
def generate_ca_cert(db_dir, dest_dir, noise_file, name):
|
||||
return CertUtils.generate_ca_cert(db_dir, dest_dir, noise_file, name,
|
||||
3, True)
|
||||
|
||||
def generate_child_cert(db_dir, dest_dir, noise_file, name, ca_nick, is_ee,
|
||||
ocsp_url):
|
||||
return CertUtils.generate_child_cert(db_dir, dest_dir, noise_file, name,
|
||||
ca_nick, 3, True, is_ee, ocsp_url)
|
||||
|
||||
def generate_certs():
|
||||
[noise_file, pwd_file] = CertUtils.init_nss_db(srcdir)
|
||||
generate_ca_cert(srcdir, srcdir, noise_file, 'ca')
|
||||
generate_child_cert(srcdir, srcdir, noise_file, 'int', 'ca', False, '')
|
||||
nick_baseurl = { 'no-path-url': "http://www.example.com:8888",
|
||||
'ftp-url': "ftp://www.example.com:8888/",
|
||||
'no-scheme-url': "www.example.com:8888/",
|
||||
'empty-scheme-url': "://www.example.com:8888/",
|
||||
'no-host-url': "http://:8888/",
|
||||
'hTTp-url': "hTTp://www.example.com:8888/hTTp-url",
|
||||
'https-url': "https://www.example.com:8888/https-url",
|
||||
'bad-scheme': "/www.example.com",
|
||||
'empty-port': "http://www.example.com:/",
|
||||
'unknown-scheme': "ttp://www.example.com",
|
||||
'negative-port': "http://www.example.com:-1",
|
||||
'no-scheme-host-port': "/" }
|
||||
for nick, url in nick_baseurl.iteritems():
|
||||
generate_child_cert(srcdir, srcdir, noise_file, nick, 'int', True, url)
|
||||
|
||||
generate_certs()
|
Двоичный файл не отображается.
|
@ -1,3 +0,0 @@
|
|||
issuer:int
|
||||
subject:hTTp-url
|
||||
extension:authorityInformationAccess:hTTp://www.example.com:8888/hTTp-url
|
Двоичный файл не отображается.
|
@ -1,3 +0,0 @@
|
|||
issuer:int
|
||||
subject:https-url
|
||||
extension:authorityInformationAccess:https://www.example.com:8888/https-url
|
Двоичный файл не отображается.
|
@ -1,4 +0,0 @@
|
|||
issuer:ca
|
||||
subject:int
|
||||
extension:basicConstraints:cA,
|
||||
extension:keyUsage:keyCertSign,cRLSign
|
Двоичный файл не отображается.
|
@ -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]
|
Двоичный файл не отображается.
|
@ -1,3 +0,0 @@
|
|||
issuer:int
|
||||
subject:negative-port
|
||||
extension:authorityInformationAccess:http://www.example.com:-1
|
Двоичный файл не отображается.
|
@ -1,3 +0,0 @@
|
|||
issuer:int
|
||||
subject:no-host-url
|
||||
extension:authorityInformationAccess:http://:8888/
|
Двоичный файл не отображается.
|
@ -1,3 +0,0 @@
|
|||
issuer:int
|
||||
subject:no-path-url
|
||||
extension:authorityInformationAccess:http://www.example.com:8888
|
Двоичный файл не отображается.
|
@ -1,3 +0,0 @@
|
|||
issuer:int
|
||||
subject:no-scheme-host-port
|
||||
extension:authorityInformationAccess:/
|
Двоичный файл не отображается.
|
@ -1,3 +0,0 @@
|
|||
issuer:int
|
||||
subject:no-scheme-url
|
||||
extension:authorityInformationAccess:www.example.com:8888/
|
|
@ -0,0 +1,5 @@
|
|||
library=
|
||||
name=NSS Internal PKCS #11 Module
|
||||
parameters=configdir='sql:./security/manager/ssl/tests/unit/test_ocsp_url' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription=''
|
||||
NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30})
|
||||
|
Двоичный файл не отображается.
|
@ -1,3 +0,0 @@
|
|||
issuer:int
|
||||
subject:unknown-scheme-url
|
||||
extension:authorityInformationAccess:ttp://www.example.com
|
|
@ -13,8 +13,6 @@
|
|||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
|
||||
#include "base64.h"
|
||||
#include "cert.h"
|
||||
#include "nspr.h"
|
||||
#include "nss.h"
|
||||
#include "plarenas.h"
|
||||
|
@ -66,8 +64,9 @@ const static OCSPResponseName kOCSPResponseNameList[] = {
|
|||
// two years old
|
||||
};
|
||||
|
||||
|
||||
bool
|
||||
StringToOCSPResponseType(const char* respText,
|
||||
stringToOCSPResponseType(const char* respText,
|
||||
/*out*/ OCSPResponseType* OCSPType)
|
||||
{
|
||||
if (!OCSPType) {
|
||||
|
@ -106,201 +105,7 @@ WriteResponse(const char* filename, const SECItem* item)
|
|||
return true;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
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<size_t>(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<SECItem*>(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;
|
||||
}
|
||||
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) {
|
||||
AddCertificateFromFile(basePath, dirEntry->name);
|
||||
} else if (strncmp(dirEntry->name + nameLength - 4, ".key", 4) == 0) {
|
||||
AddKeyFromFile(basePath, dirEntry->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
|
@ -313,9 +118,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);
|
||||
|
@ -331,15 +139,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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче