diff options
author | Haibo Huang <hhb@google.com> | 2019-08-01 16:40:06 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-08-01 16:40:06 -0700 |
commit | d4a3294049f5208a79c3d81873ed4572fae3adf1 (patch) | |
tree | 74ccc78f47c0f5e49729ef26516e4d524ff02833 | |
parent | 8868d1936b657c11c6f412c164ec5d7103c32995 (diff) | |
parent | 019c5a7506a1b8027c4626157dc75424973f5b7b (diff) | |
download | pyasn1-modules-d4a3294049f5208a79c3d81873ed4572fae3adf1.tar.gz |
Upgrade python/pyasn1-modules to v0.2.6ndk-sysroot-r21
am: 019c5a7506
Change-Id: I5e4a12d6ee1c6f34df1c1008ad0ba1824d1a57cf
87 files changed, 5006 insertions, 373 deletions
diff --git a/.travis.yml b/.travis.yml index e5f325f..07294be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,12 +8,13 @@ matrix: - os: linux dist: trusty python: '2.7' - - os: linux - dist: trusty - python: '3.2' - - os: linux - dist: trusty - python: '3.3' +# unit test runner fails on tests import +# - os: linux +# dist: trusty +# python: '3.2' +# - os: linux +# dist: trusty +# python: '3.3' - os: linux dist: trusty python: '3.4' diff --git a/CHANGES.txt b/CHANGES.txt index 46d9389..fd564f8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,47 @@ +Revision 0.2.6, released 31-07-2019 +----------------------------------- + +- Added RFC3560 providing RSAES-OAEP Key Transport Algorithm + in CMS +- Added RFC6019 providing BinaryTime - an alternate format + for representing Date and Time +- RFC3565 superseded by RFC5649 +- Added RFC5480 providng Elliptic Curve Cryptography Subject + Public Key Information +- Added RFC8520 providing X.509 Extensions for MUD URL and + MUD Signer +- Added RFC3161 providing Time-Stamp Protocol support +- Added RFC3709 providing Logotypes in X.509 Certificates +- Added RFC3274 providing CMS Compressed Data Content Type +- Added RFC4073 providing Multiple Contents protection with CMS +- Added RFC2634 providing Enhanced Security Services for S/MIME +- Added RFC5915 providing Elliptic Curve Private Key +- Added RFC5940 providing CMS Revocation Information Choices +- Added RFC7296 providing IKEv2 Certificate Bundle +- Added RFC8619 providing HKDF Algorithm Identifiers +- Added RFC7191 providing CMS Key Package Receipt and Error Content + Types +- Added openType support for ORAddress Extension Attributes and + Algorithm Identifiers in the RFC5280 module +- Added RFC5035 providing Update to Enhanced Security Services for + S/MIME +- Added openType support for CMS Content Types and CMS Attributes + in the RFC5652 module +- Added openType support to RFC 2986 by importing definitions from + the RFC 5280 module so that the same maps are used. +- Added maps for use with openType to RFC 2634, RFC 3274, RFC 3709, + RFC 3779, RFC 4055, RFC 4073, RFC 4108, RFC 5035, RFC 5083, RFC 5480, + RFC 5940, RFC 5958, RFC 6010, RFC 6019, RFC 6402, RFC 7191, RFC 8226, + and RFC 8520 +- Changed `ValueSizeConstraint` erroneously applied to `SequenceOf` + and `SetOf` objects via `subtypeConstraint` attribute to be applied + via `sizeSpec` attribute. Although `sizeSpec` takes the same constraint + objects as `subtypeConstraint`, the former is only verified on + de/serialization i.e. when the [constructed] object at hand is fully + populated, while the latter is applied to [scalar] types at the moment + of instantiation. + Revision 0.2.5, released 24-04-2019 ----------------------------------- @@ -9,10 +9,10 @@ third_party { type: GIT value: "https://github.com/etingof/pyasn1-modules" } - version: "v0.2.5" + version: "v0.2.6" last_upgrade_date { year: 2019 - month: 5 - day: 2 + month: 8 + day: 1 } } @@ -7,9 +7,10 @@ ASN.1 modules for Python [![Coverage Status](https://img.shields.io/codecov/c/github/etingof/pyasn1-modules.svg)](https://codecov.io/github/etingof/pyasn1-modules/) [![GitHub license](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/etingof/pyasn1-modules/master/LICENSE.txt) -This is a small but growing collection of +The `pyasn1-modules` package contains a collection of [ASN.1](https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.208-198811-W!!PDF-E&type=items) -data structures expressed in Python terms using [pyasn1](https://github.com/etingof/pyasn1) data model. +data structures expressed as Python classes based on [pyasn1](https://github.com/etingof/pyasn1) +data model. If ASN.1 module you need is not present in this collection, try using [Asn1ate](https://github.com/kimgr/asn1ate) tool that compiles ASN.1 documents @@ -18,13 +19,11 @@ into pyasn1 code. Feedback -------- -If something does not work as expected, try browsing pyasn1 -[mailing list archives](https://sourceforge.net/p/pyasn1/mailman/pyasn1-users/) -or post your question -[to Stack Overflow](https://stackoverflow.com/questions/ask). -If you want to contribute ASN.1 modules you have converted into pyasn1, -please send me a pull request. +If something does not work as expected, +[open an issue](https://github.com/etingof/pyasn1-modules/issues) at GitHub +or post your question [on Stack Overflow](https://stackoverflow.com/questions/ask) + +New modules contributions are welcome via GitHub pull requests. Copyright (c) 2005-2019, [Ilya Etingof](mailto:etingof@gmail.com). All rights reserved. - diff --git a/pyasn1_modules/__init__.py b/pyasn1_modules/__init__.py index 47d7956..7bb503a 100644 --- a/pyasn1_modules/__init__.py +++ b/pyasn1_modules/__init__.py @@ -1,2 +1,2 @@ # http://www.python.org/dev/peps/pep-0396/ -__version__ = '0.2.5' +__version__ = '0.2.6' diff --git a/pyasn1_modules/rfc1905.py b/pyasn1_modules/rfc1905.py index 567e818..72c44ed 100644 --- a/pyasn1_modules/rfc1905.py +++ b/pyasn1_modules/rfc1905.py @@ -42,7 +42,7 @@ class VarBind(univ.Sequence): class VarBindList(univ.SequenceOf): componentType = VarBind() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint( + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint( 0, max_bindings ) diff --git a/pyasn1_modules/rfc2315.py b/pyasn1_modules/rfc2315.py index 932c984..a98c9a9 100644 --- a/pyasn1_modules/rfc2315.py +++ b/pyasn1_modules/rfc2315.py @@ -269,13 +269,13 @@ class DigestInfo(univ.Sequence): class SignedData(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('version', Version()), - namedtype.NamedType('digestAlgorithms', DigestAlgorithmIdentifiers()), + namedtype.OptionalNamedType('digestAlgorithms', DigestAlgorithmIdentifiers()), namedtype.NamedType('contentInfo', ContentInfo()), namedtype.OptionalNamedType('certificates', ExtendedCertificatesAndCertificates().subtype( implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), namedtype.OptionalNamedType('crls', CertificateRevocationLists().subtype( implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), - namedtype.NamedType('signerInfos', SignerInfos()) + namedtype.OptionalNamedType('signerInfos', SignerInfos()) ) diff --git a/pyasn1_modules/rfc2459.py b/pyasn1_modules/rfc2459.py index 071e5da..2a2e696 100644 --- a/pyasn1_modules/rfc2459.py +++ b/pyasn1_modules/rfc2459.py @@ -354,7 +354,7 @@ class TeletexDomainDefinedAttribute(univ.Sequence): class TeletexDomainDefinedAttributes(univ.SequenceOf): componentType = TeletexDomainDefinedAttribute() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) terminal_type = univ.Integer(23) @@ -545,7 +545,7 @@ teletex_organizational_unit_names = univ.Integer(5) class TeletexOrganizationalUnitNames(univ.SequenceOf): componentType = TeletexOrganizationalUnitName() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, ub_organizational_units) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, ub_organizational_units) teletex_personal_name = univ.Integer(4) @@ -601,7 +601,7 @@ class ExtensionAttribute(univ.Sequence): class ExtensionAttributes(univ.SetOf): componentType = ExtensionAttribute() - subtypeSpec = univ.SetOf.subtypeSpec + constraint.ValueSizeConstraint(1, ub_extension_attributes) + sizeSpec = univ.SetOf.sizeSpec + constraint.ValueSizeConstraint(1, ub_extension_attributes) class BuiltInDomainDefinedAttribute(univ.Sequence): @@ -615,16 +615,16 @@ class BuiltInDomainDefinedAttribute(univ.Sequence): class BuiltInDomainDefinedAttributes(univ.SequenceOf): componentType = BuiltInDomainDefinedAttribute() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) class OrganizationalUnitName(char.PrintableString): - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, ub_organizational_unit_name_length) + subtypeSpec = char.PrintableString.subtypeSpec + constraint.ValueSizeConstraint(1, ub_organizational_unit_name_length) class OrganizationalUnitNames(univ.SequenceOf): componentType = OrganizationalUnitName() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, ub_organizational_units) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, ub_organizational_units) class PersonalName(univ.Set): @@ -771,7 +771,7 @@ id_ce_cRLNumber = univ.ObjectIdentifier('2.5.29.20') class CRLNumber(univ.Integer): - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(0, MAX) + subtypeSpec = univ.Integer.subtypeSpec + constraint.ValueSizeConstraint(0, MAX) class BaseCRLNumber(CRLNumber): @@ -796,7 +796,7 @@ class KeyPurposeId(univ.ObjectIdentifier): class ExtKeyUsageSyntax(univ.SequenceOf): componentType = KeyPurposeId() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) class ReasonFlags(univ.BitString): @@ -925,7 +925,7 @@ class PolicyInformation(univ.Sequence): class CertificatePolicies(univ.SequenceOf): componentType = PolicyInformation() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) id_ce_policyMappings = univ.ObjectIdentifier('2.5.29.33') @@ -940,7 +940,7 @@ class PolicyMapping(univ.Sequence): class PolicyMappings(univ.SequenceOf): componentType = PolicyMapping() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) id_ce_privateKeyUsagePeriod = univ.ObjectIdentifier('2.5.29.16') @@ -1024,7 +1024,7 @@ class Attribute(univ.Sequence): class SubjectDirectoryAttributes(univ.SequenceOf): componentType = Attribute() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) class RelativeDistinguishedName(univ.SetOf): @@ -1077,7 +1077,7 @@ class GeneralName(univ.Choice): class GeneralNames(univ.SequenceOf): componentType = GeneralName() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) class AccessDescription(univ.Sequence): @@ -1089,7 +1089,7 @@ class AccessDescription(univ.Sequence): class AuthorityInfoAccessSyntax(univ.SequenceOf): componentType = AccessDescription() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) class AuthorityKeyIdentifier(univ.Sequence): @@ -1125,7 +1125,7 @@ class DistributionPoint(univ.Sequence): class CRLDistPointsSyntax(univ.SequenceOf): componentType = DistributionPoint() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) class IssuingDistributionPoint(univ.Sequence): @@ -1155,7 +1155,7 @@ class GeneralSubtree(univ.Sequence): class GeneralSubtrees(univ.SequenceOf): componentType = GeneralSubtree() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) class NameConstraints(univ.Sequence): diff --git a/pyasn1_modules/rfc2511.py b/pyasn1_modules/rfc2511.py index 6b3c37c..5dd6fc2 100644 --- a/pyasn1_modules/rfc2511.py +++ b/pyasn1_modules/rfc2511.py @@ -109,7 +109,7 @@ class PKIPublicationInfo(univ.Sequence): namedtype.NamedType('action', univ.Integer(namedValues=namedval.NamedValues(('dontPublish', 0), ('pleasePublish', 1)))), namedtype.OptionalNamedType('pubInfos', univ.SequenceOf(componentType=SinglePubInfo()).subtype( - subtypeSpec=constraint.ValueSizeConstraint(1, MAX))) + sizeSpec=constraint.ValueSizeConstraint(1, MAX))) ) @@ -195,7 +195,7 @@ class ProofOfPossession(univ.Choice): class Controls(univ.SequenceOf): componentType = AttributeTypeAndValue() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) class OptionalValidity(univ.Sequence): @@ -249,10 +249,10 @@ class CertReqMsg(univ.Sequence): namedtype.NamedType('certReq', CertRequest()), namedtype.OptionalNamedType('pop', ProofOfPossession()), namedtype.OptionalNamedType('regInfo', univ.SequenceOf(componentType=AttributeTypeAndValue()).subtype( - subtypeSpec=constraint.ValueSizeConstraint(1, MAX))) + sizeSpec=constraint.ValueSizeConstraint(1, MAX))) ) class CertReqMessages(univ.SequenceOf): componentType = CertReqMsg() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) diff --git a/pyasn1_modules/rfc2634.py b/pyasn1_modules/rfc2634.py new file mode 100644 index 0000000..4b4e5bb --- /dev/null +++ b/pyasn1_modules/rfc2634.py @@ -0,0 +1,331 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# Modified by Russ Housley to add a map for use with opentypes. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Enhanced Security Services for S/MIME +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc2634.txt +# + +from pyasn1.type import char +from pyasn1.type import constraint +from pyasn1.type import namedval +from pyasn1.type import namedtype +from pyasn1.type import tag +from pyasn1.type import univ +from pyasn1.type import useful + +from pyasn1_modules import rfc5652 +from pyasn1_modules import rfc5280 + +MAX = float('inf') + +ContentType = rfc5652.ContentType + +IssuerAndSerialNumber = rfc5652.IssuerAndSerialNumber + +SubjectKeyIdentifier = rfc5652.SubjectKeyIdentifier + +PolicyInformation = rfc5280.PolicyInformation + +GeneralNames = rfc5280.GeneralNames + +CertificateSerialNumber = rfc5280.CertificateSerialNumber + + +# Signing Certificate Attribute +# Warning: It is better to use SigningCertificateV2 from RFC 5035 + +id_aa_signingCertificate = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.12') + +class Hash(univ.OctetString): + pass # SHA-1 hash of entire certificate; RFC 5035 supports other hash algorithms + + +class IssuerSerial(univ.Sequence): + pass + +IssuerSerial.componentType = namedtype.NamedTypes( + namedtype.NamedType('issuer', GeneralNames()), + namedtype.NamedType('serialNumber', CertificateSerialNumber()) +) + + +class ESSCertID(univ.Sequence): + pass + +ESSCertID.componentType = namedtype.NamedTypes( + namedtype.NamedType('certHash', Hash()), + namedtype.OptionalNamedType('issuerSerial', IssuerSerial()) +) + + +class SigningCertificate(univ.Sequence): + pass + +SigningCertificate.componentType = namedtype.NamedTypes( + namedtype.NamedType('certs', univ.SequenceOf( + componentType=ESSCertID())), + namedtype.OptionalNamedType('policies', univ.SequenceOf( + componentType=PolicyInformation())) +) + + +# Mail List Expansion History Attribute + +id_aa_mlExpandHistory = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.3') + +ub_ml_expansion_history = univ.Integer(64) + + +class EntityIdentifier(univ.Choice): + pass + +EntityIdentifier.componentType = namedtype.NamedTypes( + namedtype.NamedType('issuerAndSerialNumber', IssuerAndSerialNumber()), + namedtype.NamedType('subjectKeyIdentifier', SubjectKeyIdentifier()) +) + + +class MLReceiptPolicy(univ.Choice): + pass + +MLReceiptPolicy.componentType = namedtype.NamedTypes( + namedtype.NamedType('none', univ.Null().subtype(implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('insteadOf', univ.SequenceOf( + componentType=GeneralNames()).subtype( + sizeSpec=constraint.ValueSizeConstraint(1, MAX)).subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), + namedtype.NamedType('inAdditionTo', univ.SequenceOf( + componentType=GeneralNames()).subtype( + sizeSpec=constraint.ValueSizeConstraint(1, MAX)).subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) +) + + +class MLData(univ.Sequence): + pass + +MLData.componentType = namedtype.NamedTypes( + namedtype.NamedType('mailListIdentifier', EntityIdentifier()), + namedtype.NamedType('expansionTime', useful.GeneralizedTime()), + namedtype.OptionalNamedType('mlReceiptPolicy', MLReceiptPolicy()) +) + +class MLExpansionHistory(univ.SequenceOf): + pass + +MLExpansionHistory.componentType = MLData() +MLExpansionHistory.sizeSpec = constraint.ValueSizeConstraint(1, ub_ml_expansion_history) + + +# ESS Security Label Attribute + +id_aa_securityLabel = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.2') + +ub_privacy_mark_length = univ.Integer(128) + +ub_security_categories = univ.Integer(64) + +ub_integer_options = univ.Integer(256) + + +class ESSPrivacyMark(univ.Choice): + pass + +ESSPrivacyMark.componentType = namedtype.NamedTypes( + namedtype.NamedType('pString', char.PrintableString().subtype( + subtypeSpec=constraint.ValueSizeConstraint(1, ub_privacy_mark_length))), + namedtype.NamedType('utf8String', char.UTF8String().subtype( + subtypeSpec=constraint.ValueSizeConstraint(1, MAX))) +) + + +class SecurityClassification(univ.Integer): + pass + +SecurityClassification.subtypeSpec=constraint.ValueRangeConstraint(0, ub_integer_options) + +SecurityClassification.namedValues = namedval.NamedValues( + ('unmarked', 0), + ('unclassified', 1), + ('restricted', 2), + ('confidential', 3), + ('secret', 4), + ('top-secret', 5) +) + + +class SecurityPolicyIdentifier(univ.ObjectIdentifier): + pass + + +class SecurityCategory(univ.Sequence): + pass + +SecurityCategory.componentType = namedtype.NamedTypes( + namedtype.NamedType('type', univ.ObjectIdentifier().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('value', univ.Any().subtype(implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 1))) +) + + +class SecurityCategories(univ.SetOf): + pass + +SecurityCategories.componentType = SecurityCategory() +SecurityCategories.sizeSpec = constraint.ValueSizeConstraint(1, ub_security_categories) + + +class ESSSecurityLabel(univ.Set): + pass + +ESSSecurityLabel.componentType = namedtype.NamedTypes( + namedtype.NamedType('security-policy-identifier', SecurityPolicyIdentifier()), + namedtype.OptionalNamedType('security-classification', SecurityClassification()), + namedtype.OptionalNamedType('privacy-mark', ESSPrivacyMark()), + namedtype.OptionalNamedType('security-categories', SecurityCategories()) +) + + +# Equivalent Labels Attribute + +id_aa_equivalentLabels = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.9') + +class EquivalentLabels(univ.SequenceOf): + pass + +EquivalentLabels.componentType = ESSSecurityLabel() + + +# Content Identifier Attribute + +id_aa_contentIdentifier = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.7') + +class ContentIdentifier(univ.OctetString): + pass + + +# Content Reference Attribute + +id_aa_contentReference = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.10') + +class ContentReference(univ.Sequence): + pass + +ContentReference.componentType = namedtype.NamedTypes( + namedtype.NamedType('contentType', ContentType()), + namedtype.NamedType('signedContentIdentifier', ContentIdentifier()), + namedtype.NamedType('originatorSignatureValue', univ.OctetString()) +) + + +# Message Signature Digest Attribute + +id_aa_msgSigDigest = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.5') + +class MsgSigDigest(univ.OctetString): + pass + + +# Content Hints Attribute + +id_aa_contentHint = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.4') + +class ContentHints(univ.Sequence): + pass + +ContentHints.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('contentDescription', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), + namedtype.NamedType('contentType', ContentType()) +) + + +# Receipt Request Attribute + +class AllOrFirstTier(univ.Integer): + pass + +AllOrFirstTier.namedValues = namedval.NamedValues( + ('allReceipts', 0), + ('firstTierRecipients', 1) +) + + +class ReceiptsFrom(univ.Choice): + pass + +ReceiptsFrom.componentType = namedtype.NamedTypes( + namedtype.NamedType('allOrFirstTier', AllOrFirstTier().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('receiptList', univ.SequenceOf( + componentType=GeneralNames()).subtype(implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 1))) +) + + +id_aa_receiptRequest = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.1') + +ub_receiptsTo = univ.Integer(16) + +class ReceiptRequest(univ.Sequence): + pass + +ReceiptRequest.componentType = namedtype.NamedTypes( + namedtype.NamedType('signedContentIdentifier', ContentIdentifier()), + namedtype.NamedType('receiptsFrom', ReceiptsFrom()), + namedtype.NamedType('receiptsTo', univ.SequenceOf(componentType=GeneralNames()).subtype(sizeSpec=constraint.ValueSizeConstraint(1, ub_receiptsTo))) +) + +# Receipt Content Type + +class ESSVersion(univ.Integer): + pass + +ESSVersion.namedValues = namedval.NamedValues( + ('v1', 1) +) + + +id_ct_receipt = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.1') + +class Receipt(univ.Sequence): + pass + +Receipt.componentType = namedtype.NamedTypes( + namedtype.NamedType('version', ESSVersion()), + namedtype.NamedType('contentType', ContentType()), + namedtype.NamedType('signedContentIdentifier', ContentIdentifier()), + namedtype.NamedType('originatorSignatureValue', univ.OctetString()) +) + + +# Map of Attribute Type to the Attribute structure + +ESSAttributeMap = { + id_aa_signingCertificate: SigningCertificate(), + id_aa_mlExpandHistory: MLExpansionHistory(), + id_aa_securityLabel: ESSSecurityLabel(), + id_aa_equivalentLabels: EquivalentLabels(), + id_aa_contentIdentifier: ContentIdentifier(), + id_aa_contentReference: ContentReference(), + id_aa_msgSigDigest: MsgSigDigest(), + id_aa_contentHint: ContentHints(), + id_aa_receiptRequest: ReceiptRequest(), +} + + +# Map of Content Type OIDs to Content Types +# To be added to the ones that are in rfc5652.py + +cmsContentTypesMapUpdate = { + id_ct_receipt: Receipt(), +}
\ No newline at end of file diff --git a/pyasn1_modules/rfc2986.py b/pyasn1_modules/rfc2986.py index 014f2cb..34acbd5 100644 --- a/pyasn1_modules/rfc2986.py +++ b/pyasn1_modules/rfc2986.py @@ -3,54 +3,43 @@ # This file is part of pyasn1-modules software. # # Created by Joel Johnson with asn1ate tool. +# Modified by Russ Housley to add support for opentypes by importing +# definitions from rfc5280 so that the same maps are used. +# # Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com> # License: http://snmplabs.com/pyasn1/license.html # # PKCS #10: Certification Request Syntax Specification # # ASN.1 source from: -# http://www.ietf.org/rfc/rfc2986.txt +# https://www.rfc-editor.org/rfc/rfc2986.txt # -from pyasn1.type import univ -from pyasn1.type import char from pyasn1.type import namedtype -from pyasn1.type import namedval -from pyasn1.type import opentype from pyasn1.type import tag -from pyasn1.type import constraint -from pyasn1.type import useful +from pyasn1.type import univ + +from pyasn1_modules import rfc5280 MAX = float('inf') -class AttributeType(univ.ObjectIdentifier): - pass +AttributeType = rfc5280.AttributeType +AttributeValue = rfc5280.AttributeValue -class AttributeValue(univ.Any): - pass +AttributeTypeAndValue = rfc5280.AttributeTypeAndValue +Attribute = rfc5280.Attribute -certificateAttributesMap = {} +RelativeDistinguishedName = rfc5280.RelativeDistinguishedName +RDNSequence = rfc5280.RDNSequence -class AttributeTypeAndValue(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('type', AttributeType()), - namedtype.NamedType( - 'value', AttributeValue(), - openType=opentype.OpenType('type', certificateAttributesMap) - ) - ) +Name = rfc5280.Name +AlgorithmIdentifier = rfc5280.AlgorithmIdentifier -class Attribute(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('type', AttributeType()), - namedtype.NamedType('values', - univ.SetOf(componentType=AttributeValue()), - openType=opentype.OpenType('type', certificateAttributesMap)) - ) +SubjectPublicKeyInfo = rfc5280.SubjectPublicKeyInfo class Attributes(univ.SetOf): @@ -60,47 +49,6 @@ class Attributes(univ.SetOf): Attributes.componentType = Attribute() -class RelativeDistinguishedName(univ.SetOf): - pass - - -RelativeDistinguishedName.componentType = AttributeTypeAndValue() -RelativeDistinguishedName.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) - - -class RDNSequence(univ.SequenceOf): - pass - - -RDNSequence.componentType = RelativeDistinguishedName() - - -class Name(univ.Choice): - pass - - -Name.componentType = namedtype.NamedTypes( - namedtype.NamedType('rdnSequence', RDNSequence()) -) - - -class AlgorithmIdentifier(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('algorithm', univ.ObjectIdentifier()), - namedtype.OptionalNamedType('parameters', univ.Any()) - ) - - -class SubjectPublicKeyInfo(univ.Sequence): - pass - - -SubjectPublicKeyInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('algorithm', AlgorithmIdentifier()), - namedtype.NamedType('subjectPublicKey', univ.BitString()) -) - - class CertificationRequestInfo(univ.Sequence): pass @@ -109,7 +57,10 @@ CertificationRequestInfo.componentType = namedtype.NamedTypes( namedtype.NamedType('version', univ.Integer()), namedtype.NamedType('subject', Name()), namedtype.NamedType('subjectPKInfo', SubjectPublicKeyInfo()), - namedtype.NamedType('attributes', Attributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) + namedtype.NamedType('attributes', + Attributes().subtype(implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 0)) + ) ) diff --git a/pyasn1_modules/rfc3161.py b/pyasn1_modules/rfc3161.py new file mode 100644 index 0000000..0e1dced --- /dev/null +++ b/pyasn1_modules/rfc3161.py @@ -0,0 +1,142 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Time-Stamp Protocol (TSP) +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc3161.txt +# + +from pyasn1.type import constraint +from pyasn1.type import namedtype +from pyasn1.type import namedval +from pyasn1.type import tag +from pyasn1.type import univ +from pyasn1.type import useful + +from pyasn1_modules import rfc4210 +from pyasn1_modules import rfc5280 +from pyasn1_modules import rfc5652 + + +Extensions = rfc5280.Extensions + +AlgorithmIdentifier = rfc5280.AlgorithmIdentifier + +GeneralName = rfc5280.GeneralName + +ContentInfo = rfc5652.ContentInfo + +PKIFreeText = rfc4210.PKIFreeText + + +id_ct_TSTInfo = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.4') + + +class Accuracy(univ.Sequence): + pass + +Accuracy.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('seconds', univ.Integer()), + namedtype.OptionalNamedType('millis', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(1, 999)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.OptionalNamedType('micros', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(1, 999)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) +) + + +class MessageImprint(univ.Sequence): + pass + +MessageImprint.componentType = namedtype.NamedTypes( + namedtype.NamedType('hashAlgorithm', AlgorithmIdentifier()), + namedtype.NamedType('hashedMessage', univ.OctetString()) +) + + +class PKIFailureInfo(univ.BitString): + pass + +PKIFailureInfo.namedValues = namedval.NamedValues( + ('badAlg', 0), + ('badRequest', 2), + ('badDataFormat', 5), + ('timeNotAvailable', 14), + ('unacceptedPolicy', 15), + ('unacceptedExtension', 16), + ('addInfoNotAvailable', 17), + ('systemFailure', 25) +) + + +class PKIStatus(univ.Integer): + pass + +PKIStatus.namedValues = namedval.NamedValues( + ('granted', 0), + ('grantedWithMods', 1), + ('rejection', 2), + ('waiting', 3), + ('revocationWarning', 4), + ('revocationNotification', 5) +) + + +class PKIStatusInfo(univ.Sequence): + pass + +PKIStatusInfo.componentType = namedtype.NamedTypes( + namedtype.NamedType('status', PKIStatus()), + namedtype.OptionalNamedType('statusString', PKIFreeText()), + namedtype.OptionalNamedType('failInfo', PKIFailureInfo()) +) + + +class TSAPolicyId(univ.ObjectIdentifier): + pass + + +class TSTInfo(univ.Sequence): + pass + +TSTInfo.componentType = namedtype.NamedTypes( + namedtype.NamedType('version', univ.Integer(namedValues=namedval.NamedValues(('v1', 1)))), + namedtype.NamedType('policy', TSAPolicyId()), + namedtype.NamedType('messageImprint', MessageImprint()), + namedtype.NamedType('serialNumber', univ.Integer()), + namedtype.NamedType('genTime', useful.GeneralizedTime()), + namedtype.OptionalNamedType('accuracy', Accuracy()), + namedtype.DefaultedNamedType('ordering', univ.Boolean().subtype(value=0)), + namedtype.OptionalNamedType('nonce', univ.Integer()), + namedtype.OptionalNamedType('tsa', GeneralName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.OptionalNamedType('extensions', Extensions().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) +) + + +class TimeStampReq(univ.Sequence): + pass + +TimeStampReq.componentType = namedtype.NamedTypes( + namedtype.NamedType('version', univ.Integer(namedValues=namedval.NamedValues(('v1', 1)))), + namedtype.NamedType('messageImprint', MessageImprint()), + namedtype.OptionalNamedType('reqPolicy', TSAPolicyId()), + namedtype.OptionalNamedType('nonce', univ.Integer()), + namedtype.DefaultedNamedType('certReq', univ.Boolean().subtype(value=0)), + namedtype.OptionalNamedType('extensions', Extensions().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) +) + + +class TimeStampToken(ContentInfo): + pass + + +class TimeStampResp(univ.Sequence): + pass + +TimeStampResp.componentType = namedtype.NamedTypes( + namedtype.NamedType('status', PKIStatusInfo()), + namedtype.OptionalNamedType('timeStampToken', TimeStampToken()) +) diff --git a/pyasn1_modules/rfc3274.py b/pyasn1_modules/rfc3274.py new file mode 100644 index 0000000..8d8541c --- /dev/null +++ b/pyasn1_modules/rfc3274.py @@ -0,0 +1,57 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# Modified by Russ Housley to add a map for use with opentypes. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# CMS Compressed Data Content Type +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc3274.txt +# + +from pyasn1.type import namedtype +from pyasn1.type import univ + +from pyasn1_modules import rfc5280 +from pyasn1_modules import rfc5652 + + +class CompressionAlgorithmIdentifier(rfc5280.AlgorithmIdentifier): + pass + + +# The CMS Compressed Data Content Type + +id_ct_compressedData = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.9') + +class CompressedData(univ.Sequence): + pass + +CompressedData.componentType = namedtype.NamedTypes( + namedtype.NamedType('version', rfc5652.CMSVersion()), # Always set to 0 + namedtype.NamedType('compressionAlgorithm', CompressionAlgorithmIdentifier()), + namedtype.NamedType('encapContentInfo', rfc5652.EncapsulatedContentInfo()) +) + + +# Algorithm identifier for the zLib Compression Algorithm +# This includes cpa_zlibCompress as defined in RFC 6268, +# from https://www.rfc-editor.org/rfc/rfc6268.txt + +id_alg_zlibCompress = univ.ObjectIdentifier('1.2.840.113549.1.9.16.3.8') + +cpa_zlibCompress = rfc5280.AlgorithmIdentifier() +cpa_zlibCompress['algorithm'] = id_alg_zlibCompress +# cpa_zlibCompress['parameters'] are absent + + +# Map of Content Type OIDs to Content Types +# To be added to the ones that are in rfc5652.py + +cmsContentTypesMapUpdate = { + id_ct_compressedData: CompressedData(), +}
\ No newline at end of file diff --git a/pyasn1_modules/rfc3280.py b/pyasn1_modules/rfc3280.py index 6c45b8f..e9dbc86 100644 --- a/pyasn1_modules/rfc3280.py +++ b/pyasn1_modules/rfc3280.py @@ -53,7 +53,7 @@ class OrganizationalUnitNames(univ.SequenceOf): OrganizationalUnitNames.componentType = OrganizationalUnitName() -OrganizationalUnitNames.subtypeSpec = constraint.ValueSizeConstraint(1, ub_organizational_units) +OrganizationalUnitNames.sizeSpec = constraint.ValueSizeConstraint(1, ub_organizational_units) class AttributeType(univ.ObjectIdentifier): @@ -152,7 +152,7 @@ class Extensions(univ.SequenceOf): Extensions.componentType = Extension() -Extensions.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +Extensions.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class CertificateSerialNumber(univ.Integer): @@ -219,7 +219,7 @@ class RelativeDistinguishedName(univ.SetOf): RelativeDistinguishedName.componentType = AttributeTypeAndValue() -RelativeDistinguishedName.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +RelativeDistinguishedName.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class RDNSequence(univ.SequenceOf): @@ -519,7 +519,7 @@ class BuiltInDomainDefinedAttributes(univ.SequenceOf): BuiltInDomainDefinedAttributes.componentType = BuiltInDomainDefinedAttribute() -BuiltInDomainDefinedAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) +BuiltInDomainDefinedAttributes.sizeSpec = constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) ub_extension_attributes = univ.Integer(256) @@ -542,7 +542,7 @@ class ExtensionAttributes(univ.SetOf): ExtensionAttributes.componentType = ExtensionAttribute() -ExtensionAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, ub_extension_attributes) +ExtensionAttributes.sizeSpec = constraint.ValueSizeConstraint(1, ub_extension_attributes) class ORAddress(univ.Sequence): @@ -706,7 +706,7 @@ class TeletexDomainDefinedAttributes(univ.SequenceOf): TeletexDomainDefinedAttributes.componentType = TeletexDomainDefinedAttribute() -TeletexDomainDefinedAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) +TeletexDomainDefinedAttributes.sizeSpec = constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) class TBSCertList(univ.Sequence): @@ -905,7 +905,7 @@ class TeletexOrganizationalUnitNames(univ.SequenceOf): TeletexOrganizationalUnitNames.componentType = TeletexOrganizationalUnitName() -TeletexOrganizationalUnitNames.subtypeSpec = constraint.ValueSizeConstraint(1, ub_organizational_units) +TeletexOrganizationalUnitNames.sizeSpec = constraint.ValueSizeConstraint(1, ub_organizational_units) physical_delivery_office_name = univ.Integer(10) @@ -1077,7 +1077,7 @@ class GeneralNames(univ.SequenceOf): GeneralNames.componentType = GeneralName() -GeneralNames.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +GeneralNames.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class IssuerAltName(GeneralNames): @@ -1100,7 +1100,7 @@ PolicyMappings.componentType = univ.Sequence(componentType=namedtype.NamedTypes( namedtype.NamedType('subjectDomainPolicy', CertPolicyId()) )) -PolicyMappings.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +PolicyMappings.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class PolicyQualifierId(univ.ObjectIdentifier): @@ -1119,7 +1119,7 @@ class SubjectDirectoryAttributes(univ.SequenceOf): SubjectDirectoryAttributes.componentType = Attribute() -SubjectDirectoryAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +SubjectDirectoryAttributes.sizeSpec = constraint.ValueSizeConstraint(1, MAX) anyPolicy = _OID(id_ce_certificatePolicies, 0) @@ -1198,7 +1198,7 @@ class CertificatePolicies(univ.SequenceOf): CertificatePolicies.componentType = PolicyInformation() -CertificatePolicies.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +CertificatePolicies.sizeSpec = constraint.ValueSizeConstraint(1, MAX) id_ce_basicConstraints = _OID(id_ce, 19) @@ -1216,7 +1216,7 @@ class ExtKeyUsageSyntax(univ.SequenceOf): ExtKeyUsageSyntax.componentType = KeyPurposeId() -ExtKeyUsageSyntax.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +ExtKeyUsageSyntax.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class SubjectAltName(GeneralNames): @@ -1287,7 +1287,7 @@ class CRLDistributionPoints(univ.SequenceOf): CRLDistributionPoints.componentType = DistributionPoint() -CRLDistributionPoints.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +CRLDistributionPoints.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class FreshestCRL(CRLDistributionPoints): @@ -1340,7 +1340,7 @@ class GeneralSubtrees(univ.SequenceOf): GeneralSubtrees.componentType = GeneralSubtree() -GeneralSubtrees.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +GeneralSubtrees.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class NameConstraints(univ.Sequence): @@ -1389,7 +1389,7 @@ class AuthorityInfoAccessSyntax(univ.SequenceOf): AuthorityInfoAccessSyntax.componentType = AccessDescription() -AuthorityInfoAccessSyntax.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +AuthorityInfoAccessSyntax.sizeSpec = constraint.ValueSizeConstraint(1, MAX) id_ce_issuingDistributionPoint = _OID(id_ce, 28) @@ -1458,7 +1458,7 @@ class SubjectInfoAccessSyntax(univ.SequenceOf): SubjectInfoAccessSyntax.componentType = AccessDescription() -SubjectInfoAccessSyntax.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +SubjectInfoAccessSyntax.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class KeyUsage(univ.BitString): diff --git a/pyasn1_modules/rfc3447.py b/pyasn1_modules/rfc3447.py index a5499fe..c3621a0 100644 --- a/pyasn1_modules/rfc3447.py +++ b/pyasn1_modules/rfc3447.py @@ -27,7 +27,7 @@ class OtherPrimeInfo(univ.Sequence): class OtherPrimeInfos(univ.SequenceOf): componentType = OtherPrimeInfo() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) class RSAPrivateKey(univ.Sequence): diff --git a/pyasn1_modules/rfc3560.py b/pyasn1_modules/rfc3560.py new file mode 100644 index 0000000..8365436 --- /dev/null +++ b/pyasn1_modules/rfc3560.py @@ -0,0 +1,74 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# RSAES-OAEP Key Transport Algorithm in CMS +# +# Notice that all of the things needed in RFC 3560 are also defined +# in RFC 4055. So, they are all pulled from the RFC 4055 module into +# this one so that people looking a RFC 3560 can easily find them. +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc3560.txt +# + +from pyasn1_modules import rfc4055 + +id_sha1 = rfc4055.id_sha1 + +id_sha256 = rfc4055.id_sha256 + +id_sha384 = rfc4055.id_sha384 + +id_sha512 = rfc4055.id_sha512 + +id_mgf1 = rfc4055.id_mgf1 + +rsaEncryption = rfc4055.rsaEncryption + +id_RSAES_OAEP = rfc4055.id_RSAES_OAEP + +id_pSpecified = rfc4055.id_pSpecified + +sha1Identifier = rfc4055.sha1Identifier + +sha256Identifier = rfc4055.sha256Identifier + +sha384Identifier = rfc4055.sha384Identifier + +sha512Identifier = rfc4055.sha512Identifier + +mgf1SHA1Identifier = rfc4055.mgf1SHA1Identifier + +mgf1SHA256Identifier = rfc4055.mgf1SHA256Identifier + +mgf1SHA384Identifier = rfc4055.mgf1SHA384Identifier + +mgf1SHA512Identifier = rfc4055.mgf1SHA512Identifier + +pSpecifiedEmptyIdentifier = rfc4055.pSpecifiedEmptyIdentifier + + +class RSAES_OAEP_params(rfc4055.RSAES_OAEP_params): + pass + + +rSAES_OAEP_Default_Params = RSAES_OAEP_params() + +rSAES_OAEP_Default_Identifier = rfc4055.rSAES_OAEP_Default_Identifier + +rSAES_OAEP_SHA256_Params = rfc4055.rSAES_OAEP_SHA256_Params + +rSAES_OAEP_SHA256_Identifier = rfc4055.rSAES_OAEP_SHA256_Identifier + +rSAES_OAEP_SHA384_Params = rfc4055.rSAES_OAEP_SHA384_Params + +rSAES_OAEP_SHA384_Identifier = rfc4055.rSAES_OAEP_SHA384_Identifier + +rSAES_OAEP_SHA512_Params = rfc4055.rSAES_OAEP_SHA512_Params + +rSAES_OAEP_SHA512_Identifier = rfc4055.rSAES_OAEP_SHA512_Identifier diff --git a/pyasn1_modules/rfc3565.py b/pyasn1_modules/rfc3565.py index 0833480..c4b742d 100644 --- a/pyasn1_modules/rfc3565.py +++ b/pyasn1_modules/rfc3565.py @@ -1,18 +1,14 @@ -# This file is being contributed to pyasn1-modules software. -# -# Created by Russ Housley. -# # Copyright (c) 2019, Vigil Security, LLC # License: http://snmplabs.com/pyasn1/license.html # -# Use of the Elliptic Curve Diffie-Hellman Key Agreement Algorithm -# with X25519 and X448 in the Cryptographic Message Syntax (CMS) +# Use of the Advanced Encryption Standard (AES) Encryption +# Algorithm in the Cryptographic Message Syntax (CMS) # # ASN.1 source from: # https://www.rfc-editor.org/rfc/rfc3565.txt - -from pyasn1.type import univ, constraint +from pyasn1.type import constraint +from pyasn1.type import univ from pyasn1_modules import rfc5280 @@ -24,8 +20,8 @@ class AlgorithmIdentifier(rfc5280.AlgorithmIdentifier): class AES_IV(univ.OctetString): pass -AES_IV.subtypeSpec = constraint.ValueSizeConstraint(16, 16) +AES_IV.subtypeSpec = constraint.ValueSizeConstraint(16, 16) id_aes128_CBC = univ.ObjectIdentifier('2.16.840.1.101.3.4.1.2') @@ -33,7 +29,6 @@ id_aes192_CBC = univ.ObjectIdentifier('2.16.840.1.101.3.4.1.22') id_aes256_CBC = univ.ObjectIdentifier('2.16.840.1.101.3.4.1.42') - id_aes128_wrap = univ.ObjectIdentifier('2.16.840.1.101.3.4.1.5') id_aes192_wrap = univ.ObjectIdentifier('2.16.840.1.101.3.4.1.25') diff --git a/pyasn1_modules/rfc3709.py b/pyasn1_modules/rfc3709.py new file mode 100644 index 0000000..a52f99e --- /dev/null +++ b/pyasn1_modules/rfc3709.py @@ -0,0 +1,202 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# Modified by Russ Housley to add maps for use with opentypes. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Logotypes in X.509 Certificates +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc3709.txt +# + +from pyasn1.type import char +from pyasn1.type import constraint +from pyasn1.type import namedtype +from pyasn1.type import namedval +from pyasn1.type import tag +from pyasn1.type import univ + +from pyasn1_modules import rfc5280 + +MAX = float('inf') + + +class HashAlgAndValue(univ.Sequence): + pass + +HashAlgAndValue.componentType = namedtype.NamedTypes( + namedtype.NamedType('hashAlg', rfc5280.AlgorithmIdentifier()), + namedtype.NamedType('hashValue', univ.OctetString()) +) + + +class LogotypeDetails(univ.Sequence): + pass + +LogotypeDetails.componentType = namedtype.NamedTypes( + namedtype.NamedType('mediaType', char.IA5String()), + namedtype.NamedType('logotypeHash', univ.SequenceOf( + componentType=HashAlgAndValue()).subtype( + sizeSpec=constraint.ValueSizeConstraint(1, MAX))), + namedtype.NamedType('logotypeURI', univ.SequenceOf( + componentType=char.IA5String()).subtype( + sizeSpec=constraint.ValueSizeConstraint(1, MAX))) +) + + +class LogotypeAudioInfo(univ.Sequence): + pass + +LogotypeAudioInfo.componentType = namedtype.NamedTypes( + namedtype.NamedType('fileSize', univ.Integer()), + namedtype.NamedType('playTime', univ.Integer()), + namedtype.NamedType('channels', univ.Integer()), + namedtype.OptionalNamedType('sampleRate', univ.Integer().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), + namedtype.OptionalNamedType('language', char.IA5String().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))) +) + + +class LogotypeAudio(univ.Sequence): + pass + +LogotypeAudio.componentType = namedtype.NamedTypes( + namedtype.NamedType('audioDetails', LogotypeDetails()), + namedtype.OptionalNamedType('audioInfo', LogotypeAudioInfo()) +) + + +class LogotypeImageType(univ.Integer): + pass + +LogotypeImageType.namedValues = namedval.NamedValues( + ('grayScale', 0), + ('color', 1) +) + + +class LogotypeImageResolution(univ.Choice): + pass + +LogotypeImageResolution.componentType = namedtype.NamedTypes( + namedtype.NamedType('numBits', + univ.Integer().subtype(implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 1))), + namedtype.NamedType('tableSize', + univ.Integer().subtype(implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 2))) +) + + +class LogotypeImageInfo(univ.Sequence): + pass + +LogotypeImageInfo.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('type', LogotypeImageType().subtype( + implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0)).subtype(value='color')), + namedtype.NamedType('fileSize', univ.Integer()), + namedtype.NamedType('xSize', univ.Integer()), + namedtype.NamedType('ySize', univ.Integer()), + namedtype.OptionalNamedType('resolution', LogotypeImageResolution()), + namedtype.OptionalNamedType('language', char.IA5String().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))) +) + + +class LogotypeImage(univ.Sequence): + pass + +LogotypeImage.componentType = namedtype.NamedTypes( + namedtype.NamedType('imageDetails', LogotypeDetails()), + namedtype.OptionalNamedType('imageInfo', LogotypeImageInfo()) +) + + +class LogotypeData(univ.Sequence): + pass + +LogotypeData.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('image', univ.SequenceOf( + componentType=LogotypeImage())), + namedtype.OptionalNamedType('audio', univ.SequenceOf( + componentType=LogotypeAudio()).subtype( + implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 1))) +) + + +class LogotypeReference(univ.Sequence): + pass + +LogotypeReference.componentType = namedtype.NamedTypes( + namedtype.NamedType('refStructHash', univ.SequenceOf( + componentType=HashAlgAndValue()).subtype( + sizeSpec=constraint.ValueSizeConstraint(1, MAX))), + namedtype.NamedType('refStructURI', univ.SequenceOf( + componentType=char.IA5String()).subtype( + sizeSpec=constraint.ValueSizeConstraint(1, MAX))) +) + + +class LogotypeInfo(univ.Choice): + pass + +LogotypeInfo.componentType = namedtype.NamedTypes( + namedtype.NamedType('direct', + LogotypeData().subtype(implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 0))), + namedtype.NamedType('indirect', LogotypeReference().subtype( + implicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 1))) +) + +# Other logotype type and associated object identifiers + +id_logo_background = univ.ObjectIdentifier('1.3.6.1.5.5.7.20.2') + +id_logo_loyalty = univ.ObjectIdentifier('1.3.6.1.5.5.7.20.1') + + +class OtherLogotypeInfo(univ.Sequence): + pass + +OtherLogotypeInfo.componentType = namedtype.NamedTypes( + namedtype.NamedType('logotypeType', univ.ObjectIdentifier()), + namedtype.NamedType('info', LogotypeInfo()) +) + + +# Logotype Certificate Extension + +id_pe_logotype = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.12') + + +class LogotypeExtn(univ.Sequence): + pass + +LogotypeExtn.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('communityLogos', univ.SequenceOf( + componentType=LogotypeInfo()).subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.OptionalNamedType('issuerLogo', LogotypeInfo().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), + namedtype.OptionalNamedType('subjectLogo', LogotypeInfo().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), + namedtype.OptionalNamedType('otherLogos', univ.SequenceOf( + componentType=OtherLogotypeInfo()).subtype(explicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatSimple, 3))) +) + + +# Map of Certificate Extension OIDs to Extensions +# To be added to the ones that are in rfc5280.py + +certificateExtensionsMapUpdate = { + id_pe_logotype: LogotypeExtn(), +} diff --git a/pyasn1_modules/rfc3779.py b/pyasn1_modules/rfc3779.py index aaf856e..125351e 100644 --- a/pyasn1_modules/rfc3779.py +++ b/pyasn1_modules/rfc3779.py @@ -2,6 +2,7 @@ # This file is part of pyasn1-modules software. # # Created by Russ Housley with assistance from asn1ate v.0.6.0. +# Modified by Russ Housley to add maps for use with opentypes. # # Copyright (c) 2019, Vigil Security, LLC # License: http://snmplabs.com/pyasn1/license.html @@ -12,8 +13,10 @@ # https://www.rfc-editor.org/rfc/rfc3779.txt # - -from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful +from pyasn1.type import constraint +from pyasn1.type import namedtype +from pyasn1.type import tag +from pyasn1.type import univ # IP Address Delegation Extension @@ -48,7 +51,9 @@ class IPAddressChoice(univ.Choice): IPAddressChoice.componentType = namedtype.NamedTypes( namedtype.NamedType('inherit', univ.Null()), - namedtype.NamedType('addressesOrRanges', univ.SequenceOf(componentType=IPAddressOrRange())) + namedtype.NamedType('addressesOrRanges', univ.SequenceOf( + componentType=IPAddressOrRange()) + ) ) @@ -56,7 +61,8 @@ class IPAddressFamily(univ.Sequence): pass IPAddressFamily.componentType = namedtype.NamedTypes( - namedtype.NamedType('addressFamily', univ.OctetString().subtype(subtypeSpec=constraint.ValueSizeConstraint(2, 3))), + namedtype.NamedType('addressFamily', univ.OctetString().subtype( + subtypeSpec=constraint.ValueSizeConstraint(2, 3))), namedtype.NamedType('ipAddressChoice', IPAddressChoice()) ) @@ -99,7 +105,9 @@ class ASIdentifierChoice(univ.Choice): ASIdentifierChoice.componentType = namedtype.NamedTypes( namedtype.NamedType('inherit', univ.Null()), - namedtype.NamedType('asIdsOrRanges', univ.SequenceOf(componentType=ASIdOrRange())) + namedtype.NamedType('asIdsOrRanges', univ.SequenceOf( + componentType=ASIdOrRange()) + ) ) @@ -107,6 +115,19 @@ class ASIdentifiers(univ.Sequence): pass ASIdentifiers.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('asnum', ASIdentifierChoice().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('rdi', ASIdentifierChoice().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) + namedtype.OptionalNamedType('asnum', ASIdentifierChoice().subtype( + explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 0))), + namedtype.OptionalNamedType('rdi', ASIdentifierChoice().subtype( + explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 1))) ) + + +# Map of Certificate Extension OIDs to Extensions +# To be added to the ones that are in rfc5280.py + +certificateExtensionsMapUpdate = { + id_pe_ipAddrBlocks: IPAddrBlocks(), + id_pe_autonomousSysIds: ASIdentifiers(), +} diff --git a/pyasn1_modules/rfc3852.py b/pyasn1_modules/rfc3852.py index 7c8f6c6..d294c5b 100644 --- a/pyasn1_modules/rfc3852.py +++ b/pyasn1_modules/rfc3852.py @@ -54,7 +54,7 @@ class SignedAttributes(univ.SetOf): SignedAttributes.componentType = Attribute() -SignedAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +SignedAttributes.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class OtherRevocationInfoFormat(univ.Sequence): @@ -309,7 +309,7 @@ class RecipientInfos(univ.SetOf): RecipientInfos.componentType = RecipientInfo() -RecipientInfos.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +RecipientInfos.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class DigestAlgorithmIdentifier(rfc3280.AlgorithmIdentifier): @@ -336,7 +336,7 @@ class UnprotectedAttributes(univ.SetOf): UnprotectedAttributes.componentType = Attribute() -UnprotectedAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +UnprotectedAttributes.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class ContentType(univ.ObjectIdentifier): @@ -430,7 +430,7 @@ class UnauthAttributes(univ.SetOf): UnauthAttributes.componentType = Attribute() -UnauthAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +UnauthAttributes.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class ExtendedCertificateInfo(univ.Sequence): @@ -550,7 +550,7 @@ class UnsignedAttributes(univ.SetOf): UnsignedAttributes.componentType = Attribute() -UnsignedAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +UnsignedAttributes.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class SignatureValue(univ.OctetString): @@ -632,7 +632,7 @@ class AuthAttributes(univ.SetOf): AuthAttributes.componentType = Attribute() -AuthAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +AuthAttributes.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class AuthenticatedData(univ.Sequence): diff --git a/pyasn1_modules/rfc4055.py b/pyasn1_modules/rfc4055.py index 02820e7..bdc1286 100644 --- a/pyasn1_modules/rfc4055.py +++ b/pyasn1_modules/rfc4055.py @@ -3,6 +3,7 @@ # # Created by Russ Housley with a very small amount of assistance from # asn1ate v.0.6.0. +# Modified by Russ Housley to add maps for opentypes. # # Copyright (c) 2019, Vigil Security, LLC # License: http://snmplabs.com/pyasn1/license.html @@ -13,8 +14,10 @@ # ASN.1 source from: # https://www.rfc-editor.org/rfc/rfc4055.txt # +from pyasn1.type import namedtype +from pyasn1.type import tag +from pyasn1.type import univ -from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful from pyasn1_modules import rfc5280 @@ -30,96 +33,72 @@ def _OID(*components): id_sha1 = _OID(1, 3, 14, 3, 2, 26) - id_sha256 = _OID(2, 16, 840, 1, 101, 3, 4, 2, 1) - id_sha384 = _OID(2, 16, 840, 1, 101, 3, 4, 2, 2) - id_sha512 = _OID(2, 16, 840, 1, 101, 3, 4, 2, 3) - id_sha224 = _OID(2, 16, 840, 1, 101, 3, 4, 2, 4) - rsaEncryption = _OID(1, 2, 840, 113549, 1, 1, 1) - id_mgf1 = _OID(1, 2, 840, 113549, 1, 1, 8) - id_RSAES_OAEP = _OID(1, 2, 840, 113549, 1, 1, 7) - id_pSpecified = _OID(1, 2, 840, 113549, 1, 1, 9) - id_RSASSA_PSS = _OID(1, 2, 840, 113549, 1, 1, 10) - sha256WithRSAEncryption = _OID(1, 2, 840, 113549, 1, 1, 11) - sha384WithRSAEncryption = _OID(1, 2, 840, 113549, 1, 1, 12) - sha512WithRSAEncryption = _OID(1, 2, 840, 113549, 1, 1, 13) - sha224WithRSAEncryption = _OID(1, 2, 840, 113549, 1, 1, 14) - sha1Identifier = rfc5280.AlgorithmIdentifier() sha1Identifier['algorithm'] = id_sha1 sha1Identifier['parameters'] = univ.Null("") - sha224Identifier = rfc5280.AlgorithmIdentifier() sha224Identifier['algorithm'] = id_sha224 sha224Identifier['parameters'] = univ.Null("") - sha256Identifier = rfc5280.AlgorithmIdentifier() sha256Identifier['algorithm'] = id_sha256 sha256Identifier['parameters'] = univ.Null("") - sha384Identifier = rfc5280.AlgorithmIdentifier() sha384Identifier['algorithm'] = id_sha384 sha384Identifier['parameters'] = univ.Null("") - sha512Identifier = rfc5280.AlgorithmIdentifier() sha512Identifier['algorithm'] = id_sha512 sha512Identifier['parameters'] = univ.Null("") - mgf1SHA1Identifier = rfc5280.AlgorithmIdentifier() mgf1SHA1Identifier['algorithm'] = id_mgf1 mgf1SHA1Identifier['parameters'] = sha1Identifier - mgf1SHA224Identifier = rfc5280.AlgorithmIdentifier() mgf1SHA224Identifier['algorithm'] = id_mgf1 mgf1SHA224Identifier['parameters'] = sha224Identifier - mgf1SHA256Identifier = rfc5280.AlgorithmIdentifier() mgf1SHA256Identifier['algorithm'] = id_mgf1 mgf1SHA256Identifier['parameters'] = sha256Identifier - mgf1SHA384Identifier = rfc5280.AlgorithmIdentifier() mgf1SHA384Identifier['algorithm'] = id_mgf1 mgf1SHA384Identifier['parameters'] = sha384Identifier - mgf1SHA512Identifier = rfc5280.AlgorithmIdentifier() mgf1SHA512Identifier['algorithm'] = id_mgf1 mgf1SHA512Identifier['parameters'] = sha512Identifier - pSpecifiedEmptyIdentifier = rfc5280.AlgorithmIdentifier() pSpecifiedEmptyIdentifier['algorithm'] = id_pSpecified pSpecifiedEmptyIdentifier['parameters'] = univ.OctetString(value='') @@ -146,49 +125,55 @@ class RSAES_OAEP_params(univ.Sequence): pass RSAES_OAEP_params.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('hashFunc', rfc5280.AlgorithmIdentifier().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('maskGenFunc', rfc5280.AlgorithmIdentifier().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), - namedtype.OptionalNamedType('pSourceFunc', rfc5280.AlgorithmIdentifier().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))) + namedtype.OptionalNamedType('hashFunc', rfc5280.AlgorithmIdentifier().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), + namedtype.OptionalNamedType('maskGenFunc', rfc5280.AlgorithmIdentifier().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), + namedtype.OptionalNamedType('pSourceFunc', rfc5280.AlgorithmIdentifier().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))) ) - rSAES_OAEP_Default_Params = RSAES_OAEP_params() rSAES_OAEP_Default_Identifier = rfc5280.AlgorithmIdentifier() rSAES_OAEP_Default_Identifier['algorithm'] = id_RSAES_OAEP rSAES_OAEP_Default_Identifier['parameters'] = rSAES_OAEP_Default_Params - rSAES_OAEP_SHA224_Params = RSAES_OAEP_params() -rSAES_OAEP_SHA224_Params['hashFunc'] = sha224Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) -rSAES_OAEP_SHA224_Params['maskGenFunc'] = mgf1SHA224Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) +rSAES_OAEP_SHA224_Params['hashFunc'] = sha224Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) +rSAES_OAEP_SHA224_Params['maskGenFunc'] = mgf1SHA224Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) rSAES_OAEP_SHA224_Identifier = rfc5280.AlgorithmIdentifier() rSAES_OAEP_SHA224_Identifier['algorithm'] = id_RSAES_OAEP rSAES_OAEP_SHA224_Identifier['parameters'] = rSAES_OAEP_SHA224_Params - rSAES_OAEP_SHA256_Params = RSAES_OAEP_params() -rSAES_OAEP_SHA256_Params['hashFunc'] = sha256Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) -rSAES_OAEP_SHA256_Params['maskGenFunc'] = mgf1SHA256Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) +rSAES_OAEP_SHA256_Params['hashFunc'] = sha256Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) +rSAES_OAEP_SHA256_Params['maskGenFunc'] = mgf1SHA256Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) rSAES_OAEP_SHA256_Identifier = rfc5280.AlgorithmIdentifier() rSAES_OAEP_SHA256_Identifier['algorithm'] = id_RSAES_OAEP rSAES_OAEP_SHA256_Identifier['parameters'] = rSAES_OAEP_SHA256_Params - rSAES_OAEP_SHA384_Params = RSAES_OAEP_params() -rSAES_OAEP_SHA384_Params['hashFunc'] = sha384Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) -rSAES_OAEP_SHA384_Params['maskGenFunc'] = mgf1SHA384Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) +rSAES_OAEP_SHA384_Params['hashFunc'] = sha384Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) +rSAES_OAEP_SHA384_Params['maskGenFunc'] = mgf1SHA384Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) rSAES_OAEP_SHA384_Identifier = rfc5280.AlgorithmIdentifier() rSAES_OAEP_SHA384_Identifier['algorithm'] = id_RSAES_OAEP rSAES_OAEP_SHA384_Identifier['parameters'] = rSAES_OAEP_SHA384_Params - rSAES_OAEP_SHA512_Params = RSAES_OAEP_params() -rSAES_OAEP_SHA512_Params['hashFunc'] = sha512Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) -rSAES_OAEP_SHA512_Params['maskGenFunc'] = mgf1SHA512Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) +rSAES_OAEP_SHA512_Params['hashFunc'] = sha512Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) +rSAES_OAEP_SHA512_Params['maskGenFunc'] = mgf1SHA512Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) rSAES_OAEP_SHA512_Identifier = rfc5280.AlgorithmIdentifier() rSAES_OAEP_SHA512_Identifier['algorithm'] = id_RSAES_OAEP @@ -199,51 +184,75 @@ class RSASSA_PSS_params(univ.Sequence): pass RSASSA_PSS_params.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('hashAlgorithm', rfc5280.AlgorithmIdentifier().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('maskGenAlgorithm', rfc5280.AlgorithmIdentifier().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), - namedtype.DefaultedNamedType('saltLength', univ.Integer(value=20).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.DefaultedNamedType('trailerField', univ.Integer(value=1).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) + namedtype.OptionalNamedType('hashAlgorithm', rfc5280.AlgorithmIdentifier().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), + namedtype.OptionalNamedType('maskGenAlgorithm', rfc5280.AlgorithmIdentifier().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), + namedtype.DefaultedNamedType('saltLength', univ.Integer(value=20).subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), + namedtype.DefaultedNamedType('trailerField', univ.Integer(value=1).subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) ) - rSASSA_PSS_Default_Params = RSASSA_PSS_params() rSASSA_PSS_Default_Identifier = rfc5280.AlgorithmIdentifier() rSASSA_PSS_Default_Identifier['algorithm'] = id_RSASSA_PSS rSASSA_PSS_Default_Identifier['parameters'] = rSASSA_PSS_Default_Params - rSASSA_PSS_SHA224_Params = RSASSA_PSS_params() -rSASSA_PSS_SHA224_Params['hashAlgorithm'] = sha224Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) -rSASSA_PSS_SHA224_Params['maskGenAlgorithm'] = mgf1SHA224Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) +rSASSA_PSS_SHA224_Params['hashAlgorithm'] = sha224Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) +rSASSA_PSS_SHA224_Params['maskGenAlgorithm'] = mgf1SHA224Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) rSASSA_PSS_SHA224_Identifier = rfc5280.AlgorithmIdentifier() rSASSA_PSS_SHA224_Identifier['algorithm'] = id_RSASSA_PSS rSASSA_PSS_SHA224_Identifier['parameters'] = rSASSA_PSS_SHA224_Params - rSASSA_PSS_SHA256_Params = RSASSA_PSS_params() -rSASSA_PSS_SHA256_Params['hashAlgorithm'] = sha256Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) -rSASSA_PSS_SHA256_Params['maskGenAlgorithm'] = mgf1SHA256Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) +rSASSA_PSS_SHA256_Params['hashAlgorithm'] = sha256Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) +rSASSA_PSS_SHA256_Params['maskGenAlgorithm'] = mgf1SHA256Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) rSASSA_PSS_SHA256_Identifier = rfc5280.AlgorithmIdentifier() rSASSA_PSS_SHA256_Identifier['algorithm'] = id_RSASSA_PSS rSASSA_PSS_SHA256_Identifier['parameters'] = rSASSA_PSS_SHA256_Params - rSASSA_PSS_SHA384_Params = RSASSA_PSS_params() -rSASSA_PSS_SHA384_Params['hashAlgorithm'] = sha384Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) -rSASSA_PSS_SHA384_Params['maskGenAlgorithm'] = mgf1SHA384Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) +rSASSA_PSS_SHA384_Params['hashAlgorithm'] = sha384Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) +rSASSA_PSS_SHA384_Params['maskGenAlgorithm'] = mgf1SHA384Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) rSASSA_PSS_SHA384_Identifier = rfc5280.AlgorithmIdentifier() rSASSA_PSS_SHA384_Identifier['algorithm'] = id_RSASSA_PSS rSASSA_PSS_SHA384_Identifier['parameters'] = rSASSA_PSS_SHA384_Params - rSASSA_PSS_SHA512_Params = RSASSA_PSS_params() -rSASSA_PSS_SHA512_Params['hashAlgorithm'] = sha512Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) -rSASSA_PSS_SHA512_Params['maskGenAlgorithm'] = mgf1SHA512Identifier.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) +rSASSA_PSS_SHA512_Params['hashAlgorithm'] = sha512Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), cloneValueFlag=True) +rSASSA_PSS_SHA512_Params['maskGenAlgorithm'] = mgf1SHA512Identifier.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), cloneValueFlag=True) rSASSA_PSS_SHA512_Identifier = rfc5280.AlgorithmIdentifier() rSASSA_PSS_SHA512_Identifier['algorithm'] = id_RSASSA_PSS rSASSA_PSS_SHA512_Identifier['parameters'] = rSASSA_PSS_SHA512_Params + + +# Update the Algorithm Identifier map + +_algorithmIdentifierMapUpdate = { + id_sha1: univ.Null(), + id_sha224: univ.Null(), + id_sha256: univ.Null(), + id_sha384: univ.Null(), + id_sha512: univ.Null(), + id_mgf1: rfc5280.AlgorithmIdentifier(), + id_pSpecified: univ.OctetString(), + id_RSAES_OAEP: RSAES_OAEP_params(), + id_RSASSA_PSS: RSASSA_PSS_params(), +} + +rfc5280.algorithmIdentifierMap.update(_algorithmIdentifierMapUpdate) diff --git a/pyasn1_modules/rfc4073.py b/pyasn1_modules/rfc4073.py new file mode 100644 index 0000000..12a9ec0 --- /dev/null +++ b/pyasn1_modules/rfc4073.py @@ -0,0 +1,57 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with some assistance from asn1ate v.0.6.0. +# Modified by Russ Housley to add a map for use with opentypes. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Protecting Multiple Contents with the CMS +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc4073.txt +# + +from pyasn1.type import constraint +from pyasn1.type import namedtype +from pyasn1.type import univ + +from pyasn1_modules import rfc5652 + +MAX = float('inf') + + +# Content Collection Content Type and Object Identifier + +id_ct_contentCollection = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.19') + +class ContentCollection(univ.SequenceOf): + pass + +ContentCollection.componentType = rfc5652.ContentInfo() +ContentCollection.sizeSpec = constraint.ValueSizeConstraint(1, MAX) + + +# Content With Attributes Content Type and Object Identifier + +id_ct_contentWithAttrs = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.20') + +class ContentWithAttributes(univ.Sequence): + pass + +ContentWithAttributes.componentType = namedtype.NamedTypes( + namedtype.NamedType('content', rfc5652.ContentInfo()), + namedtype.NamedType('attrs', univ.SequenceOf( + componentType=rfc5652.Attribute()).subtype( + sizeSpec=constraint.ValueSizeConstraint(1, MAX))) +) + + +# Map of Content Type OIDs to Content Types +# To be added to the ones that are in rfc5652.py + +cmsContentTypesMapUpdate = { + id_ct_contentCollection: ContentCollection(), + id_ct_contentWithAttrs: ContentWithAttributes(), +}
\ No newline at end of file diff --git a/pyasn1_modules/rfc4108.py b/pyasn1_modules/rfc4108.py index 9a7f190..c5cdfe9 100644 --- a/pyasn1_modules/rfc4108.py +++ b/pyasn1_modules/rfc4108.py @@ -2,6 +2,8 @@ # This file is part of pyasn1-modules software. # # Created by Russ Housley with assistance from asn1ate v.0.6.0. +# Modified by Russ Housley to add items from the verified errata. +# Modified by Russ Housley to add maps for use with opentypes. # # Copyright (c) 2019, Vigil Security, LLC # License: http://snmplabs.com/pyasn1/license.html @@ -10,11 +12,13 @@ # # ASN.1 source from: # https://www.rfc-editor.org/rfc/rfc4108.txt +# https://www.rfc-editor.org/errata_search.php?rfc=4108 # from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful +from pyasn1_modules import rfc5280 from pyasn1_modules import rfc5652 MAX = float('inf') @@ -137,8 +141,7 @@ class VendorLoadErrorCode(univ.Integer): pass - -# Wrapped Firmware Key Unsigned Attribute and Object Identifiers +# Wrapped Firmware Key Unsigned Attribute and Object Identifier id_aa_wrappedFirmwareKey = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.39') @@ -222,6 +225,19 @@ FirmwarePackageIdentifier.componentType = namedtype.NamedTypes( ) +# Firmware Package Message Digest Signed Attribute and Object Identifier + +id_aa_fwPkgMessageDigest = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.41') + +class FirmwarePackageMessageDigest(univ.Sequence): + pass + +FirmwarePackageMessageDigest.componentType = namedtype.NamedTypes( + namedtype.NamedType('algorithm', rfc5280.AlgorithmIdentifier()), + namedtype.NamedType('msgDigest', univ.OctetString()) +) + + # Firmware Package Load Error Report Content Type and Object Identifier class FWErrorVersion(univ.Integer): @@ -292,3 +308,38 @@ HardwareModuleName.componentType = namedtype.NamedTypes( namedtype.NamedType('hwType', univ.ObjectIdentifier()), namedtype.NamedType('hwSerialNum', univ.OctetString()) ) + + +# Map of Attribute Type OIDs to Attributes +# To be added to the ones that are in rfc5652.py + +cmsAttributesMapUpdate = { + id_aa_wrappedFirmwareKey: WrappedFirmwareKey(), + id_aa_firmwarePackageInfo: FirmwarePackageInfo(), + id_aa_communityIdentifiers: CommunityIdentifiers(), + id_aa_implCompressAlgs: ImplementedCompressAlgorithms(), + id_aa_implCryptoAlgs: ImplementedCryptoAlgorithms(), + id_aa_decryptKeyID: DecryptKeyIdentifier(), + id_aa_targetHardwareIDs: TargetHardwareIdentifiers(), + id_aa_firmwarePackageID: FirmwarePackageIdentifier(), + id_aa_fwPkgMessageDigest: FirmwarePackageMessageDigest(), +} + + +# Map of Content Type OIDs to Content Types +# To be added to the ones that are in rfc5652.py + +cmsContentTypesMapUpdate = { + id_ct_firmwareLoadError: FirmwarePackageLoadError(), + id_ct_firmwareLoadReceipt: FirmwarePackageLoadReceipt(), + id_ct_firmwarePackage: FirmwarePkgData(), +} + + +# Map of Other Name OIDs to Other Name +# To be added to the ones that are in rfc5280.py + +anotherNameMapUpdate = { + id_on_hardwareModuleName: HardwareModuleName(), +} + diff --git a/pyasn1_modules/rfc4210.py b/pyasn1_modules/rfc4210.py index c43fc60..fd3b256 100644 --- a/pyasn1_modules/rfc4210.py +++ b/pyasn1_modules/rfc4210.py @@ -44,7 +44,7 @@ class PKIFreeText(univ.SequenceOf): PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String """ componentType = char.UTF8String() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) class PollRepContent(univ.SequenceOf): @@ -354,16 +354,17 @@ class RevRepContent(univ.Sequence): OPTIONAL """ componentType = namedtype.NamedTypes( - namedtype.NamedType('status', PKIStatusInfo()), + namedtype.NamedType('status', PKIStatusInfo( + sizeSpec=constraint.ValueSizeConstraint(1, MAX))), namedtype.OptionalNamedType( 'revCerts', univ.SequenceOf(componentType=rfc2511.CertId()).subtype( - subtypeSpec=constraint.ValueSizeConstraint(1, MAX), + sizeSpec=constraint.ValueSizeConstraint(1, MAX), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0) ) ), namedtype.OptionalNamedType( 'crls', univ.SequenceOf(componentType=rfc2459.CertificateList()).subtype( - subtypeSpec=constraint.ValueSizeConstraint(1, MAX), + sizeSpec=constraint.ValueSizeConstraint(1, MAX), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1) ) ) @@ -391,12 +392,12 @@ class KeyRecRepContent(univ.Sequence): namedtype.OptionalNamedType( 'caCerts', univ.SequenceOf(componentType=CMPCertificate()).subtype( explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1), - subtypeSpec=constraint.ValueSizeConstraint(1, MAX) + sizeSpec=constraint.ValueSizeConstraint(1, MAX) ) ), namedtype.OptionalNamedType('keyPairHist', univ.SequenceOf(componentType=CertifiedKeyPair()).subtype( explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2), - subtypeSpec=constraint.ValueSizeConstraint(1, MAX)) + sizeSpec=constraint.ValueSizeConstraint(1, MAX)) ) ) @@ -430,7 +431,8 @@ class CertRepMessage(univ.Sequence): namedtype.OptionalNamedType( 'caPubs', univ.SequenceOf( componentType=CMPCertificate() - ).subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)) + ).subtype(sizeSpec=constraint.ValueSizeConstraint(1, MAX), + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)) ), namedtype.NamedType('response', univ.SequenceOf(componentType=CertResponse())) ) @@ -737,7 +739,7 @@ class PKIHeader(univ.Sequence): namedtype.OptionalNamedType('generalInfo', univ.SequenceOf( componentType=InfoTypeAndValue().subtype( - subtypeSpec=constraint.ValueSizeConstraint(1, MAX), + sizeSpec=constraint.ValueSizeConstraint(1, MAX), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8) ) ) @@ -776,7 +778,7 @@ class PKIMessage(univ.Sequence): univ.SequenceOf( componentType=CMPCertificate() ).subtype( - subtypeSpec=constraint.ValueSizeConstraint(1, MAX), + sizeSpec=constraint.ValueSizeConstraint(1, MAX), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1) ) ) @@ -788,7 +790,7 @@ class PKIMessages(univ.SequenceOf): PKIMessages ::= SEQUENCE SIZE (1..MAX) OF PKIMessage """ componentType = PKIMessage() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) + sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) # pyasn1 does not naturally handle recursive definitions, thus this hack: diff --git a/pyasn1_modules/rfc4211.py b/pyasn1_modules/rfc4211.py index cc79261..9783058 100644 --- a/pyasn1_modules/rfc4211.py +++ b/pyasn1_modules/rfc4211.py @@ -282,7 +282,7 @@ class Controls(univ.SequenceOf): Controls.componentType = AttributeTypeAndValue() -Controls.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +Controls.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class CertRequest(univ.Sequence): @@ -312,7 +312,7 @@ class CertReqMessages(univ.SequenceOf): CertReqMessages.componentType = CertReqMsg() -CertReqMessages.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +CertReqMessages.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class CertReq(CertRequest): diff --git a/pyasn1_modules/rfc5035.py b/pyasn1_modules/rfc5035.py new file mode 100644 index 0000000..4a70bb0 --- /dev/null +++ b/pyasn1_modules/rfc5035.py @@ -0,0 +1,198 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# Modified by Russ Housley to add a map for use with opentypes. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Update to Enhanced Security Services for S/MIME +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc5035.txt +# + +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1.type import namedtype +from pyasn1.type import univ + +from pyasn1_modules import rfc2634 +from pyasn1_modules import rfc4055 +from pyasn1_modules import rfc5652 +from pyasn1_modules import rfc5280 + +ContentType = rfc5652.ContentType + +IssuerAndSerialNumber = rfc5652.IssuerAndSerialNumber + +SubjectKeyIdentifier = rfc5652.SubjectKeyIdentifier + +AlgorithmIdentifier = rfc5280.AlgorithmIdentifier + +PolicyInformation = rfc5280.PolicyInformation + +GeneralNames = rfc5280.GeneralNames + +CertificateSerialNumber = rfc5280.CertificateSerialNumber + + +# Signing Certificate Attribute V1 and V2 + +id_aa_signingCertificate = rfc2634.id_aa_signingCertificate + +id_aa_signingCertificateV2 = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.47') + +Hash = rfc2634.Hash + +IssuerSerial = rfc2634.IssuerSerial + +ESSCertID = rfc2634.ESSCertID + +SigningCertificate = rfc2634.SigningCertificate + + +sha256AlgId = AlgorithmIdentifier() +sha256AlgId['algorithm'] = rfc4055.id_sha256 +# A non-schema object for sha256AlgId['parameters'] as absent +sha256AlgId['parameters'] = der_encode(univ.OctetString('')) + + +class ESSCertIDv2(univ.Sequence): + pass + +ESSCertIDv2.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('hashAlgorithm', sha256AlgId), + namedtype.NamedType('certHash', Hash()), + namedtype.OptionalNamedType('issuerSerial', IssuerSerial()) +) + + +class SigningCertificateV2(univ.Sequence): + pass + +SigningCertificateV2.componentType = namedtype.NamedTypes( + namedtype.NamedType('certs', univ.SequenceOf( + componentType=ESSCertIDv2())), + namedtype.OptionalNamedType('policies', univ.SequenceOf( + componentType=PolicyInformation())) +) + + +# Mail List Expansion History Attribute + +id_aa_mlExpandHistory = rfc2634.id_aa_mlExpandHistory + +ub_ml_expansion_history = rfc2634.ub_ml_expansion_history + +EntityIdentifier = rfc2634.EntityIdentifier + +MLReceiptPolicy = rfc2634.MLReceiptPolicy + +MLData = rfc2634.MLData + +MLExpansionHistory = rfc2634.MLExpansionHistory + + +# ESS Security Label Attribute + +id_aa_securityLabel = rfc2634.id_aa_securityLabel + +ub_privacy_mark_length = rfc2634.ub_privacy_mark_length + +ub_security_categories = rfc2634.ub_security_categories + +ub_integer_options = rfc2634.ub_integer_options + +ESSPrivacyMark = rfc2634.ESSPrivacyMark + +SecurityClassification = rfc2634.SecurityClassification + +SecurityPolicyIdentifier = rfc2634.SecurityPolicyIdentifier + +SecurityCategory = rfc2634.SecurityCategory + +SecurityCategories = rfc2634.SecurityCategories + +ESSSecurityLabel = rfc2634.ESSSecurityLabel + + +# Equivalent Labels Attribute + +id_aa_equivalentLabels = rfc2634.id_aa_equivalentLabels + +EquivalentLabels = rfc2634.EquivalentLabels + + +# Content Identifier Attribute + +id_aa_contentIdentifier = rfc2634.id_aa_contentIdentifier + +ContentIdentifier = rfc2634.ContentIdentifier + + +# Content Reference Attribute + +id_aa_contentReference = rfc2634.id_aa_contentReference + +ContentReference = rfc2634.ContentReference + + +# Message Signature Digest Attribute + +id_aa_msgSigDigest = rfc2634.id_aa_msgSigDigest + +MsgSigDigest = rfc2634.MsgSigDigest + + +# Content Hints Attribute + +id_aa_contentHint = rfc2634.id_aa_contentHint + +ContentHints = rfc2634.ContentHints + + +# Receipt Request Attribute + +AllOrFirstTier = rfc2634.AllOrFirstTier + +ReceiptsFrom = rfc2634.ReceiptsFrom + +id_aa_receiptRequest = rfc2634.id_aa_receiptRequest + +ub_receiptsTo = rfc2634.ub_receiptsTo + +ReceiptRequest = rfc2634.ReceiptRequest + + +# Receipt Content Type + +ESSVersion = rfc2634.ESSVersion + +id_ct_receipt = rfc2634.id_ct_receipt + +Receipt = rfc2634.Receipt + +ub_receiptsTo = rfc2634.ub_receiptsTo + +ReceiptRequest = rfc2634.ReceiptRequest + + +# Map of Attribute Type to the Attribute structure + +ESSAttributeMap = rfc2634.ESSAttributeMap + +_ESSAttributeMapAddition = { + id_aa_signingCertificateV2: SigningCertificateV2(), +} + +ESSAttributeMap.update(_ESSAttributeMapAddition) + + +# Map of Content Type OIDs to Content Types +# To be added to the ones that are in rfc5652.py + +cmsContentTypesMapUpdate = { + id_ct_receipt: Receipt(), +}
\ No newline at end of file diff --git a/pyasn1_modules/rfc5083.py b/pyasn1_modules/rfc5083.py index 5240aaa..e3df086 100644 --- a/pyasn1_modules/rfc5083.py +++ b/pyasn1_modules/rfc5083.py @@ -1,7 +1,10 @@ # This file is being contributed to of pyasn1-modules software. # # Created by Russ Housley without assistance from the asn1ate tool. -# Copyright (c) 2018, Vigil Security, LLC +# Modified by Russ Housley to add a map for use with opentypes and +# simplify the code for the object identifier assignment. +# +# Copyright (c) 2018, 2019 Vigil Security, LLC # License: http://snmplabs.com/pyasn1/license.html # # Authenticated-Enveloped-Data for the Cryptographic Message Syntax (CMS) @@ -9,25 +12,18 @@ # ASN.1 source from: # https://www.rfc-editor.org/rfc/rfc5083.txt -from pyasn1.type import namedtype, tag, univ -from pyasn1_modules import rfc5652 +from pyasn1.type import namedtype +from pyasn1.type import tag +from pyasn1.type import univ +from pyasn1_modules import rfc5652 MAX = float('inf') -def _buildOid(*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) - - -id_ct_authEnvelopedData = _buildOid(1, 2, 840, 113549, 1, 9, 16, 1, 23) +# CMS Authenticated-Enveloped-Data Content Type +id_ct_authEnvelopedData = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.23') class AuthEnvelopedData(univ.Sequence): pass @@ -44,3 +40,11 @@ AuthEnvelopedData.componentType = namedtype.NamedTypes( namedtype.OptionalNamedType('unauthAttrs', rfc5652.UnauthAttributes().subtype( implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) ) + + +# Map of Content Type OIDs to Content Types +# To be added to the ones that are in rfc5652.py + +cmsContentTypesMapUpdate = { + id_ct_authEnvelopedData: AuthEnvelopedData(), +}
\ No newline at end of file diff --git a/pyasn1_modules/rfc5084.py b/pyasn1_modules/rfc5084.py index 99ce60d..18abec8 100644 --- a/pyasn1_modules/rfc5084.py +++ b/pyasn1_modules/rfc5084.py @@ -12,8 +12,9 @@ # ASN.1 source from: # https://www.rfc-editor.org/rfc/rfc5084.txt - -from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful +from pyasn1.type import constraint +from pyasn1.type import namedtype +from pyasn1.type import univ def _OID(*components): @@ -37,7 +38,6 @@ class AES_GCM_ICVlen(univ.Integer): AES_CCM_ICVlen.subtypeSpec = constraint.SingleValueConstraint(4, 6, 8, 10, 12, 14, 16) - AES_GCM_ICVlen.subtypeSpec = constraint.ValueRangeConstraint(12, 16) @@ -65,23 +65,16 @@ GCMParameters.componentType = namedtype.NamedTypes( namedtype.DefaultedNamedType('aes-ICVlen', AES_GCM_ICVlen().subtype(value=12)) ) - aes = _OID(2, 16, 840, 1, 101, 3, 4, 1) - id_aes128_CCM = _OID(aes, 7) - id_aes128_GCM = _OID(aes, 6) - id_aes192_CCM = _OID(aes, 27) - id_aes192_GCM = _OID(aes, 26) - id_aes256_CCM = _OID(aes, 47) - id_aes256_GCM = _OID(aes, 46) diff --git a/pyasn1_modules/rfc5280.py b/pyasn1_modules/rfc5280.py index 80bded5..181584c 100644 --- a/pyasn1_modules/rfc5280.py +++ b/pyasn1_modules/rfc5280.py @@ -3,6 +3,9 @@ # This file is part of pyasn1-modules software. # # Created by Stanisław Pitucha with asn1ate tool. +# Updated by Russ Housley for ORAddress Extension Attribute opentype support. +# Updated by Russ Housley for AlgorithmIdentifier opentype support. +# # Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com> # License: http://snmplabs.com/pyasn1/license.html # @@ -10,7 +13,7 @@ # Revocation List (CRL) Profile # # ASN.1 source from: -# http://www.ietf.org/rfc/rfc5280.txt +# https://www.rfc-editor.org/rfc/rfc5280.txt # from pyasn1.type import char from pyasn1.type import constraint @@ -72,7 +75,7 @@ class Extensions(univ.SequenceOf): Extensions.componentType = Extension() -Extensions.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +Extensions.sizeSpec = constraint.ValueSizeConstraint(1, MAX) physical_delivery_personal_name = univ.Integer(13) @@ -203,7 +206,7 @@ class TeletexDomainDefinedAttributes(univ.SequenceOf): TeletexDomainDefinedAttributes.componentType = TeletexDomainDefinedAttribute() -TeletexDomainDefinedAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) +TeletexDomainDefinedAttributes.sizeSpec = constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) extended_network_address = univ.Integer(22) @@ -280,10 +283,15 @@ class CertificateSerialNumber(univ.Integer): pass +algorithmIdentifierMap = {} + + class AlgorithmIdentifier(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('algorithm', univ.ObjectIdentifier()), - namedtype.OptionalNamedType('parameters', univ.Any(), openType=opentype.OpenType) + namedtype.OptionalNamedType('parameters', univ.Any(), + openType=opentype.OpenType('algorithm', algorithmIdentifierMap) + ) ) @@ -319,7 +327,7 @@ class RelativeDistinguishedName(univ.SetOf): RelativeDistinguishedName.componentType = AttributeTypeAndValue() -RelativeDistinguishedName.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +RelativeDistinguishedName.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class RDNSequence(univ.SequenceOf): @@ -382,7 +390,9 @@ class PhysicalDeliveryOfficeName(PDSParameter): ub_extension_attributes = univ.Integer(256) certificateExtensionsMap = { +} +oraddressExtensionAttributeMap = { } @@ -394,7 +404,7 @@ class ExtensionAttribute(univ.Sequence): namedtype.NamedType( 'extension-attribute-value', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)), - openType=opentype.OpenType('type', certificateExtensionsMap)) + openType=opentype.OpenType('extension-attribute-type', oraddressExtensionAttributeMap)) ) id_qt = _buildOid(id_pkix, 2) @@ -639,7 +649,7 @@ class ExtensionAttributes(univ.SetOf): ExtensionAttributes.componentType = ExtensionAttribute() -ExtensionAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, ub_extension_attributes) +ExtensionAttributes.sizeSpec = constraint.ValueSizeConstraint(1, ub_extension_attributes) ub_emailaddress_length = univ.Integer(255) @@ -786,7 +796,7 @@ class BuiltInDomainDefinedAttributes(univ.SequenceOf): BuiltInDomainDefinedAttributes.componentType = BuiltInDomainDefinedAttribute() -BuiltInDomainDefinedAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) +BuiltInDomainDefinedAttributes.sizeSpec = constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) id_at_pseudonym = _buildOid(id_at, 65) @@ -867,7 +877,7 @@ class OrganizationalUnitNames(univ.SequenceOf): OrganizationalUnitNames.componentType = OrganizationalUnitName() -OrganizationalUnitNames.subtypeSpec = constraint.ValueSizeConstraint(1, ub_organizational_units) +OrganizationalUnitNames.sizeSpec = constraint.ValueSizeConstraint(1, ub_organizational_units) class PrivateDomainName(univ.Choice): @@ -1026,7 +1036,7 @@ class TeletexOrganizationalUnitNames(univ.SequenceOf): TeletexOrganizationalUnitNames.componentType = TeletexOrganizationalUnitName() -TeletexOrganizationalUnitNames.subtypeSpec = constraint.ValueSizeConstraint(1, ub_organizational_units) +TeletexOrganizationalUnitNames.sizeSpec = constraint.ValueSizeConstraint(1, ub_organizational_units) id_ce = _buildOid(2, 5, 29) @@ -1149,7 +1159,7 @@ class GeneralNames(univ.SequenceOf): GeneralNames.componentType = GeneralName() -GeneralNames.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +GeneralNames.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class DistributionPointName(univ.Choice): @@ -1249,7 +1259,7 @@ class CRLDistributionPoints(univ.SequenceOf): CRLDistributionPoints.componentType = DistributionPoint() -CRLDistributionPoints.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +CRLDistributionPoints.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class GeneralSubtrees(univ.SequenceOf): @@ -1257,7 +1267,7 @@ class GeneralSubtrees(univ.SequenceOf): GeneralSubtrees.componentType = GeneralSubtree() -GeneralSubtrees.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +GeneralSubtrees.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class NameConstraints(univ.Sequence): @@ -1277,7 +1287,7 @@ class SubjectDirectoryAttributes(univ.SequenceOf): SubjectDirectoryAttributes.componentType = Attribute() -SubjectDirectoryAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +SubjectDirectoryAttributes.sizeSpec = constraint.ValueSizeConstraint(1, MAX) id_kp_OCSPSigning = _buildOid(id_kp, 9) @@ -1355,7 +1365,7 @@ class CertificatePolicies(univ.SequenceOf): CertificatePolicies.componentType = PolicyInformation() -CertificatePolicies.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +CertificatePolicies.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class SubjectAltName(GeneralNames): @@ -1393,7 +1403,7 @@ PolicyMappings.componentType = univ.Sequence( ) ) -PolicyMappings.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +PolicyMappings.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class InhibitAnyPolicy(SkipCerts): @@ -1457,7 +1467,7 @@ class AuthorityInfoAccessSyntax(univ.SequenceOf): AuthorityInfoAccessSyntax.componentType = AccessDescription() -AuthorityInfoAccessSyntax.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +AuthorityInfoAccessSyntax.sizeSpec = constraint.ValueSizeConstraint(1, MAX) id_holdinstruction_none = _buildOid(holdInstruction, 1) @@ -1485,7 +1495,7 @@ class ExtKeyUsageSyntax(univ.SequenceOf): ExtKeyUsageSyntax.componentType = KeyPurposeId() -ExtKeyUsageSyntax.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +ExtKeyUsageSyntax.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class HoldInstructionCode(univ.ObjectIdentifier): @@ -1504,7 +1514,7 @@ class SubjectInfoAccessSyntax(univ.SequenceOf): SubjectInfoAccessSyntax.componentType = AccessDescription() -SubjectInfoAccessSyntax.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +SubjectInfoAccessSyntax.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class InvalidityDate(useful.GeneralizedTime): @@ -1562,6 +1572,37 @@ id_ce_subjectKeyIdentifier = _buildOid(id_ce, 14) id_ce_inhibitAnyPolicy = _buildOid(id_ce, 54) +# map of ORAddress ExtensionAttribute type to ExtensionAttribute value + +_oraddressExtensionAttributeMapUpdate = { + common_name: CommonName(), + teletex_common_name: TeletexCommonName(), + teletex_organization_name: TeletexOrganizationName(), + teletex_personal_name: TeletexPersonalName(), + teletex_organizational_unit_names: TeletexOrganizationalUnitNames(), + pds_name: PDSName(), + physical_delivery_country_name: PhysicalDeliveryCountryName(), + postal_code: PostalCode(), + physical_delivery_office_name: PhysicalDeliveryOfficeName(), + physical_delivery_office_number: PhysicalDeliveryOfficeNumber(), + extension_OR_address_components: ExtensionORAddressComponents(), + physical_delivery_personal_name: PhysicalDeliveryPersonalName(), + physical_delivery_organization_name: PhysicalDeliveryOrganizationName(), + extension_physical_delivery_address_components: ExtensionPhysicalDeliveryAddressComponents(), + unformatted_postal_address: UnformattedPostalAddress(), + street_address: StreetAddress(), + post_office_box_address: PostOfficeBoxAddress(), + poste_restante_address: PosteRestanteAddress(), + unique_postal_name: UniquePostalName(), + local_postal_attributes: LocalPostalAttributes(), + extended_network_address: ExtendedNetworkAddress(), + terminal_type: TerminalType(), + teletex_domain_defined_attributes: TeletexDomainDefinedAttributes(), +} + +oraddressExtensionAttributeMap.update(_oraddressExtensionAttributeMapUpdate) + + # map of AttributeType -> AttributeValue _certificateAttributesMapUpdate = { diff --git a/pyasn1_modules/rfc5480.py b/pyasn1_modules/rfc5480.py new file mode 100644 index 0000000..0113826 --- /dev/null +++ b/pyasn1_modules/rfc5480.py @@ -0,0 +1,184 @@ +# This file is being contributed to pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# Modified by Russ Housley to add maps for opentypes. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Elliptic Curve Cryptography Subject Public Key Information +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc5480.txt + + +# What can be imported from rfc4055.py ? + +from pyasn1.type import namedtype +from pyasn1.type import univ + +from pyasn1_modules import rfc3279 + + +# These structures are the same as RFC 3279. + +DHPublicKey = rfc3279.DHPublicKey + +DSAPublicKey = rfc3279.DSAPublicKey + +ValidationParms = rfc3279.ValidationParms + +DomainParameters = rfc3279.DomainParameters + +ECDSA_Sig_Value = rfc3279.ECDSA_Sig_Value + +ECPoint = rfc3279.ECPoint + +KEA_Parms_Id = rfc3279.KEA_Parms_Id + +RSAPublicKey = rfc3279.RSAPublicKey + + +# RFC 5480 changed the names of these structures from RFC 3279. + +DSS_Parms = rfc3279.Dss_Parms + +DSA_Sig_Value = rfc3279.Dss_Sig_Value + + +# RFC 3279 defines a more complex alternative for ECParameters. +# RFC 5480 narrows the definition to a single CHOICE: namedCurve. + +class ECParameters(univ.Choice): + pass + +ECParameters.componentType = namedtype.NamedTypes( + namedtype.NamedType('namedCurve', univ.ObjectIdentifier()) +) + + +# OIDs for Message Digest Algorithms + +id_md2 = univ.ObjectIdentifier('1.2.840.113549.2.2') + +id_md5 = univ.ObjectIdentifier('1.2.840.113549.2.5') + +id_sha1 = univ.ObjectIdentifier('1.3.14.3.2.26') + +id_sha224 = univ.ObjectIdentifier('2.16.840.1.101.3.4.2.4') + +id_sha256 = univ.ObjectIdentifier('2.16.840.1.101.3.4.2.1') + +id_sha384 = univ.ObjectIdentifier('2.16.840.1.101.3.4.2.2') + +id_sha512 = univ.ObjectIdentifier('2.16.840.1.101.3.4.2.3') + + +# OID for RSA PK Algorithm and Key + +rsaEncryption = univ.ObjectIdentifier('1.2.840.113549.1.1.1') + + +# OID for DSA PK Algorithm, Key, and Parameters + +id_dsa = univ.ObjectIdentifier('1.2.840.10040.4.1') + + +# OID for Diffie-Hellman PK Algorithm, Key, and Parameters + +dhpublicnumber = univ.ObjectIdentifier('1.2.840.10046.2.1') + +# OID for KEA PK Algorithm and Parameters + +id_keyExchangeAlgorithm = univ.ObjectIdentifier('2.16.840.1.101.2.1.1.22') + + +# OIDs for Elliptic Curve Algorithm ID, Key, and Parameters +# Note that ECDSA keys always use this OID + +id_ecPublicKey = univ.ObjectIdentifier('1.2.840.10045.2.1') + +id_ecDH = univ.ObjectIdentifier('1.3.132.1.12') + +id_ecMQV = univ.ObjectIdentifier('1.3.132.1.13') + + +# OIDs for RSA Signature Algorithms + +md2WithRSAEncryption = univ.ObjectIdentifier('1.2.840.113549.1.1.2') + +md5WithRSAEncryption = univ.ObjectIdentifier('1.2.840.113549.1.1.4') + +sha1WithRSAEncryption = univ.ObjectIdentifier('1.2.840.113549.1.1.5') + + +# OIDs for DSA Signature Algorithms + +id_dsa_with_sha1 = univ.ObjectIdentifier('1.2.840.10040.4.3') + +id_dsa_with_sha224 = univ.ObjectIdentifier('2.16.840.1.101.3.4.3.1') + +id_dsa_with_sha256 = univ.ObjectIdentifier('2.16.840.1.101.3.4.3.2') + + +# OIDs for ECDSA Signature Algorithms + +ecdsa_with_SHA1 = univ.ObjectIdentifier('1.2.840.10045.4.1') + +ecdsa_with_SHA224 = univ.ObjectIdentifier('1.2.840.10045.4.3.1') + +ecdsa_with_SHA256 = univ.ObjectIdentifier('1.2.840.10045.4.3.2') + +ecdsa_with_SHA384 = univ.ObjectIdentifier('1.2.840.10045.4.3.3') + +ecdsa_with_SHA512 = univ.ObjectIdentifier('1.2.840.10045.4.3.4') + + +# OIDs for Named Elliptic Curves + +secp192r1 = univ.ObjectIdentifier('1.2.840.10045.3.1.1') + +sect163k1 = univ.ObjectIdentifier('1.3.132.0.1') + +sect163r2 = univ.ObjectIdentifier('1.3.132.0.15') + +secp224r1 = univ.ObjectIdentifier('1.3.132.0.33') + +sect233k1 = univ.ObjectIdentifier('1.3.132.0.26') + +sect233r1 = univ.ObjectIdentifier('1.3.132.0.27') + +secp256r1 = univ.ObjectIdentifier('1.2.840.10045.3.1.7') + +sect283k1 = univ.ObjectIdentifier('1.3.132.0.16') + +sect283r1 = univ.ObjectIdentifier('1.3.132.0.17') + +secp384r1 = univ.ObjectIdentifier('1.3.132.0.34') + +sect409k1 = univ.ObjectIdentifier('1.3.132.0.36') + +sect409r1 = univ.ObjectIdentifier('1.3.132.0.37') + +secp521r1 = univ.ObjectIdentifier('1.3.132.0.35') + +sect571k1 = univ.ObjectIdentifier('1.3.132.0.38') + +sect571r1 = univ.ObjectIdentifier('1.3.132.0.39') + + +# Map of Algorithm Identifier OIDs to Parameters +# The algorithm is not included if the parameters MUST be absent + +algorithmIdentifierMapUpdate = { + rsaEncryption: univ.Null(), + md2WithRSAEncryption: univ.Null(), + md5WithRSAEncryption: univ.Null(), + sha1WithRSAEncryption: univ.Null(), + id_dsa: DSS_Parms(), + dhpublicnumber: DomainParameters(), + id_keyExchangeAlgorithm: KEA_Parms_Id(), + id_ecPublicKey: ECParameters(), + id_ecDH: ECParameters(), + id_ecMQV: ECParameters(), +}
\ No newline at end of file diff --git a/pyasn1_modules/rfc5649.py b/pyasn1_modules/rfc5649.py new file mode 100644 index 0000000..84809ee --- /dev/null +++ b/pyasn1_modules/rfc5649.py @@ -0,0 +1,33 @@ +# This file is being contributed to pyasn1-modules software. +# +# Created by Russ Housley. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# AES Key Wrap with Padding +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc5649.txt + +from pyasn1.type import univ + +from pyasn1_modules import rfc5280 + + +class AlgorithmIdentifier(rfc5280.AlgorithmIdentifier): + pass + + +id_aes128_wrap = univ.ObjectIdentifier('2.16.840.1.101.3.4.1.5') + +id_aes192_wrap = univ.ObjectIdentifier('2.16.840.1.101.3.4.1.25') + +id_aes256_wrap = univ.ObjectIdentifier('2.16.840.1.101.3.4.1.45') + + +id_aes128_wrap_pad = univ.ObjectIdentifier('2.16.840.1.101.3.4.1.8') + +id_aes192_wrap_pad = univ.ObjectIdentifier('2.16.840.1.101.3.4.1.28') + +id_aes256_wrap_pad = univ.ObjectIdentifier('2.16.840.1.101.3.4.1.48') diff --git a/pyasn1_modules/rfc5652.py b/pyasn1_modules/rfc5652.py index 094ce74..2e48962 100644 --- a/pyasn1_modules/rfc5652.py +++ b/pyasn1_modules/rfc5652.py @@ -3,6 +3,8 @@ # This file is part of pyasn1-modules software. # # Created by Stanisław Pitucha with asn1ate tool. +# Modified by Russ Housley to add support for opentypes. +# # Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com> # License: http://snmplabs.com/pyasn1/license.html # @@ -14,6 +16,7 @@ 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.type import useful @@ -35,6 +38,19 @@ def _buildOid(*components): return univ.ObjectIdentifier(output) +cmsContentTypesMap = { } + +cmsAttributesMap = { } + +otherKeyAttributesMap = { } + +otherCertFormatMap = { } + +otherRevInfoFormatMap = { } + +otherRecipientInfoMap = { } + + class AttCertVersionV1(univ.Integer): pass @@ -89,7 +105,9 @@ class Attribute(univ.Sequence): Attribute.componentType = namedtype.NamedTypes( namedtype.NamedType('attrType', univ.ObjectIdentifier()), - namedtype.NamedType('attrValues', univ.SetOf(componentType=AttributeValue())) + namedtype.NamedType('attrValues', univ.SetOf(componentType=AttributeValue()), + openType=opentype.OpenType('attrType', cmsAttributesMap) + ) ) @@ -98,7 +116,7 @@ class SignedAttributes(univ.SetOf): SignedAttributes.componentType = Attribute() -SignedAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +SignedAttributes.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class AttributeCertificateV2(rfc3281.AttributeCertificate): @@ -111,7 +129,9 @@ class OtherKeyAttribute(univ.Sequence): OtherKeyAttribute.componentType = namedtype.NamedTypes( namedtype.NamedType('keyAttrId', univ.ObjectIdentifier()), - namedtype.OptionalNamedType('keyAttr', univ.Any()) + namedtype.OptionalNamedType('keyAttr', univ.Any(), + openType=opentype.OpenType('keyAttrId', otherKeyAttributesMap) + ) ) @@ -120,7 +140,7 @@ class UnauthAttributes(univ.SetOf): UnauthAttributes.componentType = Attribute() -UnauthAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +UnauthAttributes.sizeSpec = constraint.ValueSizeConstraint(1, MAX) id_encryptedData = _buildOid(1, 2, 840, 113549, 1, 7, 6) @@ -210,7 +230,9 @@ class OtherCertificateFormat(univ.Sequence): OtherCertificateFormat.componentType = namedtype.NamedTypes( namedtype.NamedType('otherCertFormat', univ.ObjectIdentifier()), - namedtype.NamedType('otherCert', univ.Any()) + namedtype.NamedType('otherCert', univ.Any(), + openType=opentype.OpenType('otherCertFormat', otherCertFormatMap) + ) ) @@ -274,7 +296,9 @@ class OtherRevocationInfoFormat(univ.Sequence): OtherRevocationInfoFormat.componentType = namedtype.NamedTypes( namedtype.NamedType('otherRevInfoFormat', univ.ObjectIdentifier()), - namedtype.NamedType('otherRevInfo', univ.Any()) + namedtype.NamedType('otherRevInfo', univ.Any(), + openType=opentype.OpenType('otherRevInfoFormat', otherRevInfoFormatMap) + ) ) @@ -337,7 +361,7 @@ class UnprotectedAttributes(univ.SetOf): UnprotectedAttributes.componentType = Attribute() -UnprotectedAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +UnprotectedAttributes.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class KeyEncryptionAlgorithmIdentifier(rfc5280.AlgorithmIdentifier): @@ -455,7 +479,9 @@ class OtherRecipientInfo(univ.Sequence): OtherRecipientInfo.componentType = namedtype.NamedTypes( namedtype.NamedType('oriType', univ.ObjectIdentifier()), - namedtype.NamedType('oriValue', univ.Any()) + namedtype.NamedType('oriValue', univ.Any(), + openType=opentype.OpenType('oriType', otherRecipientInfoMap) + ) ) @@ -481,7 +507,7 @@ class RecipientInfos(univ.SetOf): RecipientInfos.componentType = RecipientInfo() -RecipientInfos.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +RecipientInfos.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class EnvelopedData(univ.Sequence): @@ -533,7 +559,7 @@ class UnsignedAttributes(univ.SetOf): UnsignedAttributes.componentType = Attribute() -UnsignedAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +UnsignedAttributes.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class SignerIdentifier(univ.Choice): @@ -581,7 +607,9 @@ class ContentInfo(univ.Sequence): ContentInfo.componentType = namedtype.NamedTypes( namedtype.NamedType('contentType', ContentType()), - namedtype.NamedType('content', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) + namedtype.NamedType('content', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)), + openType=opentype.OpenType('contentType', cmsContentTypesMap) + ) ) @@ -609,7 +637,7 @@ class AuthAttributes(univ.SetOf): AuthAttributes.componentType = Attribute() -AuthAttributes.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +AuthAttributes.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class Time(univ.Choice): @@ -704,3 +732,30 @@ class SigningTime(Time): id_ct_authData = _buildOid(1, 2, 840, 113549, 1, 9, 16, 1, 2) + + +# CMS Content Type Map + +_cmsContentTypesMapUpdate = { + id_ct_contentInfo: ContentInfo(), + id_data: univ.OctetString(), + id_signedData: SignedData(), + id_envelopedData: EnvelopedData(), + id_digestedData: DigestedData(), + id_encryptedData: EncryptedData(), + id_ct_authData: AuthenticatedData(), +} + +cmsContentTypesMap.update(_cmsContentTypesMapUpdate) + + +# CMS Attribute Map + +_cmsAttributesMapUpdate = { + id_contentType: ContentType(), + id_messageDigest: MessageDigest(), + id_signingTime: SigningTime(), + id_countersignature: Countersignature(), +} + +cmsAttributesMap.update(_cmsAttributesMapUpdate) diff --git a/pyasn1_modules/rfc5915.py b/pyasn1_modules/rfc5915.py new file mode 100644 index 0000000..82ff4a3 --- /dev/null +++ b/pyasn1_modules/rfc5915.py @@ -0,0 +1,32 @@ +# This file is being contributed to pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Elliptic Curve Private Key +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc5915.txt + +from pyasn1.type import namedtype +from pyasn1.type import namedval +from pyasn1.type import tag +from pyasn1.type import univ + +from pyasn1_modules import rfc5480 + + +class ECPrivateKey(univ.Sequence): + pass + +ECPrivateKey.componentType = namedtype.NamedTypes( + namedtype.NamedType('version', univ.Integer( + namedValues=namedval.NamedValues(('ecPrivkeyVer1', 1)))), + namedtype.NamedType('privateKey', univ.OctetString()), + namedtype.OptionalNamedType('parameters', rfc5480.ECParameters().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.OptionalNamedType('publicKey', univ.BitString().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) +) diff --git a/pyasn1_modules/rfc5940.py b/pyasn1_modules/rfc5940.py new file mode 100644 index 0000000..c5ae0c8 --- /dev/null +++ b/pyasn1_modules/rfc5940.py @@ -0,0 +1,56 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# Modified by Russ Housley to add map for use with opentypes. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Additional CMS Revocation Information Choices +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc5940.txt +# + +from pyasn1.type import namedtype +from pyasn1.type import tag +from pyasn1.type import univ + +from pyasn1_modules import rfc2560 +from pyasn1_modules import rfc5652 + + +# RevocationInfoChoice for OCSP response: +# The OID is included in otherRevInfoFormat, and +# signed OCSPResponse is included in otherRevInfo + +id_ri_ocsp_response = univ.ObjectIdentifier('1.3.6.1.5.5.7.16.2') + +OCSPResponse = rfc2560.OCSPResponse + + +# RevocationInfoChoice for SCVP request/response: +# The OID is included in otherRevInfoFormat, and +# SCVPReqRes is included in otherRevInfo + +id_ri_scvp = univ.ObjectIdentifier('1.3.6.1.5.5.7.16.4') + +ContentInfo = rfc5652.ContentInfo + +class SCVPReqRes(univ.Sequence): + pass + +SCVPReqRes.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('request', ContentInfo().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('response', ContentInfo()) +) + + +# Map of Revocation Info Format OIDs to Revocation Info Format +# To be added to the ones that are in rfc5652.py + +otherRevInfoFormatMapUpdate = { + id_ri_ocsp_response: OCSPResponse(), + id_ri_scvp: SCVPReqRes(), +} diff --git a/pyasn1_modules/rfc5958.py b/pyasn1_modules/rfc5958.py index 35ea902..d8c7c90 100644 --- a/pyasn1_modules/rfc5958.py +++ b/pyasn1_modules/rfc5958.py @@ -2,6 +2,7 @@ # This file is being contributed to pyasn1-modules software. # # Created by Russ Housley. +# Modified by Russ Housley to add a map for use with opentypes. # # Copyright (c) 2019, Vigil Security, LLC # License: http://snmplabs.com/pyasn1/license.html @@ -10,7 +11,7 @@ # the PrivateKeyInfo structure in PKCS#8 in RFC 5208 # # ASN.1 source from: -# https://www.rfc-editor.org/rfc/rfc8418.txt +# https://www.rfc-editor.org/rfc/rfc5958.txt from pyasn1.type import univ, constraint, namedtype, namedval, tag @@ -83,5 +84,12 @@ class AsymmetricKeyPackage(univ.SequenceOf): pass AsymmetricKeyPackage.componentType = OneAsymmetricKey() -AsymmetricKeyPackage.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) +AsymmetricKeyPackage.sizeSpec=constraint.ValueSizeConstraint(1, MAX) + +# Map of Content Type OIDs to Content Types +# To be added to the ones that are in rfc5652.py + +cmsContentTypesMapUpdate = { + id_ct_KP_aKeyPackage: AsymmetricKeyPackage(), +} diff --git a/pyasn1_modules/rfc6019.py b/pyasn1_modules/rfc6019.py new file mode 100644 index 0000000..7816593 --- /dev/null +++ b/pyasn1_modules/rfc6019.py @@ -0,0 +1,41 @@ +# This file is being contributed to pyasn1-modules software. +# +# Created by Russ Housley. +# Modified by Russ Housley to add a map for use with opentypes. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# BinaryTime: An Alternate Format for Representing Date and Time +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc6019.txt + +from pyasn1.type import constraint +from pyasn1.type import univ + +MAX = float('inf') + + +# BinaryTime: Represent date and time as an integer + +class BinaryTime(univ.Integer): + pass + +BinaryTime.subtypeSpec = constraint.ValueRangeConstraint(0, MAX) + + +# CMS Attribute for representing signing time in BinaryTime + +id_aa_binarySigningTime = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.46') + +class BinarySigningTime(BinaryTime): + pass + + +# Map of Attribute Type OIDs to Attributes +# To be added to the ones that are in rfc5652.py + +cmsAttributesMapUpdate = { + id_aa_binarySigningTime: BinarySigningTime(), +} diff --git a/pyasn1_modules/rfc6402.py b/pyasn1_modules/rfc6402.py index 7c9f862..dbb699a 100644 --- a/pyasn1_modules/rfc6402.py +++ b/pyasn1_modules/rfc6402.py @@ -3,18 +3,22 @@ # This file is part of pyasn1-modules software. # # Created by Stanisław Pitucha with asn1ate tool. +# Modified by Russ Housley to add a maps for CMC Control Attributes +# and CMC Content Types for use with opentypes. +# # Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com> # License: http://snmplabs.com/pyasn1/license.html # # Certificate Management over CMS (CMC) Updates # # ASN.1 source from: -# http://www.ietf.org/rfc/rfc6402.txt +# https://www.rfc-editor.org/rfc/rfc6402.txt # 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.type import useful @@ -37,6 +41,9 @@ def _buildOid(*components): return univ.ObjectIdentifier(output) +cmcControlAttributesMap = { } + + class ChangeSubjectName(univ.Sequence): pass @@ -90,7 +97,7 @@ class BodyPartPath(univ.SequenceOf): BodyPartPath.componentType = BodyPartID() -BodyPartPath.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +BodyPartPath.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class BodyPartReference(univ.Choice): @@ -384,7 +391,9 @@ class TaggedAttribute(univ.Sequence): TaggedAttribute.componentType = namedtype.NamedTypes( namedtype.NamedType('bodyPartID', BodyPartID()), namedtype.NamedType('attrType', univ.ObjectIdentifier()), - namedtype.NamedType('attrValues', univ.SetOf(componentType=AttributeValue())) + namedtype.NamedType('attrValues', univ.SetOf(componentType=AttributeValue()), + openType=opentype.OpenType('attrType', cmcControlAttributesMap) + ) ) @@ -416,7 +425,7 @@ class BodyPartList(univ.SequenceOf): BodyPartList.componentType = BodyPartID() -BodyPartList.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +BodyPartList.sizeSpec = constraint.ValueSizeConstraint(1, MAX) id_cmc_responseBody = _buildOid(id_cmc, 37) @@ -481,7 +490,7 @@ class ExtensionReq(univ.SequenceOf): ExtensionReq.componentType = rfc5280.Extension() -ExtensionReq.subtypeSpec = constraint.ValueSizeConstraint(1, MAX) +ExtensionReq.sizeSpec = constraint.ValueSizeConstraint(1, MAX) id_kp_cmcArchive = _buildOid(rfc5280.id_kp, 28) @@ -565,3 +574,51 @@ class NoSignatureValue(univ.OctetString): id_ad_cmc = _buildOid(rfc5280.id_ad, 12) id_alg_noSignature = _buildOid(id_pkix, 6, 2) + + +# Map of CMC Control OIDs to CMC Control Attributes + +_cmcControlAttributesMapUpdate = { + id_cmc_statusInfo: CMCStatusInfo(), + id_cmc_statusInfoV2: CMCStatusInfoV2(), + id_cmc_identification: char.UTF8String(), + id_cmc_identityProof: univ.OctetString(), + id_cmc_identityProofV2: IdentifyProofV2(), + id_cmc_dataReturn: univ.OctetString(), + id_cmc_transactionId: univ.Integer(), + id_cmc_senderNonce: univ.OctetString(), + id_cmc_recipientNonce: univ.OctetString(), + id_cmc_addExtensions: AddExtensions(), + id_cmc_encryptedPOP: EncryptedPOP(), + id_cmc_decryptedPOP: DecryptedPOP(), + id_cmc_lraPOPWitness: LraPopWitness(), + id_cmc_getCert: GetCert(), + id_cmc_getCRL: GetCRL(), + id_cmc_revokeRequest: RevokeRequest(), + id_cmc_regInfo: univ.OctetString(), + id_cmc_responseInfo: univ.OctetString(), + id_cmc_queryPending: univ.OctetString(), + id_cmc_popLinkRandom: univ.OctetString(), + id_cmc_popLinkWitness: univ.OctetString(), + id_cmc_popLinkWitnessV2: PopLinkWitnessV2(), + id_cmc_confirmCertAcceptance: CMCCertId(), + id_cmc_trustedAnchors: PublishTrustAnchors(), + id_cmc_authData: AuthPublish(), + id_cmc_batchRequests: BodyPartList(), + id_cmc_batchResponses: BodyPartList(), + id_cmc_publishCert: CMCPublicationInfo(), + id_cmc_modCertTemplate: ModCertTemplate(), + id_cmc_controlProcessed: ControlsProcessed(), + id_ExtensionReq: ExtensionReq(), +} + +cmcControlAttributesMap.update(_cmcControlAttributesMapUpdate) + + +# Map of CMC Content Type OIDs to CMC Content Types +# To be added to the ones that are in rfc5652.py + +cmsContentTypesMapUpdate = { + id_cct_PKIData: PKIData(), + id_cct_PKIResponse: PKIResponse(), +}
\ No newline at end of file diff --git a/pyasn1_modules/rfc7191.py b/pyasn1_modules/rfc7191.py new file mode 100644 index 0000000..4f90be1 --- /dev/null +++ b/pyasn1_modules/rfc7191.py @@ -0,0 +1,257 @@ +# This file is being contributed to of pyasn1-modules software. +# +# Created by Russ Housley without assistance from the asn1ate tool. +# Modified by Russ Housley to add support for opentypes. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# CMS Key Package Receipt and Error Content Types +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc7191.txt + +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 rfc5280 +from pyasn1_modules import rfc5652 + +MAX = float('inf') + +DistinguishedName = rfc5280.DistinguishedName + + +# SingleAttribute is the same as Attribute in RFC 5652, except that the +# attrValues SET must have one and only one member + +class AttributeValue(univ.Any): + pass + + +class AttributeValues(univ.SetOf): + pass + +AttributeValues.componentType = AttributeValue() +AttributeValues.sizeSpec = univ.Set.sizeSpec + constraint.ValueSizeConstraint(1, 1) + + +class SingleAttribute(univ.Sequence): + pass + +SingleAttribute.componentType = namedtype.NamedTypes( + namedtype.NamedType('attrType', univ.ObjectIdentifier()), + namedtype.NamedType('attrValues', AttributeValues(), + openType=opentype.OpenType('attrType', rfc5652.cmsAttributesMap) + ) +) + + +# SIR Entity Name + +class SIREntityNameType(univ.ObjectIdentifier): + pass + + +class SIREntityNameValue(univ.Any): + pass + + +class SIREntityName(univ.Sequence): + pass + +SIREntityName.componentType = namedtype.NamedTypes( + namedtype.NamedType('sirenType', SIREntityNameType()), + namedtype.NamedType('sirenValue', univ.OctetString()) + # CONTAINING the DER-encoded SIREntityNameValue +) + + +class SIREntityNames(univ.SequenceOf): + pass + +SIREntityNames.componentType = SIREntityName() +SIREntityNames.sizeSpec=constraint.ValueSizeConstraint(1, MAX) + + +id_dn = univ.ObjectIdentifier('2.16.840.1.101.2.1.16.0') + + +class siren_dn(SIREntityName): + def __init__(self): + SIREntityName.__init__(self) + self['sirenType'] = id_dn + + +# Key Package Error CMS Content Type + +class EnumeratedErrorCode(univ.Enumerated): + pass + +# Error codes with values <= 33 are aligned with RFC 5934 +EnumeratedErrorCode.namedValues = namedval.NamedValues( + ('decodeFailure', 1), + ('badContentInfo', 2), + ('badSignedData', 3), + ('badEncapContent', 4), + ('badCertificate', 5), + ('badSignerInfo', 6), + ('badSignedAttrs', 7), + ('badUnsignedAttrs', 8), + ('missingContent', 9), + ('noTrustAnchor', 10), + ('notAuthorized', 11), + ('badDigestAlgorithm', 12), + ('badSignatureAlgorithm', 13), + ('unsupportedKeySize', 14), + ('unsupportedParameters', 15), + ('signatureFailure', 16), + ('insufficientMemory', 17), + ('incorrectTarget', 23), + ('missingSignature', 29), + ('resourcesBusy', 30), + ('versionNumberMismatch', 31), + ('revokedCertificate', 33), + ('ambiguousDecrypt', 60), + ('noDecryptKey', 61), + ('badEncryptedData', 62), + ('badEnvelopedData', 63), + ('badAuthenticatedData', 64), + ('badAuthEnvelopedData', 65), + ('badKeyAgreeRecipientInfo', 66), + ('badKEKRecipientInfo', 67), + ('badEncryptContent', 68), + ('badEncryptAlgorithm', 69), + ('missingCiphertext', 70), + ('decryptFailure', 71), + ('badMACAlgorithm', 72), + ('badAuthAttrs', 73), + ('badUnauthAttrs', 74), + ('invalidMAC', 75), + ('mismatchedDigestAlg', 76), + ('missingCertificate', 77), + ('tooManySigners', 78), + ('missingSignedAttributes', 79), + ('derEncodingNotUsed', 80), + ('missingContentHints', 81), + ('invalidAttributeLocation', 82), + ('badMessageDigest', 83), + ('badKeyPackage', 84), + ('badAttributes', 85), + ('attributeComparisonFailure', 86), + ('unsupportedSymmetricKeyPackage', 87), + ('unsupportedAsymmetricKeyPackage', 88), + ('constraintViolation', 89), + ('ambiguousDefaultValue', 90), + ('noMatchingRecipientInfo', 91), + ('unsupportedKeyWrapAlgorithm', 92), + ('badKeyTransRecipientInfo', 93), + ('other', 127) +) + + +class ErrorCodeChoice(univ.Choice): + pass + +ErrorCodeChoice.componentType = namedtype.NamedTypes( + namedtype.NamedType('enum', EnumeratedErrorCode()), + namedtype.NamedType('oid', univ.ObjectIdentifier()) +) + + +class KeyPkgID(univ.OctetString): + pass + + +class KeyPkgIdentifier(univ.Choice): + pass + +KeyPkgIdentifier.componentType = namedtype.NamedTypes( + namedtype.NamedType('pkgID', KeyPkgID()), + namedtype.NamedType('attribute', SingleAttribute()) +) + + +class KeyPkgVersion(univ.Integer): + pass + + +KeyPkgVersion.namedValues = namedval.NamedValues( + ('v1', 1), + ('v2', 2) +) + +KeyPkgVersion.subtypeSpec = constraint.ValueRangeConstraint(1, 65535) + + +id_ct_KP_keyPackageError = univ.ObjectIdentifier('2.16.840.1.101.2.1.2.78.6') + +class KeyPackageError(univ.Sequence): + pass + +KeyPackageError.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', KeyPkgVersion().subtype(value='v2')), + namedtype.OptionalNamedType('errorOf', KeyPkgIdentifier().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), + namedtype.NamedType('errorBy', SIREntityName()), + namedtype.NamedType('errorCode', ErrorCodeChoice()) +) + + +# Key Package Receipt CMS Content Type + +id_ct_KP_keyPackageReceipt = univ.ObjectIdentifier('2.16.840.1.101.2.1.2.78.3') + +class KeyPackageReceipt(univ.Sequence): + pass + +KeyPackageReceipt.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('version', KeyPkgVersion().subtype(value='v2')), + namedtype.NamedType('receiptOf', KeyPkgIdentifier()), + namedtype.NamedType('receivedBy', SIREntityName()) +) + + +# Key Package Receipt Request Attribute + +class KeyPkgReceiptReq(univ.Sequence): + pass + +KeyPkgReceiptReq.componentType = namedtype.NamedTypes( + namedtype.DefaultedNamedType('encryptReceipt', univ.Boolean().subtype(value=0)), + namedtype.OptionalNamedType('receiptsFrom', SIREntityNames().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('receiptsTo', SIREntityNames()) +) + + +id_aa_KP_keyPkgIdAndReceiptReq = univ.ObjectIdentifier('2.16.840.1.101.2.1.5.65') + +class KeyPkgIdentifierAndReceiptReq(univ.Sequence): + pass + +KeyPkgIdentifierAndReceiptReq.componentType = namedtype.NamedTypes( + namedtype.NamedType('pkgID', KeyPkgID()), + namedtype.OptionalNamedType('receiptReq', KeyPkgReceiptReq()) +) + + +# Map of Attribute Type OIDs to Attributes +# To be added to the ones that are in rfc5652.py + +cmsAttributesMapUpdate = { + id_aa_KP_keyPkgIdAndReceiptReq: KeyPkgIdentifierAndReceiptReq(), +} + + +# Map of Content Type OIDs to Content Types +# To be added to the ones that are in rfc5652.py + +cmsContentTypesMapUpdate = { + id_ct_KP_keyPackageError: KeyPackageError(), + id_ct_KP_keyPackageReceipt: KeyPackageReceipt(), +} diff --git a/pyasn1_modules/rfc7296.py b/pyasn1_modules/rfc7296.py new file mode 100644 index 0000000..95a191a --- /dev/null +++ b/pyasn1_modules/rfc7296.py @@ -0,0 +1,32 @@ +# This file is being contributed to pyasn1-modules software. +# +# Created by Russ Housley. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# IKEv2 Certificate Bundle +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc7296.txt + +from pyasn1.type import namedtype +from pyasn1.type import tag +from pyasn1.type import univ + +from pyasn1_modules import rfc5280 + + +class CertificateOrCRL(univ.Choice): + pass + +CertificateOrCRL.componentType = namedtype.NamedTypes( + namedtype.NamedType('cert', rfc5280.Certificate().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('crl', rfc5280.CertificateList().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) +) + + +class CertificateBundle(univ.SequenceOf): + pass + +CertificateBundle.componentType = CertificateOrCRL() diff --git a/pyasn1_modules/rfc8103.py b/pyasn1_modules/rfc8103.py index 5e2d787..6429e86 100644 --- a/pyasn1_modules/rfc8103.py +++ b/pyasn1_modules/rfc8103.py @@ -12,7 +12,8 @@ # ASN.1 source from: # https://www.rfc-editor.org/rfc/rfc8103.txt -from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful +from pyasn1.type import constraint +from pyasn1.type import univ def _OID(*components): @@ -32,7 +33,4 @@ class AEADChaCha20Poly1305Nonce(univ.OctetString): AEADChaCha20Poly1305Nonce.subtypeSpec = constraint.ValueSizeConstraint(12, 12) - id_alg_AEADChaCha20Poly1305 = _OID(1, 2, 840, 113549, 1, 9, 16, 3, 18) - - diff --git a/pyasn1_modules/rfc8226.py b/pyasn1_modules/rfc8226.py index cd9bfd1..0c3dc21 100644 --- a/pyasn1_modules/rfc8226.py +++ b/pyasn1_modules/rfc8226.py @@ -1,7 +1,8 @@ # This file is being contributed to pyasn1-modules software. # # Created by Russ Housley with assistance from the asn1ate tool, with manual -# changes to implement appropriate constraints and added comments +# changes to implement appropriate constraints and added comments. +# Modified by Russ Housley to add maps for use with opentypes. # # Copyright (c) 2019, Vigil Security, LLC # License: http://snmplabs.com/pyasn1/license.html @@ -11,7 +12,11 @@ # ASN.1 source from: # https://www.rfc-editor.org/rfc/rfc8226.txt (with errata corrected) -from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful +from pyasn1.type import char +from pyasn1.type import constraint +from pyasn1.type import namedtype +from pyasn1.type import tag +from pyasn1.type import univ MAX = float('inf') @@ -35,36 +40,38 @@ class JWTClaimName(char.IA5String): class JWTClaimNames(univ.SequenceOf): pass - JWTClaimNames.componentType = JWTClaimName() -JWTClaimNames.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) +JWTClaimNames.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class JWTClaimPermittedValues(univ.Sequence): pass - JWTClaimPermittedValues.componentType = namedtype.NamedTypes( namedtype.NamedType('claim', JWTClaimName()), - namedtype.NamedType('permitted', univ.SequenceOf(componentType=char.UTF8String()).subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))) + namedtype.NamedType('permitted', univ.SequenceOf( + componentType=char.UTF8String()).subtype( + sizeSpec=constraint.ValueSizeConstraint(1, MAX))) ) class JWTClaimPermittedValuesList(univ.SequenceOf): pass - JWTClaimPermittedValuesList.componentType = JWTClaimPermittedValues() -JWTClaimPermittedValuesList.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) +JWTClaimPermittedValuesList.sizeSpec = constraint.ValueSizeConstraint(1, MAX) class JWTClaimConstraints(univ.Sequence): pass - JWTClaimConstraints.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('mustInclude', JWTClaimNames().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('permittedValues', JWTClaimPermittedValuesList().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) + namedtype.OptionalNamedType('mustInclude', + JWTClaimNames().subtype(explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0))), + namedtype.OptionalNamedType('permittedValues', + JWTClaimPermittedValuesList().subtype(explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 1))) ) @@ -81,43 +88,56 @@ class ServiceProviderCode(char.IA5String): class TelephoneNumber(char.IA5String): pass - TelephoneNumber.subtypeSpec = constraint.ConstraintsIntersection( constraint.ValueSizeConstraint(1, 15), - constraint.PermittedAlphabetConstraint('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#', '*') + constraint.PermittedAlphabetConstraint( + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#', '*') ) class TelephoneNumberRange(univ.Sequence): pass - TelephoneNumberRange.componentType = namedtype.NamedTypes( namedtype.NamedType('start', TelephoneNumber()), - namedtype.NamedType('count', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(2, MAX))) + namedtype.NamedType('count', + univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(2, MAX))) ) class TNEntry(univ.Choice): pass - TNEntry.componentType = namedtype.NamedTypes( - namedtype.NamedType('spc', ServiceProviderCode().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('range', TelephoneNumberRange().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), - namedtype.NamedType('one', TelephoneNumber().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) + namedtype.NamedType('spc', + ServiceProviderCode().subtype(explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 0))), + namedtype.NamedType('range', + TelephoneNumberRange().subtype(explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 1))), + namedtype.NamedType('one', + TelephoneNumber().subtype(explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatSimple, 2))) ) class TNAuthorizationList(univ.SequenceOf): pass - TNAuthorizationList.componentType = TNEntry() -TNAuthorizationList.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - +TNAuthorizationList.sizeSpec = constraint.ValueSizeConstraint(1, MAX) id_pe_TNAuthList = _OID(1, 3, 6, 1, 5, 5, 7, 1, 26) id_ad_stirTNList = _OID(1, 3, 6, 1, 5, 5, 7, 48, 14) + + +# Map of Certificate Extension OIDs to Extensions +# To be added to the ones that are in rfc5280.py + +certificateExtensionsMapUpdate = { + id_pe_TNAuthList: TNAuthorizationList(), + id_pe_JWTClaimConstraints: JWTClaimConstraints(), +} + diff --git a/pyasn1_modules/rfc8410.py b/pyasn1_modules/rfc8410.py index 7d87c29..98bc97b 100644 --- a/pyasn1_modules/rfc8410.py +++ b/pyasn1_modules/rfc8410.py @@ -10,7 +10,6 @@ # ASN.1 source from: # https://www.rfc-editor.org/rfc/rfc8410.txt - from pyasn1.type import univ from pyasn1_modules import rfc3565 from pyasn1_modules import rfc4055 @@ -33,15 +32,12 @@ id_X25519 = univ.ObjectIdentifier('1.3.101.110') id_X448 = univ.ObjectIdentifier('1.3.101.111') - id_Ed25519 = univ.ObjectIdentifier('1.3.101.112') id_Ed448 = univ.ObjectIdentifier('1.3.101.113') - id_sha512 = rfc4055.id_sha512 - id_aes128_wrap = rfc3565.id_aes128_wrap id_aes256_wrap = rfc3565.id_aes256_wrap diff --git a/pyasn1_modules/rfc8418.py b/pyasn1_modules/rfc8418.py index 4962f26..6e76487 100644 --- a/pyasn1_modules/rfc8418.py +++ b/pyasn1_modules/rfc8418.py @@ -29,7 +29,6 @@ dhSinglePass_stdDH_sha384kdf_scheme = univ.ObjectIdentifier('1.3.133.16.840.63.0 dhSinglePass_stdDH_sha512kdf_scheme = univ.ObjectIdentifier('1.3.133.16.840.63.0.11.3') - dhSinglePass_stdDH_hkdf_sha256_scheme = univ.ObjectIdentifier('1.2.840.113549.1.9.16.3.19') dhSinglePass_stdDH_hkdf_sha384_scheme = univ.ObjectIdentifier('1.2.840.113549.1.9.16.3.20') diff --git a/pyasn1_modules/rfc8520.py b/pyasn1_modules/rfc8520.py new file mode 100644 index 0000000..8e4adf3 --- /dev/null +++ b/pyasn1_modules/rfc8520.py @@ -0,0 +1,56 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# Modified by Russ Housley to add maps for use with opentypes. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# X.509 Extensions for MUD URL and MUD Signer; +# Object Identifier for CMS Content Type for a MUD file +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc8520.txt +# + +from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful +from pyasn1_modules import rfc5280 + + +# X.509 Extension for MUD URL + +id_pe_mud_url = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.25') + +class MUDURLSyntax(char.IA5String): + pass + + +# X.509 Extension for MUD Signer + +id_pe_mudsigner = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.30') + +class MUDsignerSyntax(rfc5280.Name): + pass + + +# Object Identifier for CMS Content Type for a MUD file + +id_ct_mudtype = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.41') + + +# Map of Certificate Extension OIDs to Extensions +# To be added to the ones that are in rfc5280.py + +certificateExtensionsMapUpdate = { + id_pe_mud_url: MUDURLSyntax(), + id_pe_mudsigner: MUDsignerSyntax(), +} + + +# Map of Content Type OIDs to Content Types +# To be added to the ones that are in rfc5652.py + +cmsContentTypesMapUpdate = { + id_ct_mudtype: univ.OctetString(), +}
\ No newline at end of file diff --git a/pyasn1_modules/rfc8619.py b/pyasn1_modules/rfc8619.py new file mode 100644 index 0000000..0aaa811 --- /dev/null +++ b/pyasn1_modules/rfc8619.py @@ -0,0 +1,45 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Algorithm Identifiers for HKDF +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc8619.txt +# + +from pyasn1.type import univ + +from pyasn1_modules import rfc5280 + + +# Object Identifiers + +id_alg_hkdf_with_sha256 = univ.ObjectIdentifier('1.2.840.113549.1.9.16.3.28') + + +id_alg_hkdf_with_sha384 = univ.ObjectIdentifier('1.2.840.113549.1.9.16.3.29') + + +id_alg_hkdf_with_sha512 = univ.ObjectIdentifier('1.2.840.113549.1.9.16.3.30') + + +# Key Derivation Algorithm Identifiers + +kda_hkdf_with_sha256 = rfc5280.AlgorithmIdentifier() +kda_hkdf_with_sha256['algorithm'] = id_alg_hkdf_with_sha256 +# kda_hkdf_with_sha256['parameters'] are absent + + +kda_hkdf_with_sha384 = rfc5280.AlgorithmIdentifier() +kda_hkdf_with_sha384['algorithm'] = id_alg_hkdf_with_sha384 +# kda_hkdf_with_sha384['parameters'] are absent + + +kda_hkdf_with_sha512 = rfc5280.AlgorithmIdentifier() +kda_hkdf_with_sha512['algorithm'] = id_alg_hkdf_with_sha512 +# kda_hkdf_with_sha512['parameters'] are absent diff --git a/requirements.txt b/requirements.txt index 2c51a6a..cb1feb0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -pyasn1>=0.4.1,<0.5.0 +pyasn1>=0.4.6,<0.5.0 @@ -69,7 +69,7 @@ try: params = { 'zip_safe': True, - 'install_requires': ['pyasn1>=0.4.1,<0.5.0'] + 'install_requires': ['pyasn1>=0.4.6,<0.5.0'] } except ImportError: @@ -82,7 +82,7 @@ except ImportError: if sys.version_info[:2] > (2, 4): params = { - 'requires': ['pyasn1(>=0.4.1,<0.5.0)'] + 'requires': ['pyasn1(>=0.4.6,<0.5.0)'] } else: params = { @@ -100,7 +100,7 @@ params.update( 'url': 'https://github.com/etingof/pyasn1-modules', 'platforms': ['any'], 'classifiers': [x for x in classifiers.split('\n') if x], - 'license': 'BSD', + 'license': 'BSD-2-Clause', 'packages': ['pyasn1_modules']} ) diff --git a/tests/__main__.py b/tests/__main__.py index fe1deae..08300c2 100644 --- a/tests/__main__.py +++ b/tests/__main__.py @@ -11,30 +11,50 @@ except ImportError: import unittest suite = unittest.TestLoader().loadTestsFromNames( - ['tests.test_rfc2314.suite', + ['tests.test_pem.suite', + 'tests.test_rfc2314.suite', 'tests.test_rfc2315.suite', 'tests.test_rfc2437.suite', 'tests.test_rfc2459.suite', 'tests.test_rfc2511.suite', 'tests.test_rfc2560.suite', + 'tests.test_rfc2634.suite', 'tests.test_rfc2986.suite', + 'tests.test_rfc3161.suite', + 'tests.test_rfc3274.suite', + 'tests.test_rfc3560.suite', 'tests.test_rfc3565.suite', + 'tests.test_rfc3709.suite', 'tests.test_rfc3779.suite', - 'tests.test_rfc4055.suite' - 'tests.test_rfc4108.suite' + 'tests.test_rfc4055.suite', + 'tests.test_rfc4073.suite', + 'tests.test_rfc4108.suite', 'tests.test_rfc4210.suite', - 'tests.test_rfc5083.suite' - 'tests.test_rfc5084.suite' + 'tests.test_rfc5035.suite', + 'tests.test_rfc5083.suite', + 'tests.test_rfc5084.suite', 'tests.test_rfc5208.suite', 'tests.test_rfc5280.suite', + 'tests.test_rfc5480.suite', + 'tests.test_rfc5649.suite', 'tests.test_rfc5652.suite', - 'tests.test_rfc5958.suite' - 'tests.test_rfc8103.suite' + 'tests.test_rfc5915.suite', + 'tests.test_rfc5940.suite', + 'tests.test_rfc5958.suite', + 'tests.test_rfc6019.suite', + 'tests.test_rfc7191.suite', + 'tests.test_rfc7296.suite', + 'tests.test_rfc8103.suite', 'tests.test_rfc8226.suite', - 'tests.test_rfc8410.suite' - 'tests.test_rfc8418.suite'] + 'tests.test_rfc8410.suite', + 'tests.test_rfc8418.suite', + 'tests.test_rfc8520.suite', + 'tests.test_rfc8619.suite'] ) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_pem.py b/tests/test_pem.py new file mode 100644 index 0000000..02604fc --- /dev/null +++ b/tests/test_pem.py @@ -0,0 +1,111 @@ +# +# This file is part of pyasn1-modules software. +# +# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com> +# License: http://snmplabs.com/pyasn1/license.html +# +import sys + +from pyasn1.compat.octets import ints2octs + +from pyasn1_modules import pem + +try: + import unittest2 as unittest + +except ImportError: + import unittest + + +class PemTestCase(unittest.TestCase): + pem_text = """\ +MIIDATCCAekCAQAwgZkxCzAJBgNVBAYTAlJVMRYwFAYDVQQIEw1Nb3Njb3cgUmVn +aW9uMQ8wDQYDVQQHEwZNb3Njb3cxGjAYBgNVBAoTEVNOTVAgTGFib3JhdG9yaWVz +MQwwCgYDVQQLFANSJkQxFTATBgNVBAMTDHNubXBsYWJzLmNvbTEgMB4GCSqGSIb3 +DQEJARYRaW5mb0Bzbm1wbGFicy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC9n2NfGS98JDBmAXQn+vNUyPB3QPYC1cwpX8UMYh9MdAmBZJCnvXrQ +Pp14gNAv6AQKxefmGES1b+Yd+1we9HB8AKm1/8xvRDUjAvy4iO0sqFCPvIfSujUy +pBcfnR7QE2itvyrMxCDSEVnMhKdCNb23L2TptUmpvLcb8wfAMLFsSu2yaOtJysep +oH/mvGqlRv2ti2+E2YA0M7Pf83wyV1XmuEsc9tQ225rprDk2uyshUglkDD2235rf +0QyONq3Aw3BMrO9ss1qj7vdDhVHVsxHnTVbEgrxEWkq2GkVKh9QReMZ2AKxe40j4 +og+OjKXguOCggCZHJyXKxccwqCaeCztbAgMBAAGgIjAgBgkqhkiG9w0BCQIxExMR +U05NUCBMYWJvcmF0b3JpZXMwDQYJKoZIhvcNAQEFBQADggEBAAihbwmN9M2bsNNm +9KfxqiGMqqcGCtzIlpDz/2NVwY93cEZsbz3Qscc0QpknRmyTSoDwIG+1nUH0vzkT +Nv8sBmp9I1GdhGg52DIaWwL4t9O5WUHgfHSJpPxZ/zMP2qIsdPJ+8o19BbXRlufc +73c03H1piGeb9VcePIaulSHI622xukI6f4Sis49vkDaoi+jadbEEb6TYkJQ3AMRD +WdApGGm0BePdLqboW1Yv70WRRFFD8sxeT7Yw4qrJojdnq0xMHPGfKpf6dJsqWkHk +b5DRbjil1Zt9pJuF680S9wtBzSi0hsMHXR9TzS7HpMjykL2nmCVY6A78MZapsCzn +GGbx7DI= +""" + + def testReadBase64fromText(self): + + binary = pem.readBase64fromText(self.pem_text) + + assert binary + + expected = [ + 48, 130, 3, 1, 48, 130, 1, 233, 2, 1, 0, 48, 129, 153, 49, 11, 48, + 9, 6, 3, 85, 4, 6, 19, 2, 82, 85, 49, 22, 48, 20, 6, 3, 85, 4, 8, + 19, 13, 77, 111, 115, 99, 111, 119, 32, 82, 101, 103, 105, 111, + 110, 49, 15, 48, 13, 6, 3, 85, 4, 7, 19, 6, 77, 111, 115, 99, 111, + 119, 49, 26, 48, 24, 6, 3, 85, 4, 10, 19, 17, 83, 78, 77, 80, 32, + 76, 97, 98, 111, 114, 97, 116, 111, 114, 105, 101, 115, 49, 12, + 48, 10, 6, 3, 85, 4, 11, 20, 3, 82, 38, 68, 49, 21, 48, 19, 6, 3, + 85, 4, 3, 19, 12, 115, 110, 109, 112, 108, 97, 98, 115, 46, 99, + 111, 109, 49, 32, 48, 30, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 1, + 22, 17, 105, 110, 102, 111, 64, 115, 110, 109, 112, 108, 97, 98, + 115, 46, 99, 111, 109, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, + 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, + 130, 1, 1, 0, 189, 159, 99, 95, 25, 47, 124, 36, 48, 102, 1, 116, + 39, 250, 243, 84, 200, 240, 119, 64, 246, 2, 213, 204, 41, 95, 197, + 12, 98, 31, 76, 116, 9, 129, 100, 144, 167, 189, 122, 208, 62, 157, + 120, 128, 208, 47, 232, 4, 10, 197, 231, 230, 24, 68, 181, 111, + 230, 29, 251, 92, 30, 244, 112, 124, 0, 169, 181, 255, 204, 111, + 68, 53, 35, 2, 252, 184, 136, 237, 44, 168, 80, 143, 188, 135, 210, + 186, 53, 50, 164, 23, 31, 157, 30, 208, 19, 104, 173, 191, 42, 204, + 196, 32, 210, 17, 89, 204, 132, 167, 66, 53, 189, 183, 47, 100, + 233, 181, 73, 169, 188, 183, 27, 243, 7, 192, 48, 177, 108, 74, + 237, 178, 104, 235, 73, 202, 199, 169, 160, 127, 230, 188, 106, + 165, 70, 253, 173, 139, 111, 132, 217, 128, 52, 51, 179, 223, 243, + 124, 50, 87, 85, 230, 184, 75, 28, 246, 212, 54, 219, 154, 233, + 172, 57, 54, 187, 43, 33, 82, 9, 100, 12, 61, 182, 223, 154, 223, + 209, 12, 142, 54, 173, 192, 195, 112, 76, 172, 239, 108, 179, 90, + 163, 238, 247, 67, 133, 81, 213, 179, 17, 231, 77, 86, 196, 130, + 188, 68, 90, 74, 182, 26, 69, 74, 135, 212, 17, 120, 198, 118, 0, + 172, 94, 227, 72, 248, 162, 15, 142, 140, 165, 224, 184, 224, 160, + 128, 38, 71, 39, 37, 202, 197, 199, 48, 168, 38, 158, 11, 59, 91, 2, + 3, 1, 0, 1, 160, 34, 48, 32, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, + 2, 49, 19, 19, 17, 83, 78, 77, 80, 32, 76, 97, 98, 111, 114, 97, + 116, 111, 114, 105, 101, 115, 48, 13, 6, 9, 42, 134, 72, 134, 247, + 13, 1, 1, 5, 5, 0, 3, 130, 1, 1, 0, 8, 161, 111, 9, 141, 244, 205, + 155, 176, 211, 102, 244, 167, 241, 170, 33, 140, 170, 167, 6, 10, + 220, 200, 150, 144, 243, 255, 99, 85, 193, 143, 119, 112, 70, 108, + 111, 61, 208, 177, 199, 52, 66, 153, 39, 70, 108, 147, 74, 128, 240, + 32, 111, 181, 157, 65, 244, 191, 57, 19, 54, 255, 44, 6, 106, 125, + 35, 81, 157, 132, 104, 57, 216, 50, 26, 91, 2, 248, 183, 211, 185, + 89, 65, 224, 124, 116, 137, 164, 252, 89, 255, 51, 15, 218, 162, + 44, 116, 242, 126, 242, 141, 125, 5, 181, 209, 150, 231, 220, 239, + 119, 52, 220, 125, 105, 136, 103, 155, 245, 87, 30, 60, 134, 174, + 149, 33, 200, 235, 109, 177, 186, 66, 58, 127, 132, 162, 179, 143, + 111, 144, 54, 168, 139, 232, 218, 117, 177, 4, 111, 164, 216, 144, + 148, 55, 0, 196, 67, 89, 208, 41, 24, 105, 180, 5, 227, 221, 46, + 166, 232, 91, 86, 47, 239, 69, 145, 68, 81, 67, 242, 204, 94, 79, + 182, 48, 226, 170, 201, 162, 55, 103, 171, 76, 76, 28, 241, 159, + 42, 151, 250, 116, 155, 42, 90, 65, 228, 111, 144, 209, 110, 56, + 165, 213, 155, 125, 164, 155, 133, 235, 205, 18, 247, 11, 65, 205, + 40, 180, 134, 195, 7, 93, 31, 83, 205, 46, 199, 164, 200, 242, 144, + 189, 167, 152, 37, 88, 232, 14, 252, 49, 150, 169, 176, 44, 231, + 24, 102, 241, 236, 50 + ] + + assert ints2octs(expected) == binary + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc2314.py b/tests/test_rfc2314.py index 985e504..f303927 100644 --- a/tests/test_rfc2314.py +++ b/tests/test_rfc2314.py @@ -57,4 +57,7 @@ GGbx7DI= suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc2315.py b/tests/test_rfc2315.py index e65ce80..829099f 100644 --- a/tests/test_rfc2315.py +++ b/tests/test_rfc2315.py @@ -155,14 +155,18 @@ Kv0xuR3b3Le+ZqolT8wQELd5Mmw5JPofZ+O2cGNvet8tYwOKFjEA def testDerCodecDecodeOpenTypes(self): substrate = pem.readBase64fromText(self.pem_text_reordered) - asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec, decodeOpenTypes=True) assert not rest assert asn1Object.prettyPrint() - assert der_encoder.encode(asn1Object) == substrate + assert der_encoder.encode( + asn1Object, omitEmptyOptionals=False) == substrate + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc2437.py b/tests/test_rfc2437.py index 7eaedd6..2490d10 100644 --- a/tests/test_rfc2437.py +++ b/tests/test_rfc2437.py @@ -47,4 +47,7 @@ n8lDw3JT6NjvMnD6aM8KBsLyhazWSVVkaUSqmJzgCF0= suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc2459.py b/tests/test_rfc2459.py index e6335f4..4b54e44 100644 --- a/tests/test_rfc2459.py +++ b/tests/test_rfc2459.py @@ -137,8 +137,10 @@ INow2I3/ks+0MxDabTY= assert der_encoder.encode(asn1Object) == substrate - suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc2511.py b/tests/test_rfc2511.py index 327b561..494d017 100644 --- a/tests/test_rfc2511.py +++ b/tests/test_rfc2511.py @@ -49,4 +49,7 @@ xfu5YVWi81/fw8QQ6X6YGHFQkomLd7jxakVyjxSng9BhO6GpjJNF suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc2560.py b/tests/test_rfc2560.py index 79f8aad..fd6db37 100644 --- a/tests/test_rfc2560.py +++ b/tests/test_rfc2560.py @@ -81,4 +81,7 @@ HAESdf7nebz1wtqAOXE1jWF/y8g= suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc2634.py b/tests/test_rfc2634.py new file mode 100644 index 0000000..d57315b --- /dev/null +++ b/tests/test_rfc2634.py @@ -0,0 +1,184 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# + +import sys + +from pyasn1.codec.der.decoder import decode as der_decode +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1_modules import pem +from pyasn1_modules import rfc5652 +from pyasn1_modules import rfc2634 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class SignedMessageTestCase(unittest.TestCase): + signed_message_pem_text = """\ +MIIFLgYJKoZIhvcNAQcCoIIFHzCCBRsCAQExDTALBglghkgBZQMEAgIwUQYJKoZI +hvcNAQcBoEQEQkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbg0KDQpXYXRzb24sIGNv +bWUgaGVyZSAtIEkgd2FudCB0byBzZWUgeW91LqCCAnwwggJ4MIIB/qADAgECAgkA +pbNUKBuwbjswCgYIKoZIzj0EAwMwPzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlZB +MRAwDgYDVQQHDAdIZXJuZG9uMREwDwYDVQQKDAhCb2d1cyBDQTAeFw0xOTA1Mjkx +NDQ1NDFaFw0yMDA1MjgxNDQ1NDFaMHAxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJW +QTEQMA4GA1UEBxMHSGVybmRvbjEQMA4GA1UEChMHRXhhbXBsZTEOMAwGA1UEAxMF +QWxpY2UxIDAeBgkqhkiG9w0BCQEWEWFsaWNlQGV4YW1wbGUuY29tMHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAE+M2fBy/sRA6V1pKFqecRTE8+LuAHtZxes1wmJZrBBg+b +z7uYZfYQxI3dVB0YCSD6Mt3yXFlnmfBRwoqyArbjIBYrDbHBv2k8Csg2DhQ7qs/w +to8hMKoFgkcscqIbiV7Zo4GUMIGRMAsGA1UdDwQEAwIHgDBCBglghkgBhvhCAQ0E +NRYzVGhpcyBjZXJ0aWZpY2F0ZSBjYW5ub3QgYmUgdHJ1c3RlZCBmb3IgYW55IHB1 +cnBvc2UuMB0GA1UdDgQWBBTEuloOPnrjPIGw9AKqaLsW4JYONTAfBgNVHSMEGDAW +gBTyNds0BNqlVfK9aQOZsGLs4hUIwTAKBggqhkjOPQQDAwNoADBlAjBjuR/RNbgL +3kRhmn+PJTeKaL9sh/oQgHOYTgLmSnv3+NDCkhfKuMNoo/tHrkmihYgCMQC94Mae +rDIrQpi0IDh+v0QSAv9rMife8tClafXWtDwwL8MS7oAh0ymT446Uizxx3PUxggIy +MIICLgIBATBMMD8xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UEBwwH +SGVybmRvbjERMA8GA1UECgwIQm9ndXMgQ0ECCQCls1QoG7BuOzALBglghkgBZQME +AgKgggFXMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8X +DTE5MDUyOTE4MjMxOVowJQYLKoZIhvcNAQkQAgcxFgQUAbWZQYhLO5wtUgsOCGtT +4V3aNhUwLwYLKoZIhvcNAQkQAgQxIDAeDBFXYXRzb24sIGNvbWUgaGVyZQYJKoZI +hvcNAQcBMDUGCyqGSIb3DQEJEAICMSYxJAIBAQYKKwYBBAGBrGABARMTQm9hZ3Vz +IFByaXZhY3kgTWFyazA/BgkqhkiG9w0BCQQxMgQwtuQipP2CZx7U96rGbUT06LC5 +jVFYccZW5/CaNvpcrOPiChDm2vI3m4k300z5mSZsME0GCyqGSIb3DQEJEAIBMT4w +PAQgx08hD2QnVwj1DoeRELNtdZ0PffW4BQIvcwwVc/goU6OAAQEwFTATgRFhbGlj +ZUBleGFtcGxlLmNvbTAKBggqhkjOPQQDAwRnMGUCMAFFVP2gYFLTbaxvV5J2ICNM +Nk/K4pXbj5Zvj3dcCeC4+OUYyG3ZW5lOtKqaabEAXAIxALDg1WOouhkDfwuQdgBi +mNTr0mjYeUWRe/15IsWNx+kuFcLDr71DFHvMFY5M3sdfMA== +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.signed_message_pem_text) + asn1Object, rest = der_decode (substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + sd, rest = der_decode(asn1Object['content'], asn1Spec=rfc5652.SignedData()) + assert not rest + assert sd.prettyPrint() + assert der_encode(sd) == asn1Object['content'] + + for sa in sd['signerInfos'][0]['signedAttrs']: + sat = sa['attrType'] + sav0 = sa['attrValues'][0] + + if sat in rfc2634.ESSAttributeMap.keys(): + sav, rest = der_decode(sav0, asn1Spec=rfc2634.ESSAttributeMap[sat]) + assert not rest + assert sav.prettyPrint() + assert der_encode(sav) == sav0 + + +class SignedReceiptTestCase(unittest.TestCase): + signed_receipt_pem_text = """\ +MIIE3gYJKoZIhvcNAQcCoIIEzzCCBMsCAQMxDTALBglghkgBZQMEAgEwga4GCyq +GSIb3DQEJEAEBoIGeBIGbMIGYAgEBBgkqhkiG9w0BBwEEIMdPIQ9kJ1cI9Q6HkR +CzbXWdD331uAUCL3MMFXP4KFOjBGYwZAIwOLV5WCbYjy5HLHE69IqXQQHVDJQzm +o18WwkFrEYH3EMsvpXEIGqsFTFN6NV4VBe9AjA5fGOCP5IhI32YqmGfs+zDlqZy +b2xSX6Gr/IfCIm0angfOI39g7lAZDyivjh5H/oSgggJ3MIICczCCAfqgAwIBAgI +JAKWzVCgbsG48MAoGCCqGSM49BAMDMD8xCzAJBgNVBAYTAlVTMQswCQYDVQQIDA +JWQTEQMA4GA1UEBwwHSGVybmRvbjERMA8GA1UECgwIQm9ndXMgQ0EwHhcNMTkwN +TI5MTkyMDEzWhcNMjAwNTI4MTkyMDEzWjBsMQswCQYDVQQGEwJVUzELMAkGA1UE +CBMCVkExEDAOBgNVBAcTB0hlcm5kb24xEDAOBgNVBAoTB0V4YW1wbGUxDDAKBgN +VBAMTA0JvYjEeMBwGCSqGSIb3DQEJARYPYm9iQGV4YW1wbGUuY29tMHYwEAYHKo +ZIzj0CAQYFK4EEACIDYgAEMaRiVS8WvN8Ycmpfq75jBbOMUukNfXAg6AL0JJBXt +IFAuIJcZVlkLn/xbywkcMLHK/O+w9RWUQa2Cjw+h8b/1Cl+gIpqLtE558bD5PfM +2aYpJ/YE6yZ9nBfTQs7z1TH5o4GUMIGRMAsGA1UdDwQEAwIHgDBCBglghkgBhvh +CAQ0ENRYzVGhpcyBjZXJ0aWZpY2F0ZSBjYW5ub3QgYmUgdHJ1c3RlZCBmb3IgYW +55IHB1cnBvc2UuMB0GA1UdDgQWBBTKa2Zy3iybV3+YjuLDKtNmjsIapTAfBgNVH +SMEGDAWgBTyNds0BNqlVfK9aQOZsGLs4hUIwTAKBggqhkjOPQQDAwNnADBkAjAV +boS6OfEYQomLDi2RUkd71hzwwiQZztbxNbosahIzjR8ZQaHhjdjJlrP/T6aXBws +CMDfRweYz3Ce4E4wPfoqQnvqpM7ZlfhstjQQGOsWAtIIfqW/l+TgCO8ux3XLV6f +j36zGCAYkwggGFAgEBMEwwPzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlZBMRAwD +gYDVQQHDAdIZXJuZG9uMREwDwYDVQQKDAhCb2d1cyBDQQIJAKWzVCgbsG48MAsG +CWCGSAFlAwQCAaCBrjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQEwHAYJKoZ +IhvcNAQkFMQ8XDTE5MDUyOTE5MzU1NVowLwYJKoZIhvcNAQkEMSIEIGb9Hm2kCn +M0CYNpZU4Uj7dN0AzOieIn9sDqZMcIcZrEMEEGCyqGSIb3DQEJEAIFMTIEMBZze +HVja7fQ62ywyh8rtKzBP1WJooMdZ+8c6pRqfIESYIU5bQnH99OPA51QCwdOdjAK +BggqhkjOPQQDAgRoMGYCMQDZiT22xgab6RFMAPvN4fhWwzx017EzttD4VaYrpbo +lropBdPJ6jIXiZQgCwxbGTCwCMQClaQ9K+L5LTeuW50ZKSIbmBZQ5dxjtnK3OlS +7hYRi6U0JKZmWbbuS8vFIgX7eIkd8= +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.signed_receipt_pem_text) + asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + sd, rest = der_decode (asn1Object['content'], asn1Spec=rfc5652.SignedData()) + assert not rest + assert sd.prettyPrint() + assert der_encode(sd) == asn1Object['content'] + + assert sd['encapContentInfo']['eContentType'] == rfc2634.id_ct_receipt + receipt, rest = der_decode(sd['encapContentInfo']['eContent'], + asn1Spec=rfc2634.Receipt()) + assert not rest + assert receipt.prettyPrint() + assert der_encode(receipt) == sd['encapContentInfo']['eContent'] + assert receipt['version'] == rfc2634.ESSVersion().subtype(value='v1') + + for sa in sd['signerInfos'][0]['signedAttrs']: + sat = sa['attrType'] + sav0 = sa['attrValues'][0] + + if sat in rfc2634.ESSAttributeMap.keys(): + sav, rest = der_decode(sav0, asn1Spec=rfc2634.ESSAttributeMap[sat]) + assert not rest + assert sav.prettyPrint() + assert der_encode(sav) == sav0 + + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.signed_receipt_pem_text) + rfc5652.cmsContentTypesMap.update(rfc2634.cmsContentTypesMapUpdate) + rfc5652.cmsAttributesMap.update(rfc2634.ESSAttributeMap) + asn1Object, rest = der_decode(substrate, + asn1Spec=self.asn1Spec, decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] in rfc5652.cmsContentTypesMap.keys() + assert asn1Object['contentType'] == rfc5652.id_signedData + + sd = asn1Object['content'] + assert sd['version'] == rfc5652.CMSVersion().subtype(value='v3') + assert sd['encapContentInfo']['eContentType'] in rfc5652.cmsContentTypesMap.keys() + assert sd['encapContentInfo']['eContentType'] == rfc2634.id_ct_receipt + + for sa in sd['signerInfos'][0]['signedAttrs']: + assert sa['attrType'] in rfc5652.cmsAttributesMap.keys() + if sa['attrType'] == rfc2634.id_aa_msgSigDigest: + sa['attrValues'][0].prettyPrint()[:10] == '0x167378' + + # Since receipt is inside an OCTET STRING, decodeOpenTypes=True cannot + # automatically decode it + receipt, rest = der_decode(sd['encapContentInfo']['eContent'], + asn1Spec=rfc5652.cmsContentTypesMap[sd['encapContentInfo']['eContentType']]) + assert receipt['version'] == rfc2634.ESSVersion().subtype(value='v1') + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc2986.py b/tests/test_rfc2986.py index 8dbad8b..92834ee 100644 --- a/tests/test_rfc2986.py +++ b/tests/test_rfc2986.py @@ -9,8 +9,13 @@ import sys from pyasn1.codec.der import decoder as der_decoder from pyasn1.codec.der import encoder as der_encoder +from pyasn1.type import char +from pyasn1.type import univ + from pyasn1_modules import pem from pyasn1_modules import rfc2986 +from pyasn1_modules import rfc5280 + try: import unittest2 as unittest @@ -51,8 +56,41 @@ fi6h7i9VVAZpslaKFfkNg12gLbbsCB1q36l5VXjHY/qe0FIUa9ogRrOi assert asn1Object.prettyPrint() assert der_encoder.encode(asn1Object) == substrate + def testOpenTypes(self): + algorithmIdentifierMapUpdate = { + univ.ObjectIdentifier('1.2.840.113549.1.1.1'): univ.Null(""), + univ.ObjectIdentifier('1.2.840.113549.1.1.5'): univ.Null(""), + univ.ObjectIdentifier('1.2.840.113549.1.1.11'): univ.Null(""), + } + + rfc5280.algorithmIdentifierMap.update(algorithmIdentifierMapUpdate) + substrate = pem.readBase64fromText(self.pem_text) + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=rfc2986.CertificationRequest(), + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + + assert der_encoder.encode(asn1Object) == substrate + + for rdn in asn1Object['certificationRequestInfo']['subject']['rdnSequence']: + for atv in rdn: + if atv['type'] == rfc5280.id_at_countryName: + assert atv['value'] == char.PrintableString('US') + else: + assert len(atv['value']['utf8String']) > 2 + + spki_alg = asn1Object['certificationRequestInfo']['subjectPKInfo']['algorithm'] + assert spki_alg['parameters'] == univ.Null("") + + sig_alg = asn1Object['signatureAlgorithm'] + assert sig_alg['parameters'] == univ.Null("") + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc3161.py b/tests/test_rfc3161.py new file mode 100644 index 0000000..7068d5a --- /dev/null +++ b/tests/test_rfc3161.py @@ -0,0 +1,86 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# + +import sys + +from pyasn1.codec.der.decoder import decode as der_decode +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1_modules import pem +from pyasn1_modules import rfc3161 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class TSPQueryTestCase(unittest.TestCase): + tsp_query_pem_text = """\ +MFYCAQEwUTANBglghkgBZQMEAgMFAARAGu1DauxDZZv8F7l4EKIbS00U40mUKfBW5C0giEz0 +t1zOHCvK4A8i8zxwUXFHv4pAJZE+uFhZ+v53HTg9rLjO5Q== +""" + + def setUp(self): + self.asn1Spec = rfc3161.TimeStampReq() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.tsp_query_pem_text) + asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + +class TSPResponseTestCase(unittest.TestCase): + tsp_response_pem_text = """\ +MIIFMTADAgEAMIIFKAYJKoZIhvcNAQcCoIIFGTCCBRUCAQMxCzAJBgUrDgMCGgUAMIIBowYL +KoZIhvcNAQkQAQSgggGSBIIBjjCCAYoCAQEGBCoDBAEwUTANBglghkgBZQMEAgMFAARAGu1D +auxDZZv8F7l4EKIbS00U40mUKfBW5C0giEz0t1zOHCvK4A8i8zxwUXFHv4pAJZE+uFhZ+v53 +HTg9rLjO5QIDDwJEGA8yMDE5MDUxMDE4MzQxOFoBAf+gggERpIIBDTCCAQkxETAPBgNVBAoT +CEZyZWUgVFNBMQwwCgYDVQQLEwNUU0ExdjB0BgNVBA0TbVRoaXMgY2VydGlmaWNhdGUgZGln +aXRhbGx5IHNpZ25zIGRvY3VtZW50cyBhbmQgdGltZSBzdGFtcCByZXF1ZXN0cyBtYWRlIHVz +aW5nIHRoZSBmcmVldHNhLm9yZyBvbmxpbmUgc2VydmljZXMxGDAWBgNVBAMTD3d3dy5mcmVl +dHNhLm9yZzEiMCAGCSqGSIb3DQEJARYTYnVzaWxlemFzQGdtYWlsLmNvbTESMBAGA1UEBxMJ +V3VlcnpidXJnMQswCQYDVQQGEwJERTEPMA0GA1UECBMGQmF5ZXJuMYIDWjCCA1YCAQEwgaMw +gZUxETAPBgNVBAoTCEZyZWUgVFNBMRAwDgYDVQQLEwdSb290IENBMRgwFgYDVQQDEw93d3cu +ZnJlZXRzYS5vcmcxIjAgBgkqhkiG9w0BCQEWE2J1c2lsZXphc0BnbWFpbC5jb20xEjAQBgNV +BAcTCVd1ZXJ6YnVyZzEPMA0GA1UECBMGQmF5ZXJuMQswCQYDVQQGEwJERQIJAMHphhYNqOmC +MAkGBSsOAwIaBQCggYwwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJ +BTEPFw0xOTA1MTAxODM0MThaMCMGCSqGSIb3DQEJBDEWBBSuLICty7PQHx0Ynk0a3rGcCRrf +EjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBSRbaPYYOzKguNLxZ0Xk+fpaIdfFDANBgkqhkiG +9w0BAQEFAASCAgBFDVbGQ3L5GcaUBMtBnMW7x3S57QowQhhrTewvncY+3Nc2i6tlM1UEdxIp +3m2iMqaH/N2xIm2sU/L/lIwaT1XIS4bJ2Nn8UPjZu/prJrVUFTMjJ5LWkG55x6c5A4pa2xxS +N/kOV2e+6RHYlGvcDOvu2fzuz08hE+NjaHIPg3idU1cBsl0gTWZCTrxdXTLuuvHahxUAdQKm +gTdGPjIiOR4GYpaVxEAgulaBQLZU5MhfBTASI1LkljhiFeDBQMhTUeZoA59/OxgnQR1Zpca4 +ZuWuqnZImxziRQA1tX/6pjAo5eP1V+SLWYHeIO7ia/urGIK9AXd3jY3Ljq4h7R1E+RRKIseO +74mmtbJtCaiGL9H+6k164qC7U5fHBzKl3UboZtOUmNj10IJPUNyKQ5JPwCe6HEhbeXLRdh/8 +bjdqy56hBHyG1NRBqiTXTvj9LOzsJGIF5GjwyCT0B2hpvzdTdzNtfQ27HUUYgnYg0fGEpNpi +vyaW5qCh9S704IKB0m/fXlqiIfNVdqDr/aAHNww8CouZP2oFO61WXCspbFNPLubeqxd5P4o4 +dJzD4PKsurILdX7SL8pRI+O2UtJLwNB1t3LBLKfTZuOWoSBFvQwbqBsDEchrZIDZXSXMbXd6 +uuvuO3ZsRWuej+gso+nWi3CRnRc9Wb0++cq4s8YSLaYSj2pHMA== +""" + + def setUp(self): + self.asn1Spec = rfc3161.TimeStampResp() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.tsp_response_pem_text) + asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc3274.py b/tests/test_rfc3274.py new file mode 100644 index 0000000..a8137fd --- /dev/null +++ b/tests/test_rfc3274.py @@ -0,0 +1,81 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# + +import sys + +from pyasn1.codec.der.decoder import decode as der_decode +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1_modules import pem +from pyasn1_modules import rfc3274 +from pyasn1_modules import rfc5652 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class CompressedDataTestCase(unittest.TestCase): + compressed_data_pem_text = """\ +MIIB7wYLKoZIhvcNAQkQAQmgggHeMIIB2gIBADANBgsqhkiG9w0BCRADCDCCAcQG +CSqGSIb3DQEHAaCCAbUEggGxeJxVksGO1DAQRO/+ir4xK4VlNSAhcUPRrgRiLgw/ +0Il7Egu7bdntMOHraSezMJyixOWq19XpIwuxvP2xJvoEQld5lzw6Nub7Sw/vjx8/ +dJDq4F2ZyYJj+FqZ4Pj0dOzA0sUxFUC4xBxQ2gNqcTzBGEPKVApZY1EQsKn6vCaJ +U8Y0uxFOeowTwXllwSsc+tP5Qe9tOCCK8wjQ32zUcvcZSDMIJCOX4PQgMqQcF2c3 +Dq5hoAzxAmgXVN+JSqfUo6+2YclMhrwLjlHaVRVutplsZYs8rvBL2WblqN7CTD4B +MqAIjj8pd1ASUXMyNbXccWeDYd0sxlsGYIhVp3i1l6jgr3qtUeUehbIpQqnAoVSN +1IqKm7hZaI3EY2tLIR86RbD//ONCGb2HsPdnivvdqvrsZY51mlu+NjTjQhpKWz0p +FvRlWw9ae7+fVgKKie0SeFpIZYemoyuG5HUS2QY6fTk9N6zz+dsuUyr9Xghs5Ddi +1LbZbVoNHDyFNv19jL7qiv9uuLK/XTD3Kqct1JS822vS8vWXpMzYBtal/083rMap +XQ7u2qbaKFtZ7V96NH8ApkUFkg== +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.compressed_data_pem_text) + asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc3274.id_ct_compressedData + cd, rest = der_decode(asn1Object['content'], asn1Spec=rfc3274.CompressedData()) + assert not rest + assert cd.prettyPrint() + assert der_encode(cd) == asn1Object['content'] + + assert cd['compressionAlgorithm']['algorithm'] == rfc3274.id_alg_zlibCompress + assert cd['encapContentInfo']['eContentType'] == rfc5652.id_data + + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.compressed_data_pem_text) + + rfc5652.cmsContentTypesMap.update(rfc3274.cmsContentTypesMapUpdate) + asn1Object, rest = der_decode(substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc3274.id_ct_compressedData + cd = asn1Object['content'] + assert cd['compressionAlgorithm']['algorithm'] == rfc3274.id_alg_zlibCompress + assert cd['encapContentInfo']['eContentType'] == rfc5652.id_data + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc3560.py b/tests/test_rfc3560.py new file mode 100644 index 0000000..112381a --- /dev/null +++ b/tests/test_rfc3560.py @@ -0,0 +1,78 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# + +import sys + +from pyasn1.codec.der import decoder as der_decoder +from pyasn1.codec.der import encoder as der_encoder + +from pyasn1_modules import pem +from pyasn1_modules import rfc5280 +from pyasn1_modules import rfc3560 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class OAEPDefautTestCase(unittest.TestCase): + oaep_default_pem_text = "MAsGCSqGSIb3DQEBBw==" + + def setUp(self): + self.asn1Spec = rfc5280.AlgorithmIdentifier() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.oaep_default_pem_text) + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert asn1Object[0] == rfc3560.id_RSAES_OAEP + assert der_encoder.encode(asn1Object) == substrate + assert substrate == der_encoder.encode(asn1Object) + + +class OAEPSHA256TestCase(unittest.TestCase): + oaep_sha256_pem_text = "MDwGCSqGSIb3DQEBBzAvoA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQA=" + + def setUp(self): + self.asn1Spec = rfc5280.AlgorithmIdentifier() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.oaep_sha256_pem_text) + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert asn1Object[0] == rfc3560.id_RSAES_OAEP + assert der_encoder.encode(asn1Object) == substrate + assert substrate == der_encoder.encode(asn1Object) + + +class OAEPFullTestCase(unittest.TestCase): + oaep_full_pem_text = "MFMGCSqGSIb3DQEBBzBGoA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiFTATBgkqhkiG9w0BAQkEBmZvb2Jhcg==" + + def setUp(self): + self.asn1Spec = rfc5280.AlgorithmIdentifier() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.oaep_full_pem_text) + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert asn1Object[0] == rfc3560.id_RSAES_OAEP + assert der_encoder.encode(asn1Object) == substrate + assert substrate == der_encoder.encode(asn1Object) + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc3565.py b/tests/test_rfc3565.py index 8665950..99cb567 100644 --- a/tests/test_rfc3565.py +++ b/tests/test_rfc3565.py @@ -54,4 +54,7 @@ class AESCBCTestCase(unittest.TestCase): suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc3709.py b/tests/test_rfc3709.py new file mode 100644 index 0000000..a7d0ef8 --- /dev/null +++ b/tests/test_rfc3709.py @@ -0,0 +1,88 @@ +# +# This file is part of pyasn1-modules software. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +import sys + +from pyasn1.codec.der import decoder as der_decoder +from pyasn1.codec.der import encoder as der_encoder + +from pyasn1_modules import pem +from pyasn1_modules import rfc5280 +from pyasn1_modules import rfc3709 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class CertificateExtnTestCase(unittest.TestCase): + pem_text = """\ +MIIC9zCCAn2gAwIBAgIJAKWzVCgbsG46MAoGCCqGSM49BAMDMD8xCzAJBgNVBAYT +AlVTMQswCQYDVQQIDAJWQTEQMA4GA1UEBwwHSGVybmRvbjERMA8GA1UECgwIQm9n +dXMgQ0EwHhcNMTkwNTE0MTAwMjAwWhcNMjAwNTEzMTAwMjAwWjBlMQswCQYDVQQG +EwJVUzELMAkGA1UECBMCVkExEDAOBgNVBAcTB0hlcm5kb24xGzAZBgNVBAoTElZp +Z2lsIFNlY3VyaXR5IExMQzEaMBgGA1UEAxMRbWFpbC52aWdpbHNlYy5jb20wdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAATwUXZUseiOaqWdrClDCMbp9YFAM87LTmFirygp +zKDU9cfqSCg7zBDIphXCwMcS9zVWDoStCbcvN0jw5CljHcffzpHYX91P88SZRJ1w +4hawHjOsWxvM3AkYgZ5nfdlL7EajggEdMIIBGTALBgNVHQ8EBAMCB4AwQgYJYIZI +AYb4QgENBDUWM1RoaXMgY2VydGlmaWNhdGUgY2Fubm90IGJlIHRydXN0ZWQgZm9y +IGFueSBwdXJwb3NlLjAdBgNVHQ4EFgQU8jXbNATapVXyvWkDmbBi7OIVCMEwHwYD +VR0jBBgwFoAU8jXbNATapVXyvWkDmbBi7OIVCMEwgYUGCCsGAQUFBwEMBHkwd6J1 +oHMwcTBvMG0WCWltYWdlL3BuZzAzMDEwDQYJYIZIAWUDBAIBBQAEIJtBNrMSSNo+ +6Rwqwctmcy0qf68ilRuKEmlf3GLwGiIkMCsWKWh0dHA6Ly93d3cudmlnaWxzZWMu +Y29tL3ZpZ2lsc2VjX2xvZ28ucG5nMAoGCCqGSM49BAMDA2gAMGUCMGhfLH4kZaCD +H43A8m8mHCUpYt9unT0qYu4TCMaRuOTYEuqj3qtuwyLcfAGuXKp/oAIxAIrPY+3y +Pj22pmfmQi5w21UljqoTj/+lQLkU3wfy5BdVKBwI0GfEA+YL3ctSzPNqAA== +""" + + def setUp(self): + self.asn1Spec = rfc5280.Certificate() + + def testDerCodec(self): + + substrate = pem.readBase64fromText(self.pem_text) + + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + for extn in asn1Object['tbsCertificate']['extensions']: + + if extn['extnID'] == rfc3709.id_pe_logotype: + s = extn['extnValue'] + logotype, rest = der_decoder.decode(s, rfc3709.LogotypeExtn()) + assert not rest + assert logotype.prettyPrint() + assert der_encoder.encode(logotype) == s + ids = logotype['subjectLogo']['direct']['image'][0]['imageDetails'] + assert ids['mediaType'] == "image/png" + assert ids['logotypeURI'][0] == "http://www.vigilsec.com/vigilsec_logo.png" + + def testExtensionsMap(self): + substrate = pem.readBase64fromText(self.pem_text) + rfc5280.certificateExtensionsMap.update(rfc3709.certificateExtensionsMapUpdate) + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + for extn in asn1Object['tbsCertificate']['extensions']: + if extn['extnID'] in rfc5280.certificateExtensionsMap.keys(): + extnValue, rest = der_decoder.decode(extn['extnValue'], + asn1Spec=rfc5280.certificateExtensionsMap[extn['extnID']]) + assert der_encoder.encode(extnValue) == extn['extnValue'] + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc3779.py b/tests/test_rfc3779.py index bebe06c..081f69b 100644 --- a/tests/test_rfc3779.py +++ b/tests/test_rfc3779.py @@ -74,8 +74,27 @@ V+vo2L72yerdbsP9xjqvhZrLKfsLZjYK4SdYYthi assert as_ids.prettyPrint() assert der_encoder.encode(as_ids) == s + def testExtensionsMap(self): + substrate = pem.readBase64fromText(self.pem_text) + rfc5280.certificateExtensionsMap.update(rfc3779.certificateExtensionsMapUpdate) + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + for extn in asn1Object['tbsCertificate']['extensions']: + if extn['extnID'] == rfc3779.id_pe_ipAddrBlocks or \ + extn['extnID'] == rfc3779.id_pe_autonomousSysIds: + + extnValue, rest = der_decoder.decode(extn['extnValue'], + asn1Spec=rfc5280.certificateExtensionsMap[extn['extnID']]) + assert der_encoder.encode(extnValue) == extn['extnValue'] + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc4055.py b/tests/test_rfc4055.py index c5609c9..3bb319a 100644..100755 --- a/tests/test_rfc4055.py +++ b/tests/test_rfc4055.py @@ -11,6 +11,8 @@ import sys from pyasn1.codec.der import decoder as der_decoder from pyasn1.codec.der import encoder as der_encoder +from pyasn1.type import univ + from pyasn1_modules import pem from pyasn1_modules import rfc5280 from pyasn1_modules import rfc4055 @@ -36,6 +38,16 @@ class PSSDefautTestCase(unittest.TestCase): assert der_encoder.encode(asn1Object) == substrate assert substrate == der_encoder.encode(asn1Object) + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.pss_default_pem_text) + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + assert not asn1Object['parameters'].hasValue() + class PSSSHA512TestCase(unittest.TestCase): pss_sha512_pem_text = "MDwGCSqGSIb3DQEBCjAvoA8wDQYJYIZIAWUDBAIDBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIDBQA=" @@ -52,6 +64,17 @@ class PSSSHA512TestCase(unittest.TestCase): assert der_encoder.encode(asn1Object) == substrate assert substrate == der_encoder.encode(asn1Object) + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.pss_sha512_pem_text) + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + assert asn1Object['parameters'].hasValue() + assert asn1Object['parameters']['saltLength'] == 20 + class OAEPDefautTestCase(unittest.TestCase): oaep_default_pem_text = "MAsGCSqGSIb3DQEBBw==" @@ -68,6 +91,16 @@ class OAEPDefautTestCase(unittest.TestCase): assert der_encoder.encode(asn1Object) == substrate assert substrate == der_encoder.encode(asn1Object) + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.oaep_default_pem_text) + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + assert not asn1Object['parameters'].hasValue() + class OAEPSHA256TestCase(unittest.TestCase): oaep_sha256_pem_text = "MDwGCSqGSIb3DQEBBzAvoA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQA=" @@ -84,6 +117,19 @@ class OAEPSHA256TestCase(unittest.TestCase): assert der_encoder.encode(asn1Object) == substrate assert substrate == der_encoder.encode(asn1Object) + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.oaep_sha256_pem_text) + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + assert asn1Object['parameters'].hasValue() + oaep_p = asn1Object['parameters'] + assert oaep_p['hashFunc']['parameters'] == univ.Null("") + assert oaep_p['maskGenFunc']['parameters']['parameters'] == univ.Null("") + class OAEPFullTestCase(unittest.TestCase): oaep_full_pem_text = "MFMGCSqGSIb3DQEBBzBGoA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiFTATBgkqhkiG9w0BAQkEBmZvb2Jhcg==" @@ -100,8 +146,25 @@ class OAEPFullTestCase(unittest.TestCase): assert der_encoder.encode(asn1Object) == substrate assert substrate == der_encoder.encode(asn1Object) + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.oaep_full_pem_text) + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + assert asn1Object['parameters'].hasValue() + oaep_p = asn1Object['parameters'] + assert oaep_p['hashFunc']['parameters'] == univ.Null("") + assert oaep_p['maskGenFunc']['parameters']['parameters'] == univ.Null("") + assert oaep_p['pSourceFunc']['parameters'] == univ.OctetString(value='foobar') + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc4073.py b/tests/test_rfc4073.py new file mode 100644 index 0000000..34cebea --- /dev/null +++ b/tests/test_rfc4073.py @@ -0,0 +1,156 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# + +import sys + +from pyasn1.codec.der.decoder import decode as der_decode +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1.compat.octets import str2octs + +from pyasn1_modules import pem +from pyasn1_modules import rfc2634 +from pyasn1_modules import rfc4073 +from pyasn1_modules import rfc5652 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class ContentCollectionTestCase(unittest.TestCase): + pem_text = """\ +MIIG/QYLKoZIhvcNAQkQAROgggbsMIIG6DCCAWcGCyqGSIb3DQEJEAEUoIIBVjCC +AVIwgfEGCSqGSIb3DQEHAaCB4wSB4ENvbnRlbnQtVHlwZTogdGV4dC9wbGFpbgoK +UkZDIDQwNzMsIHB1Ymxpc2hlZCBpbiBNYXkgMjAwNSwgZGVzY3JpYmVzIGEgY29u +dmVudGlvbiBmb3IgdXNpbmcgdGhlCkNyeXB0b2dyYXBoaWMgTWVzc2FnZSBTeW50 +YXggKENNUykgdG8gcHJvdGVjdCBhIGNvbnRlbnQgY29sbGVjdGlvbi4gIElmCmRl +c2lyZWQsIGF0dHJpYnV0ZXMgY2FuIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgY29u +dGVudC4KMFwwMwYLKoZIhvcNAQkQAgQxJDAiDBVBYnN0cmFjdCBmb3IgUkZDIDQw +NzMGCSqGSIb3DQEHATAlBgsqhkiG9w0BCRACBzEWBBSkLSXBiRWvbwnJKb4EGb1X +FwCa3zCCBXkGCyqGSIb3DQEJEAEUoIIFaDCCBWQwggT9BgkqhkiG9w0BBwGgggTu +BIIE6kNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbgoKVGhlIGZvbGxvd2luZyBBU04u +MSBtb2R1bGUgZGVmaW5lcyB0aGUgc3RydWN0dXJlcyB0aGF0IGFyZSBuZWVkZWQg +dG8KaW1wbGVtZW50IHRoZSBzcGVjaWZpY2F0aW9uIGluIFJGQyA0MDczLiAgSXQg +aXMgZXhwZWN0ZWQgdG8gYmUgdXNlZCBpbgpjb25qdW5jdGlvbiB3aXRoIHRoZSBB +U04uMSBtb2R1bGVzIGluIFJGQyA1NjUyIGFuZCBSRkMgMzI3NC4KCiAgIENvbnRl +bnRDb2xsZWN0aW9uTW9kdWxlCiAgICAgeyBpc28oMSkgbWVtYmVyLWJvZHkoMikg +dXMoODQwKSByc2Fkc2koMTEzNTQ5KSBwa2NzKDEpCiAgICAgICBwa2NzLTkoOSkg +c21pbWUoMTYpIG1vZHVsZXMoMCkgMjYgfQoKICAgREVGSU5JVElPTlMgSU1QTElD +SVQgVEFHUyA6Oj0KICAgQkVHSU4KCiAgIElNUE9SVFMKICAgICBBdHRyaWJ1dGUs +IENvbnRlbnRJbmZvCiAgICAgICBGUk9NIENyeXB0b2dyYXBoaWNNZXNzYWdlU3lu +dGF4MjAwNCAtLSBbQ01TXQogICAgICAgICB7IGlzbygxKSBtZW1iZXItYm9keSgy +KSB1cyg4NDApIHJzYWRzaSgxMTM1NDkpCiAgICAgICAgICAgcGtjcygxKSBwa2Nz +LTkoOSkgc21pbWUoMTYpIG1vZHVsZXMoMCkgY21zLTIwMDEoMTQpIH07CgoKICAg +LS0gQ29udGVudCBDb2xsZWN0aW9uIENvbnRlbnQgVHlwZSBhbmQgT2JqZWN0IElk +ZW50aWZpZXIKCiAgIGlkLWN0LWNvbnRlbnRDb2xsZWN0aW9uIE9CSkVDVCBJREVO +VElGSUVSIDo6PSB7CiAgICAgICAgICAgaXNvKDEpIG1lbWJlci1ib2R5KDIpIHVz +KDg0MCkgcnNhZHNpKDExMzU0OSkgcGtjcygxKQogICAgICAgICAgIHBrY3M5KDkp +IHNtaW1lKDE2KSBjdCgxKSAxOSB9CgogICBDb250ZW50Q29sbGVjdGlvbiA6Oj0g +U0VRVUVOQ0UgU0laRSAoMS4uTUFYKSBPRiBDb250ZW50SW5mbwoKICAgLS0gQ29u +dGVudCBXaXRoIEF0dHJpYnV0ZXMgQ29udGVudCBUeXBlIGFuZCBPYmplY3QgSWRl +bnRpZmllcgoKICAgaWQtY3QtY29udGVudFdpdGhBdHRycyBPQkpFQ1QgSURFTlRJ +RklFUiA6Oj0gewogICAgICAgICAgIGlzbygxKSBtZW1iZXItYm9keSgyKSB1cyg4 +NDApIHJzYWRzaSgxMTM1NDkpIHBrY3MoMSkKICAgICAgICAgICBwa2NzOSg5KSBz +bWltZSgxNikgY3QoMSkgMjAgfQoKICAgQ29udGVudFdpdGhBdHRyaWJ1dGVzIDo6 +PSBTRVFVRU5DRSB7CiAgICAgICBjb250ZW50ICAgICBDb250ZW50SW5mbywKICAg +ICAgIGF0dHJzICAgICAgIFNFUVVFTkNFIFNJWkUgKDEuLk1BWCkgT0YgQXR0cmli +dXRlIH0KCiAgIEVORAowYTA4BgsqhkiG9w0BCRACBDEpMCcMGkFTTi4xIE1vZHVs +ZSBmcm9tIFJGQyA0MDczBgkqhkiG9w0BBwEwJQYLKoZIhvcNAQkQAgcxFgQUMbeK +buWO3egPDL8Kf7tBhzjIKLw= +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + def testDerCodec(self): + + def test_layer(substrate, content_type): + asn1Object, rest = der_decode(substrate, asn1Spec=layers[content_type]) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + if content_type == rfc4073.id_ct_contentWithAttrs: + for attr in asn1Object['attrs']: + assert attr['attrType'] in rfc5652.cmsAttributesMap.keys() + + return asn1Object + + rfc5652.cmsAttributesMap.update(rfc2634.ESSAttributeMap) + rfc5652.cmsContentTypesMap.update(rfc4073.cmsContentTypesMapUpdate) + layers = rfc5652.cmsContentTypesMap + + getNextLayer = { + rfc5652.id_ct_contentInfo: lambda x: x['contentType'], + rfc4073.id_ct_contentCollection: lambda x: x[0]['contentType'], + rfc4073.id_ct_contentWithAttrs: lambda x: x['content']['contentType'], + rfc5652.id_data: lambda x: None, + } + + getNextSubstrate = { + rfc5652.id_ct_contentInfo: lambda x: x['content'], + rfc4073.id_ct_contentCollection: lambda x: x[0]['content'], + rfc4073.id_ct_contentWithAttrs: lambda x: x['content']['content'], + rfc5652.id_data: lambda x: None, + } + + substrate = pem.readBase64fromText(self.pem_text) + + this_layer = rfc5652.id_ct_contentInfo + while this_layer != rfc5652.id_data: + if this_layer == rfc4073.id_ct_contentCollection: + asn1Object = test_layer(substrate, this_layer) + for ci in asn1Object: + substrate = ci['content'] + this_layer = ci['contentType'] + while this_layer != rfc5652.id_data: + asn1Object = test_layer(substrate, this_layer) + substrate = getNextSubstrate[this_layer](asn1Object) + this_layer = getNextLayer[this_layer](asn1Object) + else: + asn1Object = test_layer(substrate, this_layer) + substrate = getNextSubstrate[this_layer](asn1Object) + this_layer = getNextLayer[this_layer](asn1Object) + + def testOpenTypes(self): + + substrate = pem.readBase64fromText(self.pem_text) + + rfc5652.cmsAttributesMap.update(rfc2634.ESSAttributeMap) + rfc5652.cmsContentTypesMap.update(rfc4073.cmsContentTypesMapUpdate) + asn1Object, rest = der_decode(substrate, + asn1Spec=rfc5652.ContentInfo(), + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc4073.id_ct_contentCollection + for ci in asn1Object['content']: + assert ci['contentType'] in rfc5652.cmsContentTypesMap.keys() + assert ci['contentType'] == rfc4073.id_ct_contentWithAttrs + next_ci = ci['content']['content'] + assert next_ci['contentType'] in rfc5652.cmsContentTypesMap.keys() + assert next_ci['contentType'] == rfc5652.id_data + assert str2octs('Content-Type: text') in next_ci['content'] + + for attr in ci['content']['attrs']: + assert attr['attrType'] in rfc5652.cmsAttributesMap.keys() + if attr['attrType'] == rfc2634.id_aa_contentHint: + assert 'RFC 4073' in attr['attrValues'][0]['contentDescription'] + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc4108.py b/tests/test_rfc4108.py index 49514b1..aa5dfd2 100644 --- a/tests/test_rfc4108.py +++ b/tests/test_rfc4108.py @@ -23,7 +23,7 @@ except ImportError: class CMSFirmwareWrapperTestCase(unittest.TestCase): pem_text = """\ -MIIEdwYJKoZIhvcNAQcCoIIEaDCCBGQCAQExDTALBglghkgBZQMEAgEwggIVBgsq +MIIEvAYJKoZIhvcNAQcCoIIErTCCBKkCAQExDTALBglghkgBZQMEAgEwggIVBgsq hkiG9w0BCRABEKCCAgQEggIA3ntqPr5kDpx+//pgWGfHCH/Ht4pbenGwXv80txyE Y0I2mT9BUGz8ILkbhD7Xz89pBS5KhEJpthxH8WREJtvS+wL4BqYLt23wjWoZy5Gt 5dPzWgaNlV/aQ5AdfAY9ljmnNYnK8D8r8ur7bQM4cKUdxry+QA0nqXHMAOSpx4Um @@ -35,18 +35,20 @@ RJNFP9vpDM8CxJIqcobC5Kuv8b0GqGfGl6ouuQKEVMfBcrupgjk3oc3KL1iVdSr1 /D9dmiFiErDB3Fzr4+8Qz0aKedNE/1uvM+dhu9qjuRdkDzZ4S7txTfk6y9pG9iyk aEeTV2kElKXblgi+Cf0Ut4f5he8rt6jveHdMo9X36YiUQVvevj2cgN7lFivEnFYV QY0xugpP7lvEFDfsi2+0ozgP8EKOLYaCUKpuvttlYJ+vdtUFEijizEZ4cx02RsXm -EesxggI1MIICMQIBA4AUnutnybladNRNLxY5ZoDoAbXLpJwwCwYJYIZIAWUDBAIB -oHgwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEQMCkGCyqGSIb3DQEJEAIkMRoG -CysGAQQBjb9BAQEqBgsrBgEEAY2/QQEBMDAvBgkqhkiG9w0BCQQxIgQgAJfvuasB -4P6WDLOkOyvj33YPgZW4olHbidzyh1EKP9YwCwYJKoZIhvcNAQELBIIBgDn0y+4B -cCX7ICovWcyWf0IxNXx7+1VlYneAZ8pMBaKu+6q7jRFZ+QsQFFbQ1yPO/3Pr2wVb -UJSJAL4QCJDurJ42LdPQIOGIV2aWq70vl6B9yt6svEdjxJ3XkopwcCBXLcB1Hp9b -6wYZzSFCujOlsABJiz2gMD6wUT4lq7RJO31LEPxx/Va4Ftp1F4okmgL8VpMemihU -atRXpIhedfli+TWEtMmoxcX3paLcU7MmJFUAwkHmb8rSRF5VBy5QWcNgzzskof0W -mCR/8bZjqR/g3VlFPyz7zOCxG/wIdZVAb4O/QP8fC0GhyHNE+NX6d+GI8RPpRyMf -5RfCCsHwbApCv8+tpFslYzwvUTIFx0y9zVrnkz/UrDjZtrKxLC0oRJlnlnKR1unm -lbolB9c2p60/mZHwQhLM5CjeYcMX3mMVJo4jqag+8o48CibW50h8y21usKaeA9b0 -9EMxfG3KaaP5mMEOZMpeGdUKQSJYweDstxlrY5ajPbeOycdMv7tRNoLpyw== +EesxggJ6MIICdgIBA4AUnutnybladNRNLxY5ZoDoAbXLpJwwCwYJYIZIAWUDBAIB +oIG8MBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABEDArBgsqhkiG9w0BCRACJDEc +MBoGCysGAQQBjb9BAQEqBgsrBgEEAY2/QQEBMDAvBgkqhkiG9w0BCQQxIgQgAJfv +uasB4P6WDLOkOyvj33YPgZW4olHbidzyh1EKP9YwQAYLKoZIhvcNAQkQAikxMTAv +MAsGCWCGSAFlAwQCAQQgAJfvuasB4P6WDLOkOyvj33YPgZW4olHbidzyh1EKP9Yw +CwYJKoZIhvcNAQELBIIBgDivAlSLbMPPu+zV+pPcYpNp+A1mwVOytjMBzSo31kR/ +qEu+hVrDknAOk9IdCaDvcz612CcfNT85/KzrYvWWxOP2woU/vZj253SnndALpfNN +n3/crJjF6hKgkjUwoXebI7kuj5WCh2q5lkd6xUa+jkCw+CINcN43thtS66UsVI4d +mv02EvsS2cxPY/508uaQZ6AYAacm667bgX8xEjbzACMOeMCuvKQXWAuh3DkNk+gV +xizHDw7xZxXgMGMAnJglAeBtd3Si5ztILw9U2gKUqFn/nOgy+eW63JuU/q31/Hgg +ZATjyBznSzneTZrw8/ePoSCj7E9vBeCTUkeFbVB2tJK1iYDMblp6HUuwgYuGKXy/ +ZwKL3GvB11qg7ntdEyjdLq0xcVrht/K0d2dPo4iO4Ac7c1xbFMDAlWOt4FMPWh6O +iTh55YvT7hAJjTbB5ebgMA9QJnAczQPFnaIePnlFrkETd3YyLK4yHwnoIGo1GiW/ +dsnhVtIdkPtfJIvcYteYJg== """ def setUp(self): @@ -67,14 +69,49 @@ lbolB9c2p60/mZHwQhLM5CjeYcMX3mMVJo4jqag+8o48CibW50h8y21usKaeA9b0 assert inner['encapContentInfo']['eContentType'] == rfc4108.id_ct_firmwarePackage assert inner['encapContentInfo']['eContent'] - found_target_hardware_identifier_attribute = False + attribute_list = [ ] for attr in inner['signerInfos'][0]['signedAttrs']: + attribute_list.append(attr['attrType']) if attr['attrType'] == rfc4108.id_aa_targetHardwareIDs: - found_target_hardware_identifier_attribute = True - assert found_target_hardware_identifier_attribute + av, rest = der_decode(attr['attrValues'][0], + asn1Spec=rfc4108.TargetHardwareIdentifiers()) + assert len(av) == 2 + for oid in av: + assert '1.3.6.1.4.1.221121.1.1.' in oid.prettyPrint() + + assert rfc5652.id_contentType in attribute_list + assert rfc5652.id_messageDigest in attribute_list + assert rfc4108.id_aa_targetHardwareIDs in attribute_list + assert rfc4108.id_aa_fwPkgMessageDigest in attribute_list + + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.pem_text) + + rfc5652.cmsContentTypesMap.update(rfc4108.cmsContentTypesMapUpdate) + rfc5652.cmsAttributesMap.update(rfc4108.cmsAttributesMapUpdate) + asn1Object, rest = der_decode(substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + sd_eci = asn1Object['content']['encapContentInfo'] + assert sd_eci['eContentType'] == rfc4108.id_ct_firmwarePackage + assert sd_eci['eContent'].hasValue() + + for attr in asn1Object['content']['signerInfos'][0]['signedAttrs']: + assert attr['attrType'] in rfc5652.cmsAttributesMap.keys() + if attr['attrType'] == rfc4108.id_aa_targetHardwareIDs: + for oid in attr['attrValues'][0]: + assert '1.3.6.1.4.1.221121.1.1.' in oid.prettyPrint() suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc4210.py b/tests/test_rfc4210.py index 0e78b9a..b3862e3 100644 --- a/tests/test_rfc4210.py +++ b/tests/test_rfc4210.py @@ -129,4 +129,7 @@ JA5RSwQoMDYTj2WrwtM/nsP12T39or4JRZhlLSM43IaTwEBtQw== suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc5035.py b/tests/test_rfc5035.py new file mode 100644 index 0000000..b031c1b --- /dev/null +++ b/tests/test_rfc5035.py @@ -0,0 +1,183 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# + +import sys + +from pyasn1.codec.der.decoder import decode as der_decode +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1_modules import pem +from pyasn1_modules import rfc5652 +from pyasn1_modules import rfc5035 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class SignedMessageTestCase(unittest.TestCase): + signed_message_pem_text = """\ +MIIFzAYJKoZIhvcNAQcCoIIFvTCCBbkCAQExDTALBglghkgBZQMEAgIwUQYJKoZI +hvcNAQcBoEQEQkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbg0KDQpXYXRzb24sIGNv +bWUgaGVyZSAtIEkgd2FudCB0byBzZWUgeW91LqCCAnwwggJ4MIIB/qADAgECAgkA +pbNUKBuwbjswCgYIKoZIzj0EAwMwPzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlZB +MRAwDgYDVQQHDAdIZXJuZG9uMREwDwYDVQQKDAhCb2d1cyBDQTAeFw0xOTA1Mjkx +NDQ1NDFaFw0yMDA1MjgxNDQ1NDFaMHAxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJW +QTEQMA4GA1UEBxMHSGVybmRvbjEQMA4GA1UEChMHRXhhbXBsZTEOMAwGA1UEAxMF +QWxpY2UxIDAeBgkqhkiG9w0BCQEWEWFsaWNlQGV4YW1wbGUuY29tMHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAE+M2fBy/sRA6V1pKFqecRTE8+LuAHtZxes1wmJZrBBg+b +z7uYZfYQxI3dVB0YCSD6Mt3yXFlnmfBRwoqyArbjIBYrDbHBv2k8Csg2DhQ7qs/w +to8hMKoFgkcscqIbiV7Zo4GUMIGRMAsGA1UdDwQEAwIHgDBCBglghkgBhvhCAQ0E +NRYzVGhpcyBjZXJ0aWZpY2F0ZSBjYW5ub3QgYmUgdHJ1c3RlZCBmb3IgYW55IHB1 +cnBvc2UuMB0GA1UdDgQWBBTEuloOPnrjPIGw9AKqaLsW4JYONTAfBgNVHSMEGDAW +gBTyNds0BNqlVfK9aQOZsGLs4hUIwTAKBggqhkjOPQQDAwNoADBlAjBjuR/RNbgL +3kRhmn+PJTeKaL9sh/oQgHOYTgLmSnv3+NDCkhfKuMNoo/tHrkmihYgCMQC94Mae +rDIrQpi0IDh+v0QSAv9rMife8tClafXWtDwwL8MS7oAh0ymT446Uizxx3PUxggLQ +MIICzAIBATBMMD8xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UEBwwH +SGVybmRvbjERMA8GA1UECgwIQm9ndXMgQ0ECCQCls1QoG7BuOzALBglghkgBZQME +AgKgggH1MBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8X +DTE5MDUyOTE4MjMxOVowJQYLKoZIhvcNAQkQAgcxFgQUAbWZQYhLO5wtUgsOCGtT +4V3aNhUwLwYLKoZIhvcNAQkQAgQxIDAeDBFXYXRzb24sIGNvbWUgaGVyZQYJKoZI +hvcNAQcBMDUGCyqGSIb3DQEJEAICMSYxJAIBAQYKKwYBBAGBrGABARMTQm9hZ3Vz +IFByaXZhY3kgTWFyazA/BgkqhkiG9w0BCQQxMgQwtuQipP2CZx7U96rGbUT06LC5 +jVFYccZW5/CaNvpcrOPiChDm2vI3m4k300z5mSZsME0GCyqGSIb3DQEJEAIBMT4w +PAQgx08hD2QnVwj1DoeRELNtdZ0PffW4BQIvcwwVc/goU6OAAQEwFTATgRFhbGlj +ZUBleGFtcGxlLmNvbTCBmwYLKoZIhvcNAQkQAi8xgYswgYgwdjB0BCACcp04gyM2 +dTDg+0ydCwlucr6Mg8Wd3J3c9V+iLHsnZzBQMEOkQTA/MQswCQYDVQQGEwJVUzEL +MAkGA1UECAwCVkExEDAOBgNVBAcMB0hlcm5kb24xETAPBgNVBAoMCEJvZ3VzIENB +AgkApbNUKBuwbjswDjAMBgorBgEEAYGsYAEBMAoGCCqGSM49BAMDBGcwZQIxAO3K +D9YjFTKE3p383VVw/ol79WTVoMea4H1+7xn+3E1XO4oyb7qwQz0KmsGfdqWptgIw +T9yMtRLN5ZDU14y+Phzq9NKpSw/x5KyXoUKjCMc3Ru6dIW+CgcRQees+dhnvuD5U +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.signed_message_pem_text) + asn1Object, rest = der_decode (substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + sd, rest = der_decode(asn1Object['content'], asn1Spec=rfc5652.SignedData()) + assert not rest + assert sd.prettyPrint() + assert der_encode(sd) == asn1Object['content'] + + for sa in sd['signerInfos'][0]['signedAttrs']: + sat = sa['attrType'] + sav0 = sa['attrValues'][0] + + if sat in rfc5035.ESSAttributeMap.keys(): + sav, rest = der_decode(sav0, asn1Spec=rfc5035.ESSAttributeMap[sat]) + assert not rest + assert sav.prettyPrint() + assert der_encode(sav) == sav0 + + +class SignedReceiptTestCase(unittest.TestCase): + signed_receipt_pem_text = """\ +MIIE3gYJKoZIhvcNAQcCoIIEzzCCBMsCAQMxDTALBglghkgBZQMEAgEwga4GCyqGSIb3DQEJ +EAEBoIGeBIGbMIGYAgEBBgkqhkiG9w0BBwEEIMdPIQ9kJ1cI9Q6HkRCzbXWdD331uAUCL3MM +FXP4KFOjBGYwZAIwOLV5WCbYjy5HLHE69IqXQQHVDJQzmo18WwkFrEYH3EMsvpXEIGqsFTFN +6NV4VBe9AjA5fGOCP5IhI32YqmGfs+zDlqZyb2xSX6Gr/IfCIm0angfOI39g7lAZDyivjh5H +/oSgggJ3MIICczCCAfqgAwIBAgIJAKWzVCgbsG48MAoGCCqGSM49BAMDMD8xCzAJBgNVBAYT +AlVTMQswCQYDVQQIDAJWQTEQMA4GA1UEBwwHSGVybmRvbjERMA8GA1UECgwIQm9ndXMgQ0Ew +HhcNMTkwNTI5MTkyMDEzWhcNMjAwNTI4MTkyMDEzWjBsMQswCQYDVQQGEwJVUzELMAkGA1UE +CBMCVkExEDAOBgNVBAcTB0hlcm5kb24xEDAOBgNVBAoTB0V4YW1wbGUxDDAKBgNVBAMTA0Jv +YjEeMBwGCSqGSIb3DQEJARYPYm9iQGV4YW1wbGUuY29tMHYwEAYHKoZIzj0CAQYFK4EEACID +YgAEMaRiVS8WvN8Ycmpfq75jBbOMUukNfXAg6AL0JJBXtIFAuIJcZVlkLn/xbywkcMLHK/O+ +w9RWUQa2Cjw+h8b/1Cl+gIpqLtE558bD5PfM2aYpJ/YE6yZ9nBfTQs7z1TH5o4GUMIGRMAsG +A1UdDwQEAwIHgDBCBglghkgBhvhCAQ0ENRYzVGhpcyBjZXJ0aWZpY2F0ZSBjYW5ub3QgYmUg +dHJ1c3RlZCBmb3IgYW55IHB1cnBvc2UuMB0GA1UdDgQWBBTKa2Zy3iybV3+YjuLDKtNmjsIa +pTAfBgNVHSMEGDAWgBTyNds0BNqlVfK9aQOZsGLs4hUIwTAKBggqhkjOPQQDAwNnADBkAjAV +boS6OfEYQomLDi2RUkd71hzwwiQZztbxNbosahIzjR8ZQaHhjdjJlrP/T6aXBwsCMDfRweYz +3Ce4E4wPfoqQnvqpM7ZlfhstjQQGOsWAtIIfqW/l+TgCO8ux3XLV6fj36zGCAYkwggGFAgEB +MEwwPzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlZBMRAwDgYDVQQHDAdIZXJuZG9uMREwDwYD +VQQKDAhCb2d1cyBDQQIJAKWzVCgbsG48MAsGCWCGSAFlAwQCAaCBrjAaBgkqhkiG9w0BCQMx +DQYLKoZIhvcNAQkQAQEwHAYJKoZIhvcNAQkFMQ8XDTE5MDUyOTE5MzU1NVowLwYJKoZIhvcN +AQkEMSIEIGb9Hm2kCnM0CYNpZU4Uj7dN0AzOieIn9sDqZMcIcZrEMEEGCyqGSIb3DQEJEAIF +MTIEMBZzeHVja7fQ62ywyh8rtKzBP1WJooMdZ+8c6pRqfIESYIU5bQnH99OPA51QCwdOdjAK +BggqhkjOPQQDAgRoMGYCMQDZiT22xgab6RFMAPvN4fhWwzx017EzttD4VaYrpbolropBdPJ6 +jIXiZQgCwxbGTCwCMQClaQ9K+L5LTeuW50ZKSIbmBZQ5dxjtnK3OlS7hYRi6U0JKZmWbbuS8 +vFIgX7eIkd8= +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.signed_receipt_pem_text) + asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + sd, rest = der_decode (asn1Object['content'], asn1Spec=rfc5652.SignedData()) + assert not rest + assert sd.prettyPrint() + assert der_encode(sd) == asn1Object['content'] + + assert sd['encapContentInfo']['eContentType'] == rfc5035.id_ct_receipt + receipt, rest = der_decode(sd['encapContentInfo']['eContent'], + asn1Spec=rfc5035.Receipt()) + assert not rest + assert receipt.prettyPrint() + assert der_encode(receipt) == sd['encapContentInfo']['eContent'] + + for sa in sd['signerInfos'][0]['signedAttrs']: + sat = sa['attrType'] + sav0 = sa['attrValues'][0] + + if sat in rfc5035.ESSAttributeMap.keys(): + sav, rest = der_decode(sav0, asn1Spec=rfc5035.ESSAttributeMap[sat]) + assert not rest + assert sav.prettyPrint() + assert der_encode(sav) == sav0 + + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.signed_receipt_pem_text) + rfc5652.cmsContentTypesMap.update(rfc5035.cmsContentTypesMapUpdate) + rfc5652.cmsAttributesMap.update(rfc5035.ESSAttributeMap) + asn1Object, rest = der_decode(substrate, + asn1Spec=self.asn1Spec, decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] in rfc5652.cmsContentTypesMap.keys() + assert asn1Object['contentType'] == rfc5652.id_signedData + + sd = asn1Object['content'] + assert sd['version'] == rfc5652.CMSVersion().subtype(value='v3') + assert sd['encapContentInfo']['eContentType'] in rfc5652.cmsContentTypesMap.keys() + assert sd['encapContentInfo']['eContentType'] == rfc5035.id_ct_receipt + + for sa in sd['signerInfos'][0]['signedAttrs']: + assert sa['attrType'] in rfc5652.cmsAttributesMap.keys() + if sa['attrType'] == rfc5035.id_aa_msgSigDigest: + sa['attrValues'][0].prettyPrint()[:10] == '0x167378' + + # Since receipt is inside an OCTET STRING, decodeOpenTypes=True cannot + # automatically decode it + receipt, rest = der_decode(sd['encapContentInfo']['eContent'], + asn1Spec=rfc5652.cmsContentTypesMap[sd['encapContentInfo']['eContentType']]) + assert receipt['version'] == rfc5035.ESSVersion().subtype(value='v1') + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc5083.py b/tests/test_rfc5083.py index 08eabfb..a1222f9 100644 --- a/tests/test_rfc5083.py +++ b/tests/test_rfc5083.py @@ -2,7 +2,7 @@ # This file is part of pyasn1-modules software. # # Created by Russ Housley -# Copyright (c) 2018, Vigil Security, LLC +# Copyright (c) 2018, 2019 Vigil Security, LLC # License: http://snmplabs.com/pyasn1/license.html # @@ -12,7 +12,9 @@ from pyasn1.codec.der import decoder as der_decoder from pyasn1.codec.der import encoder as der_encoder from pyasn1_modules import pem +from pyasn1_modules import rfc5652 from pyasn1_modules import rfc5083 +from pyasn1_modules import rfc5035 try: import unittest2 as unittest @@ -47,7 +49,54 @@ ur76ztut3sr4iIANmvLRbyFUf87+2bPvLQQMoOWSXMGE4BckY8RM assert der_encoder.encode(asn1Object) == substrate +class AuthEnvelopedDataOpenTypesTestCase(unittest.TestCase): + pem_text = """\ +MIICvQYLKoZIhvcNAQkQARegggKsMIICqAIBADGCAiekggIjBgsqhkiG9w0BCRAN +ATCCAhICAQAEE3B0Zi1rbWM6MTM2MTQxMjIxMTIwDQYLKoZIhvcNAQkQAzAwCwYJ +YIZIAWUDBAEtMIIBsDCCAawCAQKAFJ7rZ8m5WnTUTS8WOWaA6AG1y6ScMA0GCSqG +SIb3DQEBAQUABIIBgHfnHNqDbyyql2NqX6UQggelWMTjwzJJ1L2erbsj1bIAGmpI +sUijw+fX8VOS7v1C9ui2Md9NFgCfkmKLo8T/jELqrk7MpMu09G5zDgeXzJfQDFc1 +15wbrWAUU3XP7XIb6TNOc3xtq4UxA5V6jNUK2XyWKpjzOtM7gm0VWIJGVVlYu+u3 +2LQcCjRFb87kvOY/WEnjxQpCW8g+4V747Ud97dYpMub7TLJiRNZkdHnq8xEGKlXj +VHSgc10lhphe1kFGeCpfJEsqjtN7YsVzf65ri9Z+3FJ1IO4cnMDbzGhyRXkS7a0k +58/miJbSj88PvzKNSURwpu4YHMQQX/mjT2ey1SY4ihPMuxxgTdCa04L0UxaRr7xA +ucz3n2UWShelm3IIjnWRlYdXypnXvKvwCLoeh5mJwUl1JNFPCQkQ487cKRyobUyN +gXQKT4ZDHCgXciwsX5nTsom87Ixp5vqSDJ+DhXA0r/Caiu1vnY5X9GLHSkqgXkgq +gUuu0LfcsQERD8psfQQogbiuZDqJmYt1Iau/pkuGfmeeqeiM3aeQ4NZf9AFZUVWB +GArPNHrvVDA3BgkqhkiG9w0BBwEwGwYJYIZIAWUDBAEuMA4EDMr+ur76ztut3sr4 +iIANmvLRbyFUf87+2bPvLQQMoOWSXMGE4BckY8RMojEwLwYLKoZIhvcNAQkQAgQx +IDAeDBFXYXRzb24sIGNvbWUgaGVyZQYJKoZIhvcNAQcB +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.pem_text) + rfc5652.cmsAttributesMap.update(rfc5035.ESSAttributeMap) + rfc5652.cmsContentTypesMap.update(rfc5083.cmsContentTypesMapUpdate) + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + assert asn1Object['contentType'] in rfc5652.cmsContentTypesMap + assert asn1Object['contentType'] == rfc5083.id_ct_authEnvelopedData + authenv = asn1Object['content'] + assert authenv['version'] == rfc5652.CMSVersion().subtype(value='v0') + + for attr in authenv['unauthAttrs']: + assert attr['attrType'] in rfc5652.cmsAttributesMap + if attr['attrType'] == rfc5035.id_aa_contentHint: + assert 'Watson' in attr['attrValues'][0]['contentDescription'] + + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc5084.py b/tests/test_rfc5084.py index dae84b4..8356f90 100644 --- a/tests/test_rfc5084.py +++ b/tests/test_rfc5084.py @@ -51,4 +51,7 @@ class GCMParametersTestCase(unittest.TestCase): suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc5208.py b/tests/test_rfc5208.py index 71d14b6..7e962ca 100644 --- a/tests/test_rfc5208.py +++ b/tests/test_rfc5208.py @@ -74,4 +74,7 @@ dLsZjNQ= suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc5280.py b/tests/test_rfc5280.py index 7d29388..5abff3e 100644 --- a/tests/test_rfc5280.py +++ b/tests/test_rfc5280.py @@ -9,6 +9,8 @@ import sys from pyasn1.codec.der import decoder as der_decoder from pyasn1.codec.der import encoder as der_encoder +from pyasn1.type import univ + from pyasn1_modules import pem from pyasn1_modules import rfc5280 @@ -79,7 +81,157 @@ vjnIhxTFoCb5vA== assert der_encoder.encode(asn1Object) == substrate +class CertificateOpenTypeTestCase(unittest.TestCase): + pem_text = """\ +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 +IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz +BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y +aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG +9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy +NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y +azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw +Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl +cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD +cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs +2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY +JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE +Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ +n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A +PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu +""" + + def setUp(self): + self.asn1Spec = rfc5280.Certificate() + + def testDerCodec(self): + + substrate = pem.readBase64fromText(self.pem_text) + + algorithmIdentifierMapUpdate = { + univ.ObjectIdentifier('1.2.840.113549.1.1.1'): univ.Null(""), + univ.ObjectIdentifier('1.2.840.113549.1.1.5'): univ.Null(""), + univ.ObjectIdentifier('1.2.840.113549.1.1.11'): univ.Null(""), + } + + rfc5280.algorithmIdentifierMap.update(algorithmIdentifierMapUpdate) + + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=self.asn1Spec, decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + for rdn in asn1Object['tbsCertificate']['subject']['rdnSequence']: + for atv in rdn: + if atv['type'] == rfc5280.id_emailAddress: + assert "valicert.com" in atv['value'] + else: + atv_ps = str(atv['value']['printableString']) + assert "valicert" in atv_ps.lower() + + sig_alg = asn1Object['tbsCertificate']['signature'] + assert sig_alg['parameters'] == univ.Null("") + + spki_alg = asn1Object['tbsCertificate']['subjectPublicKeyInfo']['algorithm'] + assert spki_alg['parameters'] == univ.Null("") + + +class CertificateListOpenTypeTestCase(unittest.TestCase): + pem_text = """\ +MIIBVjCBwAIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJBVTETMBEGA1UE +CBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk +MRUwEwYDVQQDEwxzbm1wbGFicy5jb20xIDAeBgkqhkiG9w0BCQEWEWluZm9Ac25t +cGxhYnMuY29tFw0xMjA0MTExMzQwNTlaFw0xMjA1MTExMzQwNTlaoA4wDDAKBgNV +HRQEAwIBATANBgkqhkiG9w0BAQUFAAOBgQC1D/wwnrcY/uFBHGc6SyoYss2kn+nY +RTwzXmmldbNTCQ03x5vkWGGIaRJdN8QeCzbEi7gpgxgpxAx6Y5WkxkMQ1UPjNM5n +DGVDOtR0dskFrrbHuNpWqWrDaBN0/ryZiWKjr9JRbrpkHgVY29I1gLooQ6IHuKHY +vjnIhxTFoCb5vA== +""" + + def setUp(self): + self.asn1Spec = rfc5280.CertificateList() + + def testDerCodec(self): + + substrate = pem.readBase64fromText(self.pem_text) + + algorithmIdentifierMapUpdate = { + univ.ObjectIdentifier('1.2.840.113549.1.1.1'): univ.Null(""), + univ.ObjectIdentifier('1.2.840.113549.1.1.5'): univ.Null(""), + univ.ObjectIdentifier('1.2.840.113549.1.1.11'): univ.Null(""), + } + + rfc5280.algorithmIdentifierMap.update(algorithmIdentifierMapUpdate) + + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=self.asn1Spec, decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + for rdn in asn1Object['tbsCertList']['issuer']['rdnSequence']: + for atv in rdn: + if atv['type'] == rfc5280.id_emailAddress: + assert "snmplabs.com" in atv['value'] + elif atv['type'] == rfc5280.id_at_countryName: + assert atv['value'] == 'AU' + else: + assert len(atv['value']['printableString']) > 9 + + for extn in asn1Object['tbsCertList']['crlExtensions']: + if extn['extnID'] in rfc5280.certificateExtensionsMap.keys(): + ev, rest = der_decoder.decode(extn['extnValue'], + asn1Spec=rfc5280.certificateExtensionsMap[extn['extnID']]) + assert not rest + assert ev.prettyPrint() + assert der_encoder.encode(ev) == extn['extnValue'] + + sig_alg = asn1Object['tbsCertList']['signature'] + assert sig_alg['parameters'] == univ.Null("") + + def testExtensionsMap(self): + substrate = pem.readBase64fromText(self.pem_text) + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + for extn in asn1Object['tbsCertList']['crlExtensions']: + if extn['extnID'] in rfc5280.certificateExtensionsMap.keys(): + extnValue, rest = der_decoder.decode(extn['extnValue'], + asn1Spec=rfc5280.certificateExtensionsMap[extn['extnID']]) + assert der_encoder.encode(extnValue) == extn['extnValue'] + + +class ORAddressOpenTypeTestCase(unittest.TestCase): + oraddress_pem_text = """\ +MEMwK2EEEwJHQmIKEwhHT0xEIDQwMKIHEwVVSy5BQ4MHU2FsZm9yZKYFEwNSLUQx +FDASgAEBoQ0TC1N0ZXZlIEtpbGxl +""" + + def setUp(self): + self.asn1Spec = rfc5280.ORAddress() + + def testDecodeOpenTypes(self): + + substrate = pem.readBase64fromText(self.oraddress_pem_text) + + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=self.asn1Spec, decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + ea0 = asn1Object['extension-attributes'][0] + assert ea0['extension-attribute-type'] == rfc5280.common_name + assert ea0['extension-attribute-value'] == "Steve Kille" + + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc5480.py b/tests/test_rfc5480.py new file mode 100755 index 0000000..06e336d --- /dev/null +++ b/tests/test_rfc5480.py @@ -0,0 +1,87 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# + +import sys + +from pyasn1.codec.der import decoder as der_decoder +from pyasn1.codec.der import encoder as der_encoder + +from pyasn1_modules import pem +from pyasn1_modules import rfc5280 +from pyasn1_modules import rfc5480 +from pyasn1_modules import rfc4055 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class ECCertTestCase(unittest.TestCase): + digicert_ec_cert_pem_text = """\ +MIIDrDCCApSgAwIBAgIQCssoukZe5TkIdnRw883GEjANBgkqhkiG9w0BAQwFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEwxCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJjAkBgNVBAMTHURpZ2lDZXJ0IEVDQyBT +ZWN1cmUgU2VydmVyIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ghC6nfYJN6g +LGSkE85AnCNyqQIKDjc/ITa4jVMU9tWRlUvzlgKNcR7E2Munn17voOZ/WpIRllNv +68DLP679Wz9HJOeaBy6Wvqgvu1cYr3GkvXg6HuhbPGtkESvMNCuMo4IBITCCAR0w +EgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwNAYIKwYBBQUHAQEE +KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQgYDVR0f +BDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xv +YmFsUm9vdENBLmNybDA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYc +aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAdBgNVHQ4EFgQUo53mH/naOU/A +buiRy5Wl2jHiCp8wHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJ +KoZIhvcNAQEMBQADggEBAMeKoENL7HTJxavVHzA1Nm6YVntIrAVjrnuaVyRXzG/6 +3qttnMe2uuzO58pzZNvfBDcKAEmzP58mrZGMIOgfiA4q+2Y3yDDo0sIkp0VILeoB +UEoxlBPfjV/aKrtJPGHzecicZpIalir0ezZYoyxBEHQa0+1IttK7igZFcTMQMHp6 +mCHdJLnsnLWSB62DxsRq+HfmNb4TDydkskO/g+l3VtsIh5RHFPVfKK+jaEyDj2D3 +loB5hWp2Jp2VDCADjT7ueihlZGak2YPqmXTNbk19HOuNssWvFhtOyPNV6og4ETQd +Ea8/B6hPatJ0ES8q/HO3X8IVQwVs1n3aAr0im0/T+Xc= +""" + + def setUp(self): + self.asn1Spec = rfc5280.Certificate() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.digicert_ec_cert_pem_text) + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + assert substrate == der_encoder.encode(asn1Object) + + algid = asn1Object['tbsCertificate']['subjectPublicKeyInfo']['algorithm'] + assert algid['algorithm'] == rfc5480.id_ecPublicKey + param, rest = der_decoder.decode(algid['parameters'], asn1Spec=rfc5480.ECParameters()) + assert param.prettyPrint() + assert param['namedCurve'] == rfc5480.secp384r1 + + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.digicert_ec_cert_pem_text) + rfc5280.algorithmIdentifierMap.update(rfc5480.algorithmIdentifierMapUpdate) + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + spki_alg = asn1Object['tbsCertificate']['subjectPublicKeyInfo']['algorithm'] + assert spki_alg['algorithm'] == rfc5480.id_ecPublicKey + assert spki_alg['parameters']['namedCurve'] == rfc5480.secp384r1 + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc5649.py b/tests/test_rfc5649.py new file mode 100644 index 0000000..9f404ad --- /dev/null +++ b/tests/test_rfc5649.py @@ -0,0 +1,59 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# + +import sys + +from pyasn1.codec.der import decoder as der_decoder +from pyasn1.codec.der import encoder as der_encoder + +from pyasn1_modules import pem +from pyasn1_modules import rfc5649 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class AESKeyWrapTestCase(unittest.TestCase): + kw_alg_id_pem_text = "MAsGCWCGSAFlAwQBLQ==" + + def setUp(self): + self.asn1Spec = rfc5649.AlgorithmIdentifier() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.kw_alg_id_pem_text) + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert asn1Object[0] == rfc5649.id_aes256_wrap + assert der_encoder.encode(asn1Object) == substrate + + +class AESKeyWrapWithPadTestCase(unittest.TestCase): + kw_pad_alg_id_pem_text = "MAsGCWCGSAFlAwQBMA==" + + def setUp(self): + self.asn1Spec = rfc5649.AlgorithmIdentifier() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.kw_pad_alg_id_pem_text) + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert asn1Object[0] == rfc5649.id_aes256_wrap_pad + assert der_encoder.encode(asn1Object) == substrate + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc5652.py b/tests/test_rfc5652.py index 3b08eb1..eac4262 100644 --- a/tests/test_rfc5652.py +++ b/tests/test_rfc5652.py @@ -9,7 +9,12 @@ import sys from pyasn1.codec.der import decoder as der_decoder from pyasn1.codec.der import encoder as der_encoder +from pyasn1.type import char +from pyasn1.type import namedtype +from pyasn1.type import univ + from pyasn1_modules import pem +from pyasn1_modules import rfc5280 from pyasn1_modules import rfc5652 from pyasn1_modules import rfc6402 @@ -68,7 +73,6 @@ xicQmJP+VoMHo/ZpjFY9fYCjNZUArgKsEwK/s+p9yrVVeB1Nf8Mn rfc6402.id_cct_PKIData: lambda x: None } - next_layer = rfc5652.id_ct_contentInfo while next_layer: @@ -84,8 +88,88 @@ xicQmJP+VoMHo/ZpjFY9fYCjNZUArgKsEwK/s+p9yrVVeB1Nf8Mn substrate = getNextSubstrate[next_layer](asn1Object) next_layer = getNextLayer[next_layer](asn1Object) + def testOpenTypes(self): + class ClientInformation(univ.Sequence): + pass + + ClientInformation.componentType = namedtype.NamedTypes( + namedtype.NamedType('clientId', univ.Integer()), + namedtype.NamedType('MachineName', char.UTF8String()), + namedtype.NamedType('UserName', char.UTF8String()), + namedtype.NamedType('ProcessName', char.UTF8String()) + ) + + class EnrollmentCSP(univ.Sequence): + pass + + EnrollmentCSP.componentType = namedtype.NamedTypes( + namedtype.NamedType('KeySpec', univ.Integer()), + namedtype.NamedType('Name', char.BMPString()), + namedtype.NamedType('Signature', univ.BitString()) + ) + + attributesMapUpdate = { + univ.ObjectIdentifier('1.3.6.1.4.1.311.13.2.3'): char.IA5String(), + univ.ObjectIdentifier('1.3.6.1.4.1.311.13.2.2'): EnrollmentCSP(), + univ.ObjectIdentifier('1.3.6.1.4.1.311.21.20'): ClientInformation(), + } + + rfc5652.cmsAttributesMap.update(rfc6402.cmcControlAttributesMap) + rfc5652.cmsAttributesMap.update(attributesMapUpdate) + + algorithmIdentifierMapUpdate = { + univ.ObjectIdentifier('1.2.840.113549.1.1.1'): univ.Null(""), + univ.ObjectIdentifier('1.2.840.113549.1.1.5'): univ.Null(""), + univ.ObjectIdentifier('1.2.840.113549.1.1.11'): univ.Null(""), + } + + rfc5280.algorithmIdentifierMap.update(algorithmIdentifierMapUpdate) + + rfc5652.cmsContentTypesMap.update(rfc6402.cmsContentTypesMapUpdate) + + substrate = pem.readBase64fromText(self.pem_text) + + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=rfc5652.ContentInfo(), decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + eci = asn1Object['content']['encapContentInfo'] + assert eci['eContentType'] in rfc5652.cmsContentTypesMap.keys() + assert eci['eContentType'] == rfc6402.id_cct_PKIData + pkid, rest = der_decoder.decode(eci['eContent'], + asn1Spec=rfc5652.cmsContentTypesMap[eci['eContentType']], + decodeOpenTypes=True) + assert not rest + assert pkid.prettyPrint() + assert der_encoder.encode(pkid) == eci['eContent'] + + for req in pkid['reqSequence']: + cr = req['tcr']['certificationRequest'] + + sig_alg = cr['signatureAlgorithm'] + assert sig_alg['algorithm'] in rfc5280.algorithmIdentifierMap.keys() + assert sig_alg['parameters'] == univ.Null("") + + cri = cr['certificationRequestInfo'] + spki_alg = cri['subjectPublicKeyInfo']['algorithm'] + assert spki_alg['algorithm'] in rfc5280.algorithmIdentifierMap.keys() + assert spki_alg['parameters'] == univ.Null("") + + attrs = cr['certificationRequestInfo']['attributes'] + for attr in attrs: + assert attr['attrType'] in rfc5652.cmsAttributesMap.keys() + if attr['attrType'] == univ.ObjectIdentifier('1.3.6.1.4.1.311.13.2.3'): + assert attr['attrValues'][0] == "6.2.9200.2" + else: + assert attr['attrValues'][0].hasValue() + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc5915.py b/tests/test_rfc5915.py new file mode 100644 index 0000000..bcb8198 --- /dev/null +++ b/tests/test_rfc5915.py @@ -0,0 +1,51 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# + +import sys + +from pyasn1.codec.der.decoder import decode as der_decode +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1_modules import pem +from pyasn1_modules import rfc5915 +from pyasn1_modules import rfc5480 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class MUDCertTestCase(unittest.TestCase): + private_key_pem_text = """\ +MIGkAgEBBDDLjzGbbLrR3T13lrrVum7WC/4Ua4Femc1RhhNVe1Q5XsArQ33kn9kx +3lOUfOcG+qagBwYFK4EEACKhZANiAAT4zZ8HL+xEDpXWkoWp5xFMTz4u4Ae1nF6z +XCYlmsEGD5vPu5hl9hDEjd1UHRgJIPoy3fJcWWeZ8FHCirICtuMgFisNscG/aTwK +yDYOFDuqz/C2jyEwqgWCRyxyohuJXtk= +""" + + def setUp(self): + self.asn1Spec = rfc5915.ECPrivateKey() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.private_key_pem_text) + asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['parameters']['namedCurve'] == rfc5480.secp384r1 + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc5940.py b/tests/test_rfc5940.py new file mode 100644 index 0000000..d33a1c7 --- /dev/null +++ b/tests/test_rfc5940.py @@ -0,0 +1,135 @@ +# +# This file is part of pyasn1-modules software. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +import sys + +from pyasn1.codec.der.decoder import decode as der_decode +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1.type import univ + +from pyasn1_modules import pem +from pyasn1_modules import rfc2560 +from pyasn1_modules import rfc5940 +from pyasn1_modules import rfc5652 +from pyasn1_modules import rfc5280 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class CRLandOCSPResponseTestCase(unittest.TestCase): + pem_text = """\ +MIIHWQYJKoZIhvcNAQcCoIIHSjCCB0YCAQExDTALBglghkgBZQMEAgEwUwYJKoZI +hvcNAQcBoEYERENvbnRlbnQtVHlwZTogdGV4dC9wbGFpbg0KDQpXYXRzb24sIGNv +bWUgaGVyZSAtIEkgd2FudCB0byBzZWUgeW91Lg0KoIIBaDCCAWQwggEKoAMCAQIC +CQClWUKCJkwnGTAKBggqhkjOPQQDAjAkMRQwEgYDVQQKDAtleGFtcGxlLm9yZzEM +MAoGA1UEAwwDQm9iMB4XDTE3MTIyMDIzMDc0OVoXDTE4MTIyMDIzMDc0OVowJDEU +MBIGA1UECgwLZXhhbXBsZS5vcmcxDDAKBgNVBAMMA0JvYjBZMBMGByqGSM49AgEG +CCqGSM49AwEHA0IABIZP//xT8ah2ymmxfidIegeccVKuGxN+OTuvGq69EnQ8fUFD +ov2KNw8Cup0DtzAfHaZOMFWUu2+Vy3H6SLbQo4OjJTAjMCEGA1UdEQEB/wQXMBWG +E3NpcDpib2JAZXhhbXBsZS5vcmcwCgYIKoZIzj0EAwIDSAAwRQIhALIkjJJAKCI4 +nsklf2TM/RBvuguWwRkHMDTVGxAvczlsAiAVjrFR8IW5vS4EzyePDVIua7b+Tzb3 +THcQsVpPR53kDaGCBGQwggIbMIIBAwIBATANBgkqhkiG9w0BAQsFADBsMQswCQYD +VQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGln +aWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBS +b290IENBFw0xOTA1MDIyMjE1NTRaFw0xOTA1MjMyMjE1NTRaMDEwLwIQDPWCOBgZ +nlb4K9ZS7Sft6RcNMTgxMDI1MTYxMTM4WjAMMAoGA1UdFQQDCgEAoDAwLjAfBgNV +HSMEGDAWgBSxPsNpA/i/RwHUmCYaCALvY2QrwzALBgNVHRQEBAICAcQwDQYJKoZI +hvcNAQELBQADggEBABPO3OA0OkQZ+RLVxz/cNx5uNVEO416oOePkN0A4DxFztf33 +7caS4OyfS9Wyu1j5yUdWJVpAKXSQeN95MqHkpSpYDssuqbuYjv8ViJfseGBgtXTc +zUzzNeNdY2uxMbCxuhmPkgacAo1lx9LkK2ScYHWVbfFRF1UQ/dcmavaZsEOBNuLW +OxQYA9MqfVNAymHe7vPqwm/8IY2FbHe9HsiJZfGxNWMDP5lmJiXmpntTeDQ2Ujdi +yXwGGKjyiSTFk2jVRutrGINufaoA/f7eCmIb4UDPbpMjVfD215dW8eBKouypCVoE +vmCSSTacdiBI2yOluvMN0PzvPve0ECAE+D4em9ahggJBBggrBgEFBQcQAjCCAjMK +AQCgggIsMIICKAYJKwYBBQUHMAEBBIICGTCCAhUwZqEgMB4xHDAJBgNVBAYTAlJV +MA8GA1UEAx4IAFQAZQBzAHQYEzIwMTkwNTA5MTU1MDQ4LjI1OVowLTArMBIwBwYF +Kw4DAhoEAQEEAQECAQGAABgTMjAxOTA1MDkxNTUwNDguMjYxWjAKBggqhkjOPQQD +AgNJADBGAiEAujFVH+NvuTLYa8RW3pvWSUwZfjOW5H5171JI+/50BjcCIQDhwige +wl+ts6TIvhU+CFoOipQBNKyKXKh7ngJkUtpZ86CCAVIwggFOMIIBSjCB8aADAgEC +AgEBMAoGCCqGSM49BAMCMB4xHDAJBgNVBAYTAlJVMA8GA1UEAx4IAFQAZQBzAHQw +HhcNMTkwMjAxMDUwMDAwWhcNMjIwMjAxMDUwMDAwWjAeMRwwCQYDVQQGEwJSVTAP +BgNVBAMeCABUAGUAcwB0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEM0jxEYgg +RxC/r87uV/h6iZ8BAdHT/6fxRuzG0PRMIlFBy38skFUXJJulKV9JW16YJqOkVsqv +xwMM61z7p1vQ/qMgMB4wDwYDVR0TBAgwBgEB/wIBAzALBgNVHQ8EBAMCAAYwCgYI +KoZIzj0EAwIDSAAwRQIhAIdpCt5g89ofSADXmBD3KXQGnTghwbAMeWrKXqTGww+x +AiAl8NQgfUk4xMymZ3VtCLJ2MdczDps4Zh2KPOqAR5fZAjGCAQcwggEDAgEBMDEw +JDEUMBIGA1UECgwLZXhhbXBsZS5vcmcxDDAKBgNVBAMMA0JvYgIJAKVZQoImTCcZ +MAsGCWCGSAFlAwQCAaBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZI +hvcNAQkFMQ8XDTE5MDEyNDIzNTI1NlowLwYJKoZIhvcNAQkEMSIEIO93j8lA1ebc +JXb0elmbMSYZWp8aInra81+iLAUNjRlaMAoGCCqGSM49BAMCBEcwRQIhAPeI7URq +tw//LB/6TAN0/Qh3/WHukXwxRbOJpnYVx0b6AiB3lK3FfwBhx4S5YSPMblS7goJl +ttTMEpl2prH8bbwo1g== +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.pem_text) + + asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) + + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + sd, rest = der_decode(asn1Object['content'], + asn1Spec=rfc5652.SignedData()) + assert sd.prettyPrint() + + assert sd['encapContentInfo']['eContentType'] == rfc5652.id_data + assert sd['encapContentInfo']['eContent'] + v2 = rfc5280.Version(value='v2') + assert sd['crls'][0]['crl']['tbsCertList']['version'] == v2 + ocspr_oid = rfc5940.id_ri_ocsp_response + assert sd['crls'][1]['other']['otherRevInfoFormat'] == ocspr_oid + + ocspr, rest = der_decode(sd['crls'][1]['other']['otherRevInfo'], + asn1Spec=rfc5940.OCSPResponse()) + assert ocspr.prettyPrint() + success = rfc2560.OCSPResponseStatus(value='successful') + assert ocspr['responseStatus'] == success + + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.pem_text) + + rfc5652.otherRevInfoFormatMap.update(rfc5940.otherRevInfoFormatMapUpdate) + asn1Object, rest = der_decode(substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + sd_eci = asn1Object['content']['encapContentInfo'] + assert sd_eci['eContentType'] == rfc5652.id_data + assert sd_eci['eContent'].hasValue() + + for ri in asn1Object['content']['crls']: + if ri.getName() == 'crl': + v2 = rfc5280.Version(value='v2') + assert ri['crl']['tbsCertList']['version'] == v2 + if ri.getName() == 'other': + ori = ri['other'] + ocspr_oid = rfc5940.id_ri_ocsp_response + assert ori['otherRevInfoFormat'] == ocspr_oid + ocspr_status = ori['otherRevInfo']['responseStatus'] + success = rfc2560.OCSPResponseStatus(value='successful') + assert ocspr_status == success + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc5958.py b/tests/test_rfc5958.py index 1abc40e..febec78 100644 --- a/tests/test_rfc5958.py +++ b/tests/test_rfc5958.py @@ -11,7 +11,10 @@ import sys from pyasn1.codec.der import decoder as der_decoder from pyasn1.codec.der import encoder as der_encoder +from pyasn1.type import univ + from pyasn1_modules import pem +from pyasn1_modules import rfc5652 from pyasn1_modules import rfc5958 from pyasn1_modules import rfc8410 @@ -44,7 +47,37 @@ Z9w7lshQhqowtrbLDFw4rXAxZuE= assert der_encoder.encode(asn1Object) == substrate +class PrivateKeyOpenTypesTestCase(unittest.TestCase): + asymmetric_key_pkg_pem_text = """\ +MIGEBgpghkgBZQIBAk4FoHYwdDByAgEBMAUGAytlcAQiBCDU7nLb+RNYStW22PH3 +afitOv58KMvx1Pvgl6iPRHVYQqAfMB0GCiqGSIb3DQEJCRQxDwwNQ3VyZGxlIENo +YWlyc4EhABm/RAlphM3+hUG6wWfcO5bIUIaqMLa2ywxcOK1wMWbh +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.asymmetric_key_pkg_pem_text) + rfc5652.cmsContentTypesMap.update(rfc5958.cmsContentTypesMapUpdate) + asn1Object, rest = der_decoder.decode(substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + assert rfc5958.id_ct_KP_aKeyPackage in rfc5652.cmsContentTypesMap.keys() + oneKey = asn1Object['content'][0] + assert oneKey['privateKeyAlgorithm']['algorithm'] == rfc8410.id_Ed25519 + pkcs_9_at_friendlyName = univ.ObjectIdentifier('1.2.840.113549.1.9.9.20') + assert oneKey['attributes'][0]['type'] == pkcs_9_at_friendlyName + + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc6019.py b/tests/test_rfc6019.py new file mode 100644 index 0000000..311e49f --- /dev/null +++ b/tests/test_rfc6019.py @@ -0,0 +1,65 @@ +# +# This file is part of pyasn1-modules software. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +import sys + +from pyasn1.codec.der.decoder import decode as der_decode +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1.type import univ + +from pyasn1_modules import pem +from pyasn1_modules import rfc5652 +from pyasn1_modules import rfc6019 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class BinarySigningTimeTestCase(unittest.TestCase): + pem_text = "MBUGCyqGSIb3DQEJEAIuMQYCBFy/hlQ=" + + def setUp(self): + self.asn1Spec = rfc5652.Attribute() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.pem_text) + + asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) + + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['attrType'] == rfc6019.id_aa_binarySigningTime + bintime, rest = der_decode(asn1Object['attrValues'][0], + asn1Spec=rfc6019.BinaryTime()) + assert bintime == 0x5cbf8654 + + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.pem_text) + + rfc5652.cmsAttributesMap.update(rfc6019.cmsAttributesMapUpdate) + asn1Object, rest = der_decode(substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['attrType'] in rfc5652.cmsAttributesMap.keys() + assert asn1Object['attrValues'][0] == 0x5cbf8654 + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc7191.py b/tests/test_rfc7191.py new file mode 100644 index 0000000..337bd44 --- /dev/null +++ b/tests/test_rfc7191.py @@ -0,0 +1,296 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# + +import sys + +from pyasn1.codec.der.decoder import decode as der_decode +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1.type import univ + +from pyasn1_modules import pem +from pyasn1_modules import rfc5652 +from pyasn1_modules import rfc7191 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class ReceiptRequestTestCase(unittest.TestCase): + message1_pem_text = """\ +MIIGfAYJKoZIhvcNAQcCoIIGbTCCBmkCAQMxDTALBglghkgBZQMEAgIwgb4GCyqGSIb3DQEJ +EAEZoIGuBIGrMIGooEQwIwYLKoZIhvcNAQkQDAExFAwSVmlnaWwgU2VjdXJpdHkgTExDMB0G +CyqGSIb3DQEJEAwDMQ4MDFByZXRlbmQgMDQ4QTBgMF4wVjAbBgsqhkiG9w0BCRAMGzEMDApl +eGFtcGxlSUQxMBUGCyqGSIb3DQEJEAwKMQYMBEhPVFAwIAYLKoZIhvcNAQkQDAsxEQwPa3Rh +LmV4YW1wbGUuY29tBAQxMjM0oIIChzCCAoMwggIKoAMCAQICCQCls1QoG7BuPTAKBggqhkjO +PQQDAzA/MQswCQYDVQQGEwJVUzELMAkGA1UECAwCVkExEDAOBgNVBAcMB0hlcm5kb24xETAP +BgNVBAoMCEJvZ3VzIENBMB4XDTE5MDYxMjE0MzEwNFoXDTIwMDYxMTE0MzEwNFowfDELMAkG +A1UEBhMCVVMxCzAJBgNVBAgTAlZBMRAwDgYDVQQHEwdIZXJuZG9uMRswGQYDVQQKExJWaWdp +bCBTZWN1cml0eSBMTEMxFzAVBgNVBAsTDktleSBNYW5hZ2VtZW50MRgwFgYDVQQDEw9rdGEu +ZXhhbXBsZS5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASX9l7E3VS3GAEiiRrVozgCBQfL +F67IhOxtbQviD/ojhHSQmflLyfRJ8e7+nbWlOLstRc7lgmq+OQVaSlStkzVk/BO1wE5BgUyF +xje+sieUtPRXVqfoVZCJJsgiSbo181ejgZQwgZEwCwYDVR0PBAQDAgeAMEIGCWCGSAGG+EIB +DQQ1FjNUaGlzIGNlcnRpZmljYXRlIGNhbm5vdCBiZSB0cnVzdGVkIGZvciBhbnkgcHVycG9z +ZS4wHQYDVR0OBBYEFG2bXP0Dr7W51YvxZJ8aVuC1rU0PMB8GA1UdIwQYMBaAFPI12zQE2qVV +8r1pA5mwYuziFQjBMAoGCCqGSM49BAMDA2cAMGQCMAZ4lqTtdbaDLFfHywaQYwOWBkL3d0wH +EsNZTW1qQKy/oY3tXc0O6cbJZ5JJb9wk8QIwblXm8+JjdEJHsNjSv4rcJZou4vkMT7PzEme2 +BbMkwOWeIdhmy1vszd8TQgvdb36XMYIDBzCCAwMCAQOAFG2bXP0Dr7W51YvxZJ8aVuC1rU0P +MAsGCWCGSAFlAwQCAqCCAmUwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEZMBwGCSqGSIb3 +DQEJBTEPFw0xOTA2MTIxOTM1NTFaMCUGCyqGSIb3DQEJEAIHMRYEFCe4nFY7FiJRnReHHHm/ +rIht3/g9MD8GCSqGSIb3DQEJBDEyBDA3gzQlzfvylOn9Rf59kMSa1K2IyOBA5Eoeiyp83Bmj +KasomGorn9htte1iFPbxPRUwggG/BglghkgBZQIBBUExggGwMIIBrAQUJ7icVjsWIlGdF4cc +eb+siG3f+D0wggGSoIH+MH8GCWCGSAFlAgEQAARyMHAxCzAJBgNVBAYTAlVTMQswCQYDVQQI +EwJWQTEQMA4GA1UEBxMHSGVybmRvbjEQMA4GA1UEChMHRXhhbXBsZTEOMAwGA1UEAxMFQWxp +Y2UxIDAeBgkqhkiG9w0BCQEWEWFsaWNlQGV4YW1wbGUuY29tMHsGCWCGSAFlAgEQAARuMGwx +CzAJBgNVBAYTAlVTMQswCQYDVQQIEwJWQTEQMA4GA1UEBxMHSGVybmRvbjEQMA4GA1UEChMH +RXhhbXBsZTEMMAoGA1UEAxMDQm9iMR4wHAYJKoZIhvcNAQkBFg9ib2JAZXhhbXBsZS5jb20w +gY4wgYsGCWCGSAFlAgEQAAR+MHwxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJWQTEQMA4GA1UE +BxMHSGVybmRvbjEbMBkGA1UEChMSVmlnaWwgU2VjdXJpdHkgTExDMRcwFQYDVQQLEw5LZXkg +TWFuYWdlbWVudDEYMBYGA1UEAxMPa3RhLmV4YW1wbGUuY29tMAoGCCqGSM49BAMDBGYwZAIw +Z7DXliUb8FDKs+BadyCY+IJobPnQ6UoLldMj3pKEowONPifqrbWBJJ5cQQNgW6YuAjBbjSlY +goRV+bq4fdgOOj25JFqa80xnXGtQqjm/7NSII5SbdJk+DT7KCkSbkElkbgQ= +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.message1_pem_text) + asn1Object, rest = der_decode (substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + sd, rest = der_decode (asn1Object['content'], + asn1Spec=rfc5652.SignedData()) + + for sa in sd['signerInfos'][0]['signedAttrs']: + sat = sa['attrType'] + sav0 = sa['attrValues'][0] + + if sat == rfc7191.id_aa_KP_keyPkgIdAndReceiptReq: + sav, rest = der_decode(sav0, + asn1Spec=rfc7191.KeyPkgIdentifierAndReceiptReq()) + assert not rest + assert sav.prettyPrint() + assert der_encode(sav) == sav0 + + package_id_pem_text = "J7icVjsWIlGdF4cceb+siG3f+D0=" + package_id = pem.readBase64fromText(package_id_pem_text) + assert sav['pkgID'] == package_id + + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.message1_pem_text) + rfc5652.cmsAttributesMap.update(rfc7191.cmsAttributesMapUpdate) + asn1Object, rest = der_decode (substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + v3 = rfc5652.CMSVersion().subtype(value='v3') + assert asn1Object['content']['version'] == v3 + + for sa in asn1Object['content']['signerInfos'][0]['signedAttrs']: + if sa['attrType'] == rfc7191.id_aa_KP_keyPkgIdAndReceiptReq: + package_id_pem_text = "J7icVjsWIlGdF4cceb+siG3f+D0=" + package_id = pem.readBase64fromText(package_id_pem_text) + assert sa['attrValues'][0]['pkgID'] == package_id + + +class ReceiptTestCase(unittest.TestCase): + message2_pem_text = """\ +MIIEdAYJKoZIhvcNAQcCoIIEZTCCBGECAQMxDTALBglghkgBZQMEAgIwgawGCmCGSAFlAgEC +TgOggZ0EgZowgZcEFCe4nFY7FiJRnReHHHm/rIht3/g9MH8GCWCGSAFlAgEQAARyMHAxCzAJ +BgNVBAYTAlVTMQswCQYDVQQIEwJWQTEQMA4GA1UEBxMHSGVybmRvbjEQMA4GA1UEChMHRXhh +bXBsZTEOMAwGA1UEAxMFQWxpY2UxIDAeBgkqhkiG9w0BCQEWEWFsaWNlQGV4YW1wbGUuY29t +oIICfDCCAngwggH+oAMCAQICCQCls1QoG7BuOzAKBggqhkjOPQQDAzA/MQswCQYDVQQGEwJV +UzELMAkGA1UECAwCVkExEDAOBgNVBAcMB0hlcm5kb24xETAPBgNVBAoMCEJvZ3VzIENBMB4X +DTE5MDUyOTE0NDU0MVoXDTIwMDUyODE0NDU0MVowcDELMAkGA1UEBhMCVVMxCzAJBgNVBAgT +AlZBMRAwDgYDVQQHEwdIZXJuZG9uMRAwDgYDVQQKEwdFeGFtcGxlMQ4wDAYDVQQDEwVBbGlj +ZTEgMB4GCSqGSIb3DQEJARYRYWxpY2VAZXhhbXBsZS5jb20wdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAT4zZ8HL+xEDpXWkoWp5xFMTz4u4Ae1nF6zXCYlmsEGD5vPu5hl9hDEjd1UHRgJIPoy +3fJcWWeZ8FHCirICtuMgFisNscG/aTwKyDYOFDuqz/C2jyEwqgWCRyxyohuJXtmjgZQwgZEw +CwYDVR0PBAQDAgeAMEIGCWCGSAGG+EIBDQQ1FjNUaGlzIGNlcnRpZmljYXRlIGNhbm5vdCBi +ZSB0cnVzdGVkIGZvciBhbnkgcHVycG9zZS4wHQYDVR0OBBYEFMS6Wg4+euM8gbD0Aqpouxbg +lg41MB8GA1UdIwQYMBaAFPI12zQE2qVV8r1pA5mwYuziFQjBMAoGCCqGSM49BAMDA2gAMGUC +MGO5H9E1uAveRGGaf48lN4pov2yH+hCAc5hOAuZKe/f40MKSF8q4w2ij+0euSaKFiAIxAL3g +xp6sMitCmLQgOH6/RBIC/2syJ97y0KVp9da0PDAvwxLugCHTKZPjjpSLPHHc9TGCARwwggEY +AgEDgBTEuloOPnrjPIGw9AKqaLsW4JYONTALBglghkgBZQMEAgKgejAZBgkqhkiG9w0BCQMx +DAYKYIZIAWUCAQJOAzAcBgkqhkiG9w0BCQUxDxcNMTkwNjEzMTYxNjA4WjA/BgkqhkiG9w0B +CQQxMgQwQSWYpq4jwhMkmS0as0JL3gjYxKLgDfzP2ndTNsAY0m9p8Igp8ZcK4+5n9fXJ43vU +MAoGCCqGSM49BAMDBGgwZgIxAMfq2EJ5pSl9tGOEVJEgZitc266ljrOg5GDjkd2d089qw1A3 +bUcOYuCdivgxVuhlAgIxAPR9JavxziwCbVyBUWOAiKKYfglTgG3AwNmrKDj0NtXUQ9qDmGAc +6L+EAY2P5OVB8Q== +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.message2_pem_text) + asn1Object, rest = der_decode (substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + sd, rest = der_decode (asn1Object['content'], + asn1Spec=rfc5652.SignedData()) + assert not rest + assert sd.prettyPrint() + assert der_encode(sd) == asn1Object['content'] + + oid = sd['encapContentInfo']['eContentType'] + assert oid == rfc7191.id_ct_KP_keyPackageReceipt + receipt, rest = der_decode(sd['encapContentInfo']['eContent'], + asn1Spec=rfc7191.KeyPackageReceipt()) + assert not rest + assert receipt.prettyPrint() + assert der_encode(receipt) == sd['encapContentInfo']['eContent'] + + package_id_pem_text = "J7icVjsWIlGdF4cceb+siG3f+D0=" + package_id = pem.readBase64fromText(package_id_pem_text) + assert receipt['receiptOf']['pkgID'] == package_id + + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.message2_pem_text) + rfc5652.cmsContentTypesMap.update(rfc7191.cmsContentTypesMapUpdate) + rfc5652.cmsAttributesMap.update(rfc7191.cmsAttributesMapUpdate) + asn1Object, rest = der_decode (substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + v3 = rfc5652.CMSVersion().subtype(value='v3') + assert asn1Object['content']['version'] == v3 + + for sa in asn1Object['content']['signerInfos'][0]['signedAttrs']: + assert sa['attrType'] in rfc5652.cmsAttributesMap.keys() + if sa['attrType'] == rfc5652.id_messageDigest: + assert '0x412598a6ae2' in sa['attrValues'][0].prettyPrint() + + ct_oid = asn1Object['content']['encapContentInfo']['eContentType'] + assert ct_oid in rfc5652.cmsContentTypesMap + assert ct_oid == rfc7191.id_ct_KP_keyPackageReceipt + + # Since receipt is inside an OCTET STRING, decodeOpenTypes=True cannot + # automatically decode it + sd_eci = asn1Object['content']['encapContentInfo'] + receipt, rest = der_decode(sd_eci['eContent'], + asn1Spec=rfc5652.cmsContentTypesMap[sd_eci['eContentType']]) + package_id_pem_text = "J7icVjsWIlGdF4cceb+siG3f+D0=" + package_id = pem.readBase64fromText(package_id_pem_text) + assert receipt['receiptOf']['pkgID'] == package_id + +class ErrorTestCase(unittest.TestCase): + message3_pem_text = """\ +MIIEbwYJKoZIhvcNAQcCoIIEYDCCBFwCAQMxDTALBglghkgBZQMEAgIwga0GCmCGSAFlAgEC +TgaggZ4EgZswgZigFgQUJ7icVjsWIlGdF4cceb+siG3f+D0wewYJYIZIAWUCARAABG4wbDEL +MAkGA1UEBhMCVVMxCzAJBgNVBAgTAlZBMRAwDgYDVQQHEwdIZXJuZG9uMRAwDgYDVQQKEwdF +eGFtcGxlMQwwCgYDVQQDEwNCb2IxHjAcBgkqhkiG9w0BCQEWD2JvYkBleGFtcGxlLmNvbQoB +CqCCAncwggJzMIIB+qADAgECAgkApbNUKBuwbjwwCgYIKoZIzj0EAwMwPzELMAkGA1UEBhMC +VVMxCzAJBgNVBAgMAlZBMRAwDgYDVQQHDAdIZXJuZG9uMREwDwYDVQQKDAhCb2d1cyBDQTAe +Fw0xOTA1MjkxOTIwMTNaFw0yMDA1MjgxOTIwMTNaMGwxCzAJBgNVBAYTAlVTMQswCQYDVQQI +EwJWQTEQMA4GA1UEBxMHSGVybmRvbjEQMA4GA1UEChMHRXhhbXBsZTEMMAoGA1UEAxMDQm9i +MR4wHAYJKoZIhvcNAQkBFg9ib2JAZXhhbXBsZS5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AAQxpGJVLxa83xhyal+rvmMFs4xS6Q19cCDoAvQkkFe0gUC4glxlWWQuf/FvLCRwwscr877D +1FZRBrYKPD6Hxv/UKX6Aimou0TnnxsPk98zZpikn9gTrJn2cF9NCzvPVMfmjgZQwgZEwCwYD +VR0PBAQDAgeAMEIGCWCGSAGG+EIBDQQ1FjNUaGlzIGNlcnRpZmljYXRlIGNhbm5vdCBiZSB0 +cnVzdGVkIGZvciBhbnkgcHVycG9zZS4wHQYDVR0OBBYEFMprZnLeLJtXf5iO4sMq02aOwhql +MB8GA1UdIwQYMBaAFPI12zQE2qVV8r1pA5mwYuziFQjBMAoGCCqGSM49BAMDA2cAMGQCMBVu +hLo58RhCiYsOLZFSR3vWHPDCJBnO1vE1uixqEjONHxlBoeGN2MmWs/9PppcHCwIwN9HB5jPc +J7gTjA9+ipCe+qkztmV+Gy2NBAY6xYC0gh+pb+X5OAI7y7HdctXp+PfrMYIBGzCCARcCAQOA +FMprZnLeLJtXf5iO4sMq02aOwhqlMAsGCWCGSAFlAwQCAqB6MBkGCSqGSIb3DQEJAzEMBgpg +hkgBZQIBAk4GMBwGCSqGSIb3DQEJBTEPFw0xOTA2MTMxNjE2MDhaMD8GCSqGSIb3DQEJBDEy +BDCgXFTUc3ZInjt+MWYkYmXYERk4FgErEZNILlWgVl7Z9pImgLObIpdrGqGPt06/VkwwCgYI +KoZIzj0EAwMEZzBlAjEAsjJ3iWRUteMKBVsjaYeN6TG9NITRTOpRVkSVq55DcnhwS9g9lu8D +iNF8uKtW/lk0AjA7z2q40N0lamXkSU7ECasiWOYV1X4cWGiQwMZDKknBPDqXqB6Es6p4J+qe +0V6+BtY= +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.message3_pem_text) + asn1Object, rest = der_decode (substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + sd, rest = der_decode (asn1Object['content'], + asn1Spec=rfc5652.SignedData()) + assert not rest + assert sd.prettyPrint() + assert der_encode(sd) == asn1Object['content'] + + oid = sd['encapContentInfo']['eContentType'] + assert oid == rfc7191.id_ct_KP_keyPackageError + kpe, rest = der_decode(sd['encapContentInfo']['eContent'], + asn1Spec=rfc7191.KeyPackageError()) + assert not rest + assert kpe.prettyPrint() + assert der_encode(kpe) == sd['encapContentInfo']['eContent'] + + package_id_pem_text = "J7icVjsWIlGdF4cceb+siG3f+D0=" + package_id = pem.readBase64fromText(package_id_pem_text) + assert kpe['errorOf']['pkgID'] == package_id + assert kpe['errorCode'] == rfc7191.EnumeratedErrorCode(value=10) + + def testOpenTypes(self): + substrate = pem.readBase64fromText(self.message3_pem_text) + rfc5652.cmsContentTypesMap.update(rfc7191.cmsContentTypesMapUpdate) + rfc5652.cmsAttributesMap.update(rfc7191.cmsAttributesMapUpdate) + asn1Object, rest = der_decode (substrate, + asn1Spec=self.asn1Spec, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + assert asn1Object['contentType'] == rfc5652.id_signedData + v3 = rfc5652.CMSVersion().subtype(value='v3') + assert asn1Object['content']['version'] == v3 + + for sa in asn1Object['content']['signerInfos'][0]['signedAttrs']: + assert sa['attrType'] in rfc5652.cmsAttributesMap.keys() + if sa['attrType'] == rfc5652.id_messageDigest: + assert '0xa05c54d4737' in sa['attrValues'][0].prettyPrint() + + ct_oid = asn1Object['content']['encapContentInfo']['eContentType'] + assert ct_oid in rfc5652.cmsContentTypesMap.keys() + assert ct_oid == rfc7191.id_ct_KP_keyPackageError + + # Since receipt is inside an OCTET STRING, decodeOpenTypes=True cannot + # automatically decode it + sd_eci = asn1Object['content']['encapContentInfo'] + kpe, rest = der_decode(sd_eci['eContent'], + asn1Spec=rfc5652.cmsContentTypesMap[sd_eci['eContentType']]) + package_id_pem_text = "J7icVjsWIlGdF4cceb+siG3f+D0=" + package_id = pem.readBase64fromText(package_id_pem_text) + assert kpe['errorOf']['pkgID'] == package_id + assert kpe['errorCode'] == rfc7191.EnumeratedErrorCode(value=10) + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc7296.py b/tests/test_rfc7296.py new file mode 100644 index 0000000..bcd28ee --- /dev/null +++ b/tests/test_rfc7296.py @@ -0,0 +1,167 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# + +import sys + +from pyasn1.codec.der.decoder import decode as der_decode +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1_modules import pem +from pyasn1_modules import rfc5280 +from pyasn1_modules import rfc7296 + +from pyasn1.type.univ import noValue + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class CertBundleTestCase(unittest.TestCase): + cert_bundle_pem_text = """\ +MIITfqCCA8kwggPFMIICraADAgECAhACrFwmagtAm48LefKuRiV3MA0GCSqGSIb3 +DQEBBQUAMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX +BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNVBAMTIkRpZ2lDZXJ0IEhpZ2gg +QXNzdXJhbmNlIEVWIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAw +MDAwWjBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD +VQQLExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFz +c3VyYW5jZSBFViBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAxszlc+b71LvlLS0ypt/lgT/JzSVJtnEqw9WUNGeiChywX2mmQLHEt7KP0Jik +qUFZOtPclNY823Q4pErMTSWC90qlUxI47vNJbXGRfmO2q6Zfw6SE+E9iUb74xezb +OJLjBuUIkQzEKEFV+8taiRV+ceg1v01yCT2+OjhQW3cxG42zxyRFmqesbQAUWgS3 +uhPrUQqYQUEiTmVhh4FBUKZ5XIneGUpX1S7mXRxTLH6YzRoGFqRoc9A0BBNcoXHT +WnxV215k4TeHMFYE5RG0KYAS8Xk5iKICEXwnZreIt3jyygqoOKsKZMK/Zl2VhMGh +JR6HXRpQCyASzEG7bgtROLhLywIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUsT7DaQP4v0cB1JgmGggC72NkK8MwHwYD +VR0jBBgwFoAUsT7DaQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQEFBQADggEB +ABwaBpfc15yfPIhmBghXIdshR/gqZ6q/GDJ2QBBXwYrzetkRZY41+p78RbWe2Uwx +S7iR6EMsjrN4ztvjU3lx1uUhlAHaVYeaJGT2imbM3pw3zag0sWmbI8ieeCIrcEPj +VUcxYRnvWMWFL04w9qAxFiPI5+JlFjPLvxoboD34yl6LMYtgCIktDAZcUrfE+QqY +0RVfnxK+fDZjOL1EpH/kJisKxJdpDemM4sAQV7jIdhKRVfJIadi8KgJbD0TUIDHb +9LpwJl2QYJ68SxcJL7TLHkNoyQcnwdJc9+ohuWgSnDycv578gFybY83sR6olJ2eg +N/MAgn1U16n46S4To3foH0qgggS6MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf +4msdgzANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGln +aUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJE +aWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAw +MFoXDTI4MTAyMjEyMDAwMFowdTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD +ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGln +aUNlcnQgU0hBMiBFeHRlbmRlZCBWYWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAA +h/FnKIaFjI5j2ryxQDji0/XspQUYuD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9o +m9KxjxKws9LniB8f7zh3VFNfgHk/LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzi +kIKHaq7q12TWmFXo/a8aUGxUvBHy/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIcl +ho3YIeSwTQyJ3DkmF93215SF2AQhcJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6 +Ku8hI3UarS2bhjWMnHe1c63YlC3k8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOC +AUkwggFFMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYB +BQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8 +hjpodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNl +RVZSb290Q0EuY3JsMD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxo +dHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNK +YApl0yHU+PjWDzAfBgNVHSMEGDAWgBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkq +hkiG9w0BAQsFAAOCAQEAnbbQkIbhhgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18 +CK3mtlC4ohpNiAexKSHc59rGPCHg4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9X +R3WhfVUgLkc3UHKMf4Ib0mKPLQNa2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNo +PLpSgVh5oywM395t6zHyuqB8bPEs1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6M +o8wNXrM9zwR4jxQUezKcxwCmXMS1oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti +6G8MdOu42vi/hw15UJGQmxg7kVkn8TUoE6smftX3eqCCB9wwggfYMIIGwKADAgEC +AhABW9pmX8RLdRe2iCweq9TcMA0GCSqGSIb3DQEBCwUAMHUxCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xNDAyBgNVBAMTK0RpZ2lDZXJ0IFNIQTIgRXh0ZW5kZWQgVmFsaWRhdGlvbiBT +ZXJ2ZXIgQ0EwHhcNMTgwODE0MDAwMDAwWhcNMjAwODE4MTIwMDAwWjCB3DEdMBsG +A1UEDwwUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzARBgsrBgEEAYI3PAIBAxMCVVMx +GTAXBgsrBgEEAYI3PAIBAhMIRGVsYXdhcmUxEDAOBgNVBAUTBzMwMTQyNjcxCzAJ +BgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9z +ZTEVMBMGA1UEChMMUGF5UGFsLCBJbmMuMRQwEgYDVQQLEwtDRE4gU3VwcG9ydDEX +MBUGA1UEAxMOd3d3LnBheXBhbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDOofrgGYvXjVHH1WKEgxO51/bNk8Vw0WlZAyu0iwAUULZ3mrI8+xOw +gE5VGghgoQY9QNIA0mdFPrEmRRQAZXitszlL5s8oks4+tFzBHHtJp2D9BixRKxAR +Afo6c54tufaJUrQyIMwr2mpfbPox3palkK7RmHdimcOqtUjjQyS/WcHxMkyX3wa9 +e1JoEB9ofJGupNnC90uGgxilWLvOtn/27w56p2AYkKoSGgXsNRGE5ySxns23sZOo +tgSeTRe16K7X5JuzPcGtZGMRxlkVagZsrp8rNsf4aq0wKkBjkvVzSvJTaDJSDqEt +hV+ZoGSFYpwaHArVir0sJ63E/aq2Tb97AgMBAAGjggP6MIID9jAfBgNVHSMEGDAW +gBQ901Cl1qCt7vNKYApl0yHU+PjWDzAdBgNVHQ4EFgQUuzrmqCkAmIQyec538AFt +Xwp5Y7kwgaUGA1UdEQSBnTCBmoIOd3d3LnBheXBhbC5jb22CEmhpc3RvcnkucGF5 +cGFsLmNvbYIMdC5wYXlwYWwuY29tggxjLnBheXBhbC5jb22CDWM2LnBheXBhbC5j +b22CFGRldmVsb3Blci5wYXlwYWwuY29tggxwLnBheXBhbC5jb22CFXd3dy5wYXlw +YWxvYmplY3RzLmNvbYIOY21zLnBheXBhbC5jb20wDgYDVR0PAQH/BAQDAgWgMB0G +A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5o +dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1ldi1zZXJ2ZXItZzIuY3JsMDSg +MqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1ldi1zZXJ2ZXItZzIu +Y3JsMEsGA1UdIAREMEIwNwYJYIZIAYb9bAIBMCowKAYIKwYBBQUHAgEWHGh0dHBz +Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwBwYFZ4EMAQEwgYgGCCsGAQUFBwEBBHww +ejAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFIGCCsGAQUF +BzAChkZodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyRXh0 +ZW5kZWRWYWxpZGF0aW9uU2VydmVyQ0EuY3J0MAwGA1UdEwEB/wQCMAAwggF+Bgor +BgEEAdZ5AgQCBIIBbgSCAWoBaAB3AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3 +zQ7IDdwQAAABZTquQ3wAAAQDAEgwRgIhAMvZlCpgP2+v8gH82y3PQoMNVUVQNBjG +4DZy7qRFBo0JAiEAkzEfNkc2/B+88VR3QjutnaF1Qpj0QkSodPGAtB377UUAdQBW +FAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAWU6rkPZAAAEAwBGMEQC +IHAvzbsYhbMy5jUazj6X3mDMjjyryN5BMwbDIFv58T9nAiBxzUIRTfj+Kevp0mmO +Oe9q6K/klOU2klRuVmcs7Gzw8AB2ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCW +ZDaOHtGFAAABZTquRGgAAAQDAEcwRQIhAMvzcJw5loOfVnDNFEr4+c4y/usA2pU5 +M7vhHND680tHAiASqPd7KXNaNTJsBJ9IfBN6J2XwGJjxccRy9fJc9+UgYjANBgkq +hkiG9w0BAQsFAAOCAQEAoeuef8cXLigvTQs4lbtbyp4UOIzspiMmHztqB95OS0ER +/u7995SO0C0mQjvyPeiptQ5Yh+/OVCqV6p2ZpBmSc+mn5tzjP3LaVxoyjwghja03 +mNBXPmdkEIG+V78Ov5iIm6vxGH1xSjHssV8iXpWo3gJ+xH3krtY1Atkg243JgwNC +I3xgp01VMLAmvIvvTqmIKeEd88Ukc6kHcZsEjxwtNivWx2nl1cyDu9B1wJK0D5Mu +IBXgbFKmqUhWlEXRimphvONOJGd71qT94bT/+bhq28oGleH1leTvqft0fj+e/a7e +Hx1u3fYAxNWjNAImIxpGUyUwSVo29w/CYYc2cS69y6GB7TCB6jCBqQIBATALBgcq +hkjOOAQDBQAwLjELMAkGA1UEBhMCdXMxDDAKBgNVBAoTA3N1bjERMA8GA1UEAxMI +aGFuZmVpeXUXDTA1MDEwNzIwMDkxMFoXDTA2MDEwNzIwMDkxMFowSTAjAgMBCTIX +DTA1MDEwNzIwMDkxMFowDTALBgNVHRUEBAoCAQQwIgICMDkXDTA1MDEwNzIwMDkx +MFowDTALBgNVHRUEBAoCAQEwCwYHKoZIzjgEAwUAAy8AMCwCFFbxw8qxTDJqc8H9 +O1QIkzwkkvJfAhRF5zFU8mFsrKmnE50ERySS8vA6AKGCAh8wggIbMIIBAwIBATAN +BgkqhkiG9w0BAQsFADBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQg +SW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2Vy +dCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBFw0xOTA1MDIyMjE1NTRaFw0xOTA1 +MjMyMjE1NTRaMDEwLwIQDPWCOBgZnlb4K9ZS7Sft6RcNMTgxMDI1MTYxMTM4WjAM +MAoGA1UdFQQDCgEAoDAwLjAfBgNVHSMEGDAWgBSxPsNpA/i/RwHUmCYaCALvY2Qr +wzALBgNVHRQEBAICAcQwDQYJKoZIhvcNAQELBQADggEBABPO3OA0OkQZ+RLVxz/c +Nx5uNVEO416oOePkN0A4DxFztf337caS4OyfS9Wyu1j5yUdWJVpAKXSQeN95MqHk +pSpYDssuqbuYjv8ViJfseGBgtXTczUzzNeNdY2uxMbCxuhmPkgacAo1lx9LkK2Sc +YHWVbfFRF1UQ/dcmavaZsEOBNuLWOxQYA9MqfVNAymHe7vPqwm/8IY2FbHe9HsiJ +ZfGxNWMDP5lmJiXmpntTeDQ2UjdiyXwGGKjyiSTFk2jVRutrGINufaoA/f7eCmIb +4UDPbpMjVfD215dW8eBKouypCVoEvmCSSTacdiBI2yOluvMN0PzvPve0ECAE+D4e +m9Y= +""" + + def setUp(self): + self.asn1Spec = rfc7296.CertificateBundle() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.cert_bundle_pem_text) + asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + cert_count = 0 + crl_count = 0 + unk_count = 0 + for item in asn1Object: + if item.getName() == 'cert': + cert_count += 1 + elif item.getName() == 'crl': + crl_count += 1 + else: + unk_count += 1 + + assert cert_count == 3 + assert crl_count == 2 + assert unk_count == 0 + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc8103.py b/tests/test_rfc8103.py index 56a96fb..921b9db 100644 --- a/tests/test_rfc8103.py +++ b/tests/test_rfc8103.py @@ -15,7 +15,6 @@ from pyasn1_modules import pem from pyasn1_modules import rfc5280 from pyasn1_modules import rfc8103 - try: import unittest2 as unittest except ImportError: @@ -44,6 +43,9 @@ class CAEADChaCha20Poly1305TestCase(unittest.TestCase): suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc8226.py b/tests/test_rfc8226.py index a7dc036..69fd438 100644 --- a/tests/test_rfc8226.py +++ b/tests/test_rfc8226.py @@ -12,6 +12,7 @@ from pyasn1.codec.der import decoder as der_decoder from pyasn1.codec.der import encoder as der_encoder from pyasn1_modules import pem +from pyasn1_modules import rfc5280 from pyasn1_modules import rfc8226 try: @@ -48,7 +49,48 @@ class TNAuthorizationListTestCase(unittest.TestCase): assert der_encoder.encode(asn1Object) == substrate +class CertificateOpenTypesTestCase(unittest.TestCase): + cert_pem_text = """\ +MIICkTCCAhegAwIBAgIJAKWzVCgbsG4+MAoGCCqGSM49BAMDMD8xCzAJBgNVBAYT +AlVTMQswCQYDVQQIDAJWQTEQMA4GA1UEBwwHSGVybmRvbjERMA8GA1UECgwIQm9n +dXMgQ0EwHhcNMTkwNzE4MTUwNzQ5WhcNMjAwNzE3MTUwNzQ5WjBxMQswCQYDVQQG +EwJVUzELMAkGA1UECBMCVkExEDAOBgNVBAcTB0hlcm5kb24xKDAmBgNVBAoTH0Zh +a2UgVGVsZXBob25lIFNlcnZpY2UgUHJvdmlkZXIxGTAXBgNVBAMTEGZha2UuZXhh +bXBsZS5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARLyLhnsvrS9WBY29tmN2LI +CF/wuX4ohhUy3sxO0ynCplHHojpDg+tghGzusf0aLtMDu1II915O8YK5XVL+KZJD +C82jybxWIKjjzX2qc5/O06joUttdEDzkTaD0kgbcXl6jgawwgakwCwYDVR0PBAQD +AgeAMEIGCWCGSAGG+EIBDQQ1FjNUaGlzIGNlcnRpZmljYXRlIGNhbm5vdCBiZSB0 +cnVzdGVkIGZvciBhbnkgcHVycG9zZS4wHQYDVR0OBBYEFHOI3GpDt9dWsTAZxhcj +96uyL2aIMB8GA1UdIwQYMBaAFPI12zQE2qVV8r1pA5mwYuziFQjBMBYGCCsGAQUF +BwEaBAowCKAGFgRmYWtlMAoGCCqGSM49BAMDA2gAMGUCMQCy+qFhT7X1i18jcyIa +Jkgz/tumrPsaBA2RihkooTEr4GbqC650Z4Cwt7+x2xZq37sCMFSM6fRueLyV5StG +yEFWA6G95b/HbtPMTjLpPKtrOjhofc4LyVCDYhFhKzpvHh1qeA== +""" + + def setUp(self): + self.asn1Spec = rfc5280.Certificate() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.cert_pem_text) + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + for extn in asn1Object['tbsCertificate']['extensions']: + if extn['extnID'] in rfc5280.certificateExtensionsMap.keys(): + extnValue, rest = der_decoder.decode(extn['extnValue'], + asn1Spec=rfc5280.certificateExtensionsMap[extn['extnID']]) + assert der_encoder.encode(extnValue) == extn['extnValue'] + + if extn['extnID'] == rfc8226.id_pe_TNAuthList: + assert extnValue[0]['spc'] == 'fake' + + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc8410.py b/tests/test_rfc8410.py index 7c74175..e37bad0 100644 --- a/tests/test_rfc8410.py +++ b/tests/test_rfc8410.py @@ -41,4 +41,7 @@ class PrivateKeyTestCase(unittest.TestCase): suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc8418.py b/tests/test_rfc8418.py index b0dbb7d..46ac689 100644 --- a/tests/test_rfc8418.py +++ b/tests/test_rfc8418.py @@ -40,4 +40,7 @@ class KeyAgreeAlgTestCase(unittest.TestCase): suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite) + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc8520.py b/tests/test_rfc8520.py new file mode 100644 index 0000000..483b81a --- /dev/null +++ b/tests/test_rfc8520.py @@ -0,0 +1,106 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# + +import sys + +from pyasn1.codec.der.decoder import decode as der_decode +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1_modules import pem +from pyasn1_modules import rfc5280 +from pyasn1_modules import rfc8520 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class MUDCertTestCase(unittest.TestCase): + mud_cert_pem_text = """\ +MIIFODCCAyCgAwIBAgICEEAwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UEBhMCQ0gx +DzANBgNVBAgMBlp1cmljaDERMA8GA1UEBwwIV2V0emlrb24xEDAOBgNVBAoMB0lt +UmlnaHQxIDAeBgNVBAMMF0ltUmlnaHQgVGVzdCA4MDIuMUFSIENBMB4XDTE5MDUw +MTE4MDMyMVoXDTE5MDUzMTE4MDMyMVowZzELMAkGA1UEBhMCQ0gxEzARBgNVBAgM +ClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEg +MB4GA1UEAwwXTGlnaHRidWxiMjAwMCwgU04jMjAyMDIwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCzntv6tCdkZWPUx+CK9A9PCgKF8zGCJwdU4eIjo0oe +A81i7iltOPnU416GJMEc2jGhlZPn2Rjjy8tPbyh1RVBfkgdq4UPWPnZPb+Gkq1c8 +X8zLRrMSWKqkSGOPENieDuQpzcrkMfj7dCPcxTcJ5Gluv1jEI7bxoZOZXjNxaFXi +vsaZWFub7b+5zDLWpvmpKDaeCU+gad7rWpRE/Hjh3FX8paW8KE/hMF/au4xX2Qj/ +rDwHSxgs3n8FtuFUELotSgL3Acy3aISmJILBx6XrSs3nLruZzamulwWupSryHo3L +U+GsOETiXwxiyrfOZo3aJNnWzlEvrYCQGyqd8Nd/XOENAgMBAAGjge8wgewwCQYD +VR0TBAIwADBABggrBgEFBQcBGQQ0FjJodHRwczovL3d3dy5vZmNvdXJzZWltcmln +aHQuY29tL0x1bWluYWlyZV8xNTAuanNvbjBdBggrBgEFBQcBHgRRME8xCzAJBgNV +BAYTAkNIMSswKQYJKoZIhvcNAQkBFhxhc2NlcnRpYUBvZmNvdXJzZWltcmlnaHQu +Y29tMRMwEQYDVQQDEwpFbGlvdCBMZWFyMB0GA1UdDgQWBBS00spi6cRFdqz95TQI +9AuPn5/DRjAfBgNVHSMEGDAWgBREKvrASIa7JJ41mQWDkJ06rXTCtTANBgkqhkiG +9w0BAQsFAAOCAgEAiS4OlazkDpgR4qhrq5Wpx6m3Bmkk5RkXnqey1yyhyfZlAGH7 +ewQiybkF3nN6at/TcNWMRfGBLhRrQn1h75KEXKlc18RDorj72/bvkbJLoBmA43Mv +xMF0w4YX8pQwzb4hSt04p79P2RVVYM3ex/vdok0KkouhLTlxzY7vhv1T8WGTVQHJ +k2EyswS2nFa/OtIkwruXqJj+lotdV2yPgFav5j9lkw5VbOztlfSKT7qQInVm+VBI +/qddz/LOYrls1A7KHzWkTvOwmvQBqI4e9xLjc3r8K4pZyMd7EsmepYmLOU+pfINf +/sEjliCluR65mKcKGiUa5J31pzbVpCr6FM/NGEjqpp6F+slyNC8YM/UlaJK1W9ZI +W7JAhmfil5z1CtQILFSnUh4VneTVOaYg6+gXr169fXUDlMM4ECnuqWAE2PLhfhI8 ++lY8u18rFiX0bNSiUySgxU3asCC92xNmvJHuL4QwiYaGtTne36NMN7dH/32nMKl+ +G3XA8cX8yZIrIkmWLBSji8UwOXwVhYovmbhHjaUMTQommxYv/Cuqi5nJUJfh5YJr +APeEK6fTYpPMiZ6U1++qzZDp78MRAq7UQbluJHh8ujPuK6kQmSLXmvK5yGpnJ+Cw +izaUuU1EEwgOMELjeFL62Ssvq8X+x6hZFCLygI7GNeitlblNhCXhFFurqMs= +""" + + def setUp(self): + self.asn1Spec = rfc5280.Certificate() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.mud_cert_pem_text) + asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + for extn in asn1Object['tbsCertificate']['extensions']: + if extn['extnID'] == rfc8520.id_pe_mudsigner: + mudsigner, rest = der_decode(extn['extnValue'], rfc8520.MUDsignerSyntax()) + assert der_encode(mudsigner) == extn['extnValue'] + + c = rfc5280.X520countryName(value="CH") + assert mudsigner[0][0][0]['value'] == der_encode(c) + e = rfc5280.EmailAddress(value="ascertia@ofcourseimright.com") + assert mudsigner[0][1][0]['value'] == der_encode(e) + cn = rfc5280.X520CommonName() + cn['printableString'] = "Eliot Lear" + assert mudsigner[0][2][0]['value'] == der_encode(cn) + + if extn['extnID'] == rfc8520.id_pe_mud_url: + mudurl, rest = der_decode(extn['extnValue'], rfc8520.MUDURLSyntax()) + assert der_encode(mudurl) == extn['extnValue'] + + assert mudurl[-5:] == ".json" + + def testExtensionsMap(self): + substrate = pem.readBase64fromText(self.mud_cert_pem_text) + rfc5280.certificateExtensionsMap.update(rfc8520.certificateExtensionsMapUpdate) + asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + for extn in asn1Object['tbsCertificate']['extensions']: + if extn['extnID'] in rfc5280.certificateExtensionsMap.keys(): + extnValue, rest = der_decode(extn['extnValue'], + asn1Spec=rfc5280.certificateExtensionsMap[extn['extnID']]) + assert der_encode(extnValue) == extn['extnValue'] + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc8619.py b/tests/test_rfc8619.py new file mode 100644 index 0000000..05eee6a --- /dev/null +++ b/tests/test_rfc8619.py @@ -0,0 +1,85 @@ +# +# This file is part of pyasn1-modules software. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +import sys + +from pyasn1.codec.der import decoder as der_decoder +from pyasn1.codec.der import encoder as der_encoder + +from pyasn1_modules import pem +from pyasn1_modules import rfc5280 +from pyasn1_modules import rfc8619 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class HKDFSHA256TestCase(unittest.TestCase): + alg_id_1_pem_text = "MA0GCyqGSIb3DQEJEAMc" + + def setUp(self): + self.asn1Spec = rfc5280.AlgorithmIdentifier() + + def testDerCodec(self): + + substrate = pem.readBase64fromText(self.alg_id_1_pem_text) + + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + assert asn1Object['algorithm'] == rfc8619.id_alg_hkdf_with_sha256 + + +class HKDFSHA384TestCase(unittest.TestCase): + alg_id_1_pem_text = "MA0GCyqGSIb3DQEJEAMd" + + def setUp(self): + self.asn1Spec = rfc5280.AlgorithmIdentifier() + + def testDerCodec(self): + + substrate = pem.readBase64fromText(self.alg_id_1_pem_text) + + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + assert asn1Object['algorithm'] == rfc8619.id_alg_hkdf_with_sha384 + + +class HKDFSHA512TestCase(unittest.TestCase): + alg_id_1_pem_text = "MA0GCyqGSIb3DQEJEAMe" + + def setUp(self): + self.asn1Spec = rfc5280.AlgorithmIdentifier() + + def testDerCodec(self): + + substrate = pem.readBase64fromText(self.alg_id_1_pem_text) + + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + assert asn1Object['algorithm'] == rfc8619.id_alg_hkdf_with_sha512 + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) |