bug 1413336 - (3/7) fix pycert.py and pykey.py with respect to pyasn1/pyasn1-modules updates r?Cykesiopka
MozReview-Commit-ID: CsxOF7LdEHB
--- a/security/manager/ssl/tests/unit/pycert.py
+++ b/security/manager/ssl/tests/unit/pycert.py
@@ -80,52 +80,28 @@ TLSFeature values can either consist of
feature value (see rfc7633 for more information).
If a serial number is not explicitly specified, it is automatically
generated based on the contents of the certificate.
"""
from pyasn1.codec.der import decoder
from pyasn1.codec.der import encoder
-from pyasn1.type import constraint, namedtype, tag, univ, useful
+from pyasn1.type import constraint, tag, univ, useful
from pyasn1_modules import rfc2459
from struct import pack
import base64
import datetime
import hashlib
import re
import sys
import pyct
import pykey
-# The GeneralSubtree definition in pyasn1_modules.rfc2459 is incorrect.
-# Where this definition uses a DefaultedNamedType, pyasn1_modules uses
-# a NamedType, which results in the default value being explicitly
-# encoded, which is incorrect for DER.
-class GeneralSubtree(univ.Sequence):
- componentType = namedtype.NamedTypes(
- namedtype.NamedType('base', rfc2459.GeneralName()),
- namedtype.DefaultedNamedType('minimum', rfc2459.BaseDistance(0).subtype(
- implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))),
- namedtype.OptionalNamedType('maximum', rfc2459.BaseDistance().subtype(
- implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)))
- )
-
-
-# The NameConstraints definition in pyasn1_modules.rfc2459 is incorrect.
-# excludedSubtrees has a tag value of 1, not 0.
-class NameConstraints(univ.Sequence):
- componentType = namedtype.NamedTypes(
- namedtype.OptionalNamedType('permittedSubtrees', rfc2459.GeneralSubtrees().subtype(
- implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))),
- namedtype.OptionalNamedType('excludedSubtrees', rfc2459.GeneralSubtrees().subtype(
- implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)))
- )
-
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class UnknownBaseError(Error):
"""Base class for handling unexpected input in this module."""
@@ -239,17 +215,17 @@ class InvalidSerialNumber(Error):
def __str__(self):
return repr(self.value)
def getASN1Tag(asn1Type):
"""Helper function for returning the base tag value of a given
type from the pyasn1 package"""
- return asn1Type.baseTagSet.getBaseTag().asTuple()[2]
+ return asn1Type.tagSet.baseTag.tagId
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)
@@ -317,37 +293,46 @@ def stringToDN(string, tag=None):
def stringToAlgorithmIdentifiers(string):
"""Helper function that converts a description of an algorithm
to a representation usable by the pyasn1 package and a hash
algorithm constant for use by pykey."""
algorithmIdentifier = rfc2459.AlgorithmIdentifier()
algorithmType = None
algorithm = None
+ # We add Null parameters for RSA only
+ addParameters = False
if string == 'sha1WithRSAEncryption':
algorithmType = pykey.HASH_SHA1
algorithm = rfc2459.sha1WithRSAEncryption
+ addParameters = True
elif string == 'sha256WithRSAEncryption':
algorithmType = pykey.HASH_SHA256
algorithm = univ.ObjectIdentifier('1.2.840.113549.1.1.11')
+ addParameters = True
elif string == 'md5WithRSAEncryption':
algorithmType = pykey.HASH_MD5
algorithm = rfc2459.md5WithRSAEncryption
+ addParameters = True
elif string == 'ecdsaWithSHA256':
algorithmType = pykey.HASH_SHA256
algorithm = univ.ObjectIdentifier('1.2.840.10045.4.3.2')
elif string == 'ecdsaWithSHA384':
algorithmType = pykey.HASH_SHA384
algorithm = univ.ObjectIdentifier('1.2.840.10045.4.3.3')
elif string == 'ecdsaWithSHA512':
algorithmType = pykey.HASH_SHA512
algorithm = univ.ObjectIdentifier('1.2.840.10045.4.3.4')
else:
raise UnknownAlgorithmTypeError(string)
- algorithmIdentifier.setComponentByName('algorithm', algorithm)
+ algorithmIdentifier['algorithm'] = algorithm
+ if addParameters:
+ # Directly setting parameters to univ.Null doesn't currently work.
+ nullEncapsulated = encoder.encode(univ.Null())
+ algorithmIdentifier['parameters'] = univ.Any(nullEncapsulated)
return (algorithmIdentifier, algorithmType)
def datetimeToTime(dt):
"""Takes a datetime object and returns an rfc2459.Time object with
that time as its value as a GeneralizedTime"""
time = rfc2459.Time()
time.setComponentByName('generalTime', useful.GeneralizedTime(dt.strftime('%Y%m%d%H%M%SZ')))
return time
@@ -528,30 +513,28 @@ class Certificate(object):
def addBasicConstraints(self, basicConstraints, critical):
cA = basicConstraints.split(',')[0]
pathLenConstraint = basicConstraints.split(',')[1]
basicConstraintsExtension = rfc2459.BasicConstraints()
basicConstraintsExtension.setComponentByName('cA', cA == 'cA')
if pathLenConstraint:
pathLenConstraintValue = \
univ.Integer(int(pathLenConstraint)).subtype(
- subtypeSpec=constraint.ValueRangeConstraint(0, 64))
+ subtypeSpec=constraint.ValueRangeConstraint(0, float('inf')))
basicConstraintsExtension.setComponentByName('pathLenConstraint',
pathLenConstraintValue)
self.addExtension(rfc2459.id_ce_basicConstraints, basicConstraintsExtension, critical)
def addKeyUsage(self, keyUsage, critical):
keyUsageExtension = rfc2459.KeyUsage(keyUsage)
self.addExtension(rfc2459.id_ce_keyUsage, keyUsageExtension, critical)
def keyPurposeToOID(self, keyPurpose):
if keyPurpose == 'serverAuth':
- # the OID for id_kp_serverAuth is incorrect in the
- # pyasn1-modules implementation
- return univ.ObjectIdentifier('1.3.6.1.5.5.7.3.1')
+ return rfc2459.id_kp_serverAuth
if keyPurpose == 'clientAuth':
return rfc2459.id_kp_clientAuth
if keyPurpose == 'codeSigning':
return rfc2459.id_kp_codeSigning
if keyPurpose == 'emailProtection':
return rfc2459.id_kp_emailProtection
if keyPurpose == 'nsSGC':
return univ.ObjectIdentifier('2.16.840.1.113730.4.1')
@@ -596,17 +579,17 @@ class Certificate(object):
policyOID = '2.5.29.32.0'
policy = rfc2459.PolicyInformation()
policyIdentifier = rfc2459.CertPolicyId(policyOID)
policy.setComponentByName('policyIdentifier', policyIdentifier)
policies.setComponentByPosition(pos, policy)
self.addExtension(rfc2459.id_ce_certificatePolicies, policies, critical)
def addNameConstraints(self, constraints, critical):
- nameConstraints = NameConstraints()
+ nameConstraints = rfc2459.NameConstraints()
if constraints.startswith('permitted:'):
(subtreesType, subtreesTag) = ('permittedSubtrees', 0)
elif constraints.startswith('excluded:'):
(subtreesType, subtreesTag) = ('excludedSubtrees', 1)
else:
raise UnknownNameConstraintsSpecificationError(constraints)
generalSubtrees = rfc2459.GeneralSubtrees().subtype(
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, subtreesTag))
@@ -614,17 +597,17 @@ class Certificate(object):
for pos, name in enumerate(subtrees.split(',')):
generalName = rfc2459.GeneralName()
if '/' in name:
directoryName = stringToDN(name,
tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
generalName.setComponentByName('directoryName', directoryName)
else:
generalName.setComponentByName('dNSName', name)
- generalSubtree = GeneralSubtree()
+ generalSubtree = rfc2459.GeneralSubtree()
generalSubtree.setComponentByName('base', generalName)
generalSubtrees.setComponentByPosition(pos, generalSubtree)
nameConstraints.setComponentByName(subtreesType, generalSubtrees)
self.addExtension(rfc2459.id_ce_nameConstraints, nameConstraints, critical)
def addNSCertType(self, certType, critical):
if certType != 'sslServer':
raise UnknownNSCertTypeError(certType)
--- a/security/manager/ssl/tests/unit/pycms.py
+++ b/security/manager/ssl/tests/unit/pycms.py
@@ -108,17 +108,19 @@ class CMS(object):
if pykeyHash == pykey.HASH_SHA1:
oidString = '1.3.14.3.2.26'
elif pykeyHash == pykey.HASH_SHA256:
oidString = '2.16.840.1.101.3.4.2.1'
else:
raise pykey.UnknownHashAlgorithmError(pykeyHash)
algorithmIdentifier = rfc2459.AlgorithmIdentifier()
algorithmIdentifier['algorithm'] = univ.ObjectIdentifier(oidString)
- algorithmIdentifier['parameters'] = univ.Null()
+ # Directly setting parameters to univ.Null doesn't currently work.
+ nullEncapsulated = encoder.encode(univ.Null())
+ algorithmIdentifier['parameters'] = univ.Any(nullEncapsulated)
return algorithmIdentifier
def buildSignerInfo(self, certificate, pykeyHash, digestValue):
"""Given a pyasn1 certificate, a pykey hash identifier
and a hash value, creates a SignerInfo with the
appropriate values."""
signerInfo = rfc2315.SignerInfo()
signerInfo['version'] = 1
--- a/security/manager/ssl/tests/unit/pykey.py
+++ b/security/manager/ssl/tests/unit/pykey.py
@@ -533,17 +533,19 @@ class RSAKey(object):
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())
+ # Directly setting parameters to univ.Null doesn't currently work.
+ nullEncapsulated = encoder.encode(univ.Null())
+ algorithmIdentifier['parameters'] = univ.Any(nullEncapsulated)
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)
@@ -564,17 +566,19 @@ class RSAKey(object):
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())
+ # Directly setting parameters to univ.Null doesn't currently work.
+ nullEncapsulated = encoder.encode(univ.Null())
+ algorithmIdentifier['parameters'] = univ.Any(nullEncapsulated)
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
--- a/security/manager/ssl/tests/unit/requirements.txt
+++ b/security/manager/ssl/tests/unit/requirements.txt
@@ -1,6 +1,6 @@
lxml
-pyasn1 == 0.1.7
-pyasn1_modules == 0.0.5
+pyasn1 == 0.3.7
+pyasn1_modules == 0.1.5
ecc
mock
rsa