358 lines
8.3 KiB
Python
358 lines
8.3 KiB
Python
# This file is being contributed to pyasn1-modules software.
|
|
#
|
|
# Created by Russ Housley with assistance from the asn1ate tool.
|
|
#
|
|
# Copyright (c) 2019, Vigil Security, LLC
|
|
# License: http://snmplabs.com/pyasn1/license.html
|
|
#
|
|
# PKCS #12: Personal Information Exchange Syntax v1.1
|
|
#
|
|
# ASN.1 source from:
|
|
# https://www.rfc-editor.org/rfc/rfc7292.txt
|
|
# https://www.rfc-editor.org/errata_search.php?rfc=7292
|
|
|
|
from pyasn1.type import char
|
|
from pyasn1.type import constraint
|
|
from pyasn1.type import namedtype
|
|
from pyasn1.type import namedval
|
|
from pyasn1.type import opentype
|
|
from pyasn1.type import tag
|
|
from pyasn1.type import univ
|
|
|
|
from pyasn1_modules import rfc2315
|
|
from pyasn1_modules import rfc5652
|
|
from pyasn1_modules import rfc5280
|
|
from pyasn1_modules import rfc5958
|
|
|
|
|
|
def _OID(*components):
|
|
output = []
|
|
for x in tuple(components):
|
|
if isinstance(x, univ.ObjectIdentifier):
|
|
output.extend(list(x))
|
|
else:
|
|
output.append(int(x))
|
|
|
|
return univ.ObjectIdentifier(output)
|
|
|
|
|
|
# Initialize the maps used in PKCS#12
|
|
|
|
pkcs12BagTypeMap = { }
|
|
|
|
pkcs12CertBagMap = { }
|
|
|
|
pkcs12CRLBagMap = { }
|
|
|
|
pkcs12SecretBagMap = { }
|
|
|
|
|
|
# Imports from RFC 2315, RFC 5652, and RFC 5958
|
|
|
|
DigestInfo = rfc2315.DigestInfo
|
|
|
|
|
|
ContentInfo = rfc5652.ContentInfo
|
|
|
|
PKCS12Attribute = rfc5652.Attribute
|
|
|
|
|
|
EncryptedPrivateKeyInfo = rfc5958.EncryptedPrivateKeyInfo
|
|
|
|
PrivateKeyInfo = rfc5958.PrivateKeyInfo
|
|
|
|
|
|
# CMSSingleAttribute is the same as Attribute in RFC 5652 except the attrValues
|
|
# SET must have one and only one member
|
|
|
|
class AttributeType(univ.ObjectIdentifier):
|
|
pass
|
|
|
|
|
|
class AttributeValue(univ.Any):
|
|
pass
|
|
|
|
|
|
class AttributeValues(univ.SetOf):
|
|
pass
|
|
|
|
AttributeValues.componentType = AttributeValue()
|
|
|
|
|
|
class CMSSingleAttribute(univ.Sequence):
|
|
pass
|
|
|
|
CMSSingleAttribute.componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('attrType', AttributeType()),
|
|
namedtype.NamedType('attrValues',
|
|
AttributeValues().subtype(sizeSpec=constraint.ValueSizeConstraint(1, 1)),
|
|
openType=opentype.OpenType('attrType', rfc5652.cmsAttributesMap)
|
|
)
|
|
)
|
|
|
|
|
|
# Object identifier arcs
|
|
|
|
rsadsi = _OID(1, 2, 840, 113549)
|
|
|
|
pkcs = _OID(rsadsi, 1)
|
|
|
|
pkcs_9 = _OID(pkcs, 9)
|
|
|
|
certTypes = _OID(pkcs_9, 22)
|
|
|
|
crlTypes = _OID(pkcs_9, 23)
|
|
|
|
pkcs_12 = _OID(pkcs, 12)
|
|
|
|
|
|
# PBE Algorithm Identifiers and Parameters Structure
|
|
|
|
pkcs_12PbeIds = _OID(pkcs_12, 1)
|
|
|
|
pbeWithSHAAnd128BitRC4 = _OID(pkcs_12PbeIds, 1)
|
|
|
|
pbeWithSHAAnd40BitRC4 = _OID(pkcs_12PbeIds, 2)
|
|
|
|
pbeWithSHAAnd3_KeyTripleDES_CBC = _OID(pkcs_12PbeIds, 3)
|
|
|
|
pbeWithSHAAnd2_KeyTripleDES_CBC = _OID(pkcs_12PbeIds, 4)
|
|
|
|
pbeWithSHAAnd128BitRC2_CBC = _OID(pkcs_12PbeIds, 5)
|
|
|
|
pbeWithSHAAnd40BitRC2_CBC = _OID(pkcs_12PbeIds, 6)
|
|
|
|
|
|
class Pkcs_12PbeParams(univ.Sequence):
|
|
pass
|
|
|
|
Pkcs_12PbeParams.componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('salt', univ.OctetString()),
|
|
namedtype.NamedType('iterations', univ.Integer())
|
|
)
|
|
|
|
|
|
# Bag types
|
|
|
|
bagtypes = _OID(pkcs_12, 10, 1)
|
|
|
|
class BAG_TYPE(univ.Sequence):
|
|
pass
|
|
|
|
BAG_TYPE.componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('id', univ.ObjectIdentifier()),
|
|
namedtype.NamedType('unnamed1', univ.Any(),
|
|
openType=opentype.OpenType('attrType', pkcs12BagTypeMap)
|
|
)
|
|
)
|
|
|
|
|
|
id_keyBag = _OID(bagtypes, 1)
|
|
|
|
class KeyBag(PrivateKeyInfo):
|
|
pass
|
|
|
|
|
|
id_pkcs8ShroudedKeyBag = _OID(bagtypes, 2)
|
|
|
|
class PKCS8ShroudedKeyBag(EncryptedPrivateKeyInfo):
|
|
pass
|
|
|
|
|
|
id_certBag = _OID(bagtypes, 3)
|
|
|
|
class CertBag(univ.Sequence):
|
|
pass
|
|
|
|
CertBag.componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('certId', univ.ObjectIdentifier()),
|
|
namedtype.NamedType('certValue',
|
|
univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)),
|
|
openType=opentype.OpenType('certId', pkcs12CertBagMap)
|
|
)
|
|
)
|
|
|
|
|
|
x509Certificate = CertBag()
|
|
x509Certificate['certId'] = _OID(certTypes, 1)
|
|
x509Certificate['certValue'] = univ.OctetString()
|
|
# DER-encoded X.509 certificate stored in OCTET STRING
|
|
|
|
|
|
sdsiCertificate = CertBag()
|
|
sdsiCertificate['certId'] = _OID(certTypes, 2)
|
|
sdsiCertificate['certValue'] = char.IA5String()
|
|
# Base64-encoded SDSI certificate stored in IA5String
|
|
|
|
|
|
id_CRLBag = _OID(bagtypes, 4)
|
|
|
|
class CRLBag(univ.Sequence):
|
|
pass
|
|
|
|
CRLBag.componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('crlId', univ.ObjectIdentifier()),
|
|
namedtype.NamedType('crlValue',
|
|
univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)),
|
|
openType=opentype.OpenType('crlId', pkcs12CRLBagMap)
|
|
)
|
|
)
|
|
|
|
|
|
x509CRL = CRLBag()
|
|
x509CRL['crlId'] = _OID(crlTypes, 1)
|
|
x509CRL['crlValue'] = univ.OctetString()
|
|
# DER-encoded X.509 CRL stored in OCTET STRING
|
|
|
|
|
|
id_secretBag = _OID(bagtypes, 5)
|
|
|
|
class SecretBag(univ.Sequence):
|
|
pass
|
|
|
|
SecretBag.componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('secretTypeId', univ.ObjectIdentifier()),
|
|
namedtype.NamedType('secretValue',
|
|
univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)),
|
|
openType=opentype.OpenType('secretTypeId', pkcs12SecretBagMap)
|
|
)
|
|
)
|
|
|
|
|
|
id_safeContentsBag = _OID(bagtypes, 6)
|
|
|
|
class SafeBag(univ.Sequence):
|
|
pass
|
|
|
|
SafeBag.componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('bagId', univ.ObjectIdentifier()),
|
|
namedtype.NamedType('bagValue',
|
|
univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)),
|
|
openType=opentype.OpenType('bagId', pkcs12BagTypeMap)
|
|
),
|
|
namedtype.OptionalNamedType('bagAttributes',
|
|
univ.SetOf(componentType=PKCS12Attribute())
|
|
)
|
|
)
|
|
|
|
|
|
class SafeContents(univ.SequenceOf):
|
|
pass
|
|
|
|
SafeContents.componentType = SafeBag()
|
|
|
|
|
|
# The PFX PDU
|
|
|
|
class AuthenticatedSafe(univ.SequenceOf):
|
|
pass
|
|
|
|
AuthenticatedSafe.componentType = ContentInfo()
|
|
# Data if unencrypted
|
|
# EncryptedData if password-encrypted
|
|
# EnvelopedData if public key-encrypted
|
|
|
|
|
|
class MacData(univ.Sequence):
|
|
pass
|
|
|
|
MacData.componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('mac', DigestInfo()),
|
|
namedtype.NamedType('macSalt', univ.OctetString()),
|
|
namedtype.DefaultedNamedType('iterations', univ.Integer().subtype(value=1))
|
|
# Note: The default is for historical reasons and its use is deprecated
|
|
)
|
|
|
|
|
|
class PFX(univ.Sequence):
|
|
pass
|
|
|
|
PFX.componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('version',
|
|
univ.Integer(namedValues=namedval.NamedValues(('v3', 3)))
|
|
),
|
|
namedtype.NamedType('authSafe', ContentInfo()),
|
|
namedtype.OptionalNamedType('macData', MacData())
|
|
)
|
|
|
|
|
|
# Local key identifier (also defined as certificateAttribute in rfc2985.py)
|
|
|
|
pkcs_9_at_localKeyId = _OID(pkcs_9, 21)
|
|
|
|
localKeyId = CMSSingleAttribute()
|
|
localKeyId['attrType'] = pkcs_9_at_localKeyId
|
|
localKeyId['attrValues'][0] = univ.OctetString()
|
|
|
|
|
|
# Friendly name (also defined as certificateAttribute in rfc2985.py)
|
|
|
|
pkcs_9_ub_pkcs9String = univ.Integer(255)
|
|
|
|
pkcs_9_ub_friendlyName = univ.Integer(pkcs_9_ub_pkcs9String)
|
|
|
|
pkcs_9_at_friendlyName = _OID(pkcs_9, 20)
|
|
|
|
class FriendlyName(char.BMPString):
|
|
pass
|
|
|
|
FriendlyName.subtypeSpec = constraint.ValueSizeConstraint(1, pkcs_9_ub_friendlyName)
|
|
|
|
|
|
friendlyName = CMSSingleAttribute()
|
|
friendlyName['attrType'] = pkcs_9_at_friendlyName
|
|
friendlyName['attrValues'][0] = FriendlyName()
|
|
|
|
|
|
# Update the PKCS#12 maps
|
|
|
|
_pkcs12BagTypeMap = {
|
|
id_keyBag: KeyBag(),
|
|
id_pkcs8ShroudedKeyBag: PKCS8ShroudedKeyBag(),
|
|
id_certBag: CertBag(),
|
|
id_CRLBag: CRLBag(),
|
|
id_secretBag: SecretBag(),
|
|
id_safeContentsBag: SafeBag(),
|
|
}
|
|
|
|
pkcs12BagTypeMap.update(_pkcs12BagTypeMap)
|
|
|
|
|
|
_pkcs12CertBagMap = {
|
|
_OID(certTypes, 1): univ.OctetString(),
|
|
_OID(certTypes, 2): char.IA5String(),
|
|
}
|
|
|
|
pkcs12CertBagMap.update(_pkcs12CertBagMap)
|
|
|
|
|
|
_pkcs12CRLBagMap = {
|
|
_OID(crlTypes, 1): univ.OctetString(),
|
|
}
|
|
|
|
pkcs12CRLBagMap.update(_pkcs12CRLBagMap)
|
|
|
|
|
|
# Update the Algorithm Identifier map
|
|
|
|
_algorithmIdentifierMapUpdate = {
|
|
pbeWithSHAAnd128BitRC4: Pkcs_12PbeParams(),
|
|
pbeWithSHAAnd40BitRC4: Pkcs_12PbeParams(),
|
|
pbeWithSHAAnd3_KeyTripleDES_CBC: Pkcs_12PbeParams(),
|
|
pbeWithSHAAnd2_KeyTripleDES_CBC: Pkcs_12PbeParams(),
|
|
pbeWithSHAAnd128BitRC2_CBC: Pkcs_12PbeParams(),
|
|
pbeWithSHAAnd40BitRC2_CBC: Pkcs_12PbeParams(),
|
|
}
|
|
|
|
rfc5280.algorithmIdentifierMap.update(_algorithmIdentifierMapUpdate)
|
|
|
|
|
|
# Update the CMS Attribute map
|
|
|
|
_cmsAttributesMapUpdate = {
|
|
pkcs_9_at_friendlyName: FriendlyName(),
|
|
pkcs_9_at_localKeyId: univ.OctetString(),
|
|
}
|
|
|
|
rfc5652.cmsAttributesMap.update(_cmsAttributesMapUpdate)
|