432 lines
12 KiB
Python
432 lines
12 KiB
Python
# coding: utf-8
|
|
# PyGOST -- Pure Python GOST cryptographic functions library
|
|
# Copyright (C) 2015-2023 Sergey Matveev <stargrave@stargrave.org>
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, version 3 of the License.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
"""CMS related structures (**NOT COMPLETE**)
|
|
"""
|
|
|
|
from pyderasn import Any
|
|
from pyderasn import BitString
|
|
from pyderasn import Choice
|
|
from pyderasn import Integer
|
|
from pyderasn import ObjectIdentifier
|
|
from pyderasn import OctetString
|
|
from pyderasn import Sequence
|
|
from pyderasn import SequenceOf
|
|
from pyderasn import SetOf
|
|
from pyderasn import tag_ctxc
|
|
from pyderasn import tag_ctxp
|
|
|
|
from pygost.asn1schemas.oids import id_cms_mac_attr
|
|
from pygost.asn1schemas.oids import id_contentType
|
|
from pygost.asn1schemas.oids import id_digestedData
|
|
from pygost.asn1schemas.oids import id_encryptedData
|
|
from pygost.asn1schemas.oids import id_envelopedData
|
|
from pygost.asn1schemas.oids import id_Gost28147_89
|
|
from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm
|
|
from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_ctracpkm_omac
|
|
from pygost.asn1schemas.oids import id_gostr3412_2015_kuznyechik_wrap_kexp15
|
|
from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm
|
|
from pygost.asn1schemas.oids import id_gostr3412_2015_magma_ctracpkm_omac
|
|
from pygost.asn1schemas.oids import id_gostr3412_2015_magma_wrap_kexp15
|
|
from pygost.asn1schemas.oids import id_messageDigest
|
|
from pygost.asn1schemas.oids import id_signedData
|
|
from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256
|
|
from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512
|
|
from pygost.asn1schemas.x509 import AlgorithmIdentifier
|
|
from pygost.asn1schemas.x509 import Certificate
|
|
from pygost.asn1schemas.x509 import CertificateSerialNumber
|
|
from pygost.asn1schemas.x509 import Name
|
|
from pygost.asn1schemas.x509 import SubjectPublicKeyInfo
|
|
|
|
|
|
class CMSVersion(Integer):
|
|
pass
|
|
|
|
|
|
class ContentType(ObjectIdentifier):
|
|
pass
|
|
|
|
|
|
class IssuerAndSerialNumber(Sequence):
|
|
schema = (
|
|
("issuer", Name()),
|
|
("serialNumber", CertificateSerialNumber()),
|
|
)
|
|
|
|
|
|
class KeyIdentifier(OctetString):
|
|
pass
|
|
|
|
|
|
class SubjectKeyIdentifier(KeyIdentifier):
|
|
pass
|
|
|
|
|
|
class RecipientIdentifier(Choice):
|
|
schema = (
|
|
("issuerAndSerialNumber", IssuerAndSerialNumber()),
|
|
("subjectKeyIdentifier", SubjectKeyIdentifier(impl=tag_ctxp(0))),
|
|
)
|
|
|
|
|
|
class Gost2814789Key(OctetString):
|
|
bounds = (32, 32)
|
|
|
|
|
|
class Gost2814789MAC(OctetString):
|
|
bounds = (4, 4)
|
|
|
|
|
|
class Gost2814789EncryptedKey(Sequence):
|
|
schema = (
|
|
("encryptedKey", Gost2814789Key()),
|
|
("maskKey", Gost2814789Key(impl=tag_ctxp(0), optional=True)),
|
|
("macKey", Gost2814789MAC()),
|
|
)
|
|
|
|
|
|
class GostR34102001TransportParameters(Sequence):
|
|
schema = (
|
|
("encryptionParamSet", ObjectIdentifier()),
|
|
("ephemeralPublicKey", SubjectPublicKeyInfo(
|
|
impl=tag_ctxc(0),
|
|
optional=True,
|
|
)),
|
|
("ukm", OctetString()),
|
|
)
|
|
|
|
|
|
class GostR3410KeyTransport(Sequence):
|
|
schema = (
|
|
("sessionEncryptedKey", Gost2814789EncryptedKey()),
|
|
("transportParameters", GostR34102001TransportParameters(
|
|
impl=tag_ctxc(0),
|
|
optional=True,
|
|
)),
|
|
)
|
|
|
|
|
|
class GostR3410KeyTransport2019(Sequence):
|
|
schema = (
|
|
("encryptedKey", OctetString()),
|
|
("ephemeralPublicKey", SubjectPublicKeyInfo()),
|
|
("ukm", OctetString()),
|
|
)
|
|
|
|
|
|
class GostR341012KEGParameters(Sequence):
|
|
schema = (
|
|
("algorithm", ObjectIdentifier()),
|
|
)
|
|
|
|
|
|
class KeyEncryptionAlgorithmIdentifier(AlgorithmIdentifier):
|
|
schema = (
|
|
("algorithm", ObjectIdentifier(defines=(
|
|
(("parameters",), {
|
|
id_gostr3412_2015_magma_wrap_kexp15: GostR341012KEGParameters(),
|
|
id_gostr3412_2015_kuznyechik_wrap_kexp15: GostR341012KEGParameters(),
|
|
}),
|
|
(("..", "encryptedKey"), {
|
|
id_tc26_gost3410_2012_256: GostR3410KeyTransport(),
|
|
id_tc26_gost3410_2012_512: GostR3410KeyTransport(),
|
|
id_gostr3412_2015_magma_wrap_kexp15: GostR3410KeyTransport2019(),
|
|
id_gostr3412_2015_kuznyechik_wrap_kexp15: GostR3410KeyTransport2019(),
|
|
}),
|
|
(("..", "recipientEncryptedKeys", any, "encryptedKey"), {
|
|
id_tc26_gost3410_2012_256: Gost2814789EncryptedKey(),
|
|
id_tc26_gost3410_2012_512: Gost2814789EncryptedKey(),
|
|
}),
|
|
))),
|
|
("parameters", Any(optional=True)),
|
|
)
|
|
|
|
|
|
class EncryptedKey(OctetString):
|
|
pass
|
|
|
|
|
|
class KeyTransRecipientInfo(Sequence):
|
|
schema = (
|
|
("version", CMSVersion()),
|
|
("rid", RecipientIdentifier()),
|
|
("keyEncryptionAlgorithm", KeyEncryptionAlgorithmIdentifier()),
|
|
("encryptedKey", EncryptedKey()),
|
|
)
|
|
|
|
|
|
class OriginatorPublicKey(Sequence):
|
|
schema = (
|
|
("algorithm", AlgorithmIdentifier()),
|
|
("publicKey", BitString()),
|
|
)
|
|
|
|
|
|
class OriginatorIdentifierOrKey(Choice):
|
|
schema = (
|
|
("issuerAndSerialNumber", IssuerAndSerialNumber()),
|
|
("subjectKeyIdentifier", SubjectKeyIdentifier(impl=tag_ctxp(0))),
|
|
("originatorKey", OriginatorPublicKey(impl=tag_ctxc(1))),
|
|
)
|
|
|
|
|
|
class UserKeyingMaterial(OctetString):
|
|
pass
|
|
|
|
|
|
class KeyAgreeRecipientIdentifier(Choice):
|
|
schema = (
|
|
("issuerAndSerialNumber", IssuerAndSerialNumber()),
|
|
# ("rKeyId", RecipientKeyIdentifier(impl=tag_ctxc(0))),
|
|
)
|
|
|
|
|
|
class RecipientEncryptedKey(Sequence):
|
|
schema = (
|
|
("rid", KeyAgreeRecipientIdentifier()),
|
|
("encryptedKey", EncryptedKey()),
|
|
)
|
|
|
|
|
|
class RecipientEncryptedKeys(SequenceOf):
|
|
schema = RecipientEncryptedKey()
|
|
|
|
|
|
class KeyAgreeRecipientInfo(Sequence):
|
|
schema = (
|
|
("version", CMSVersion(3)),
|
|
("originator", OriginatorIdentifierOrKey(expl=tag_ctxc(0))),
|
|
("ukm", UserKeyingMaterial(expl=tag_ctxc(1), optional=True)),
|
|
("keyEncryptionAlgorithm", KeyEncryptionAlgorithmIdentifier()),
|
|
("recipientEncryptedKeys", RecipientEncryptedKeys()),
|
|
)
|
|
|
|
|
|
class RecipientInfo(Choice):
|
|
schema = (
|
|
("ktri", KeyTransRecipientInfo()),
|
|
("kari", KeyAgreeRecipientInfo(impl=tag_ctxc(1))),
|
|
# ("kekri", KEKRecipientInfo(impl=tag_ctxc(2))),
|
|
# ("pwri", PasswordRecipientInfo(impl=tag_ctxc(3))),
|
|
# ("ori", OtherRecipientInfo(impl=tag_ctxc(4))),
|
|
)
|
|
|
|
|
|
class RecipientInfos(SetOf):
|
|
schema = RecipientInfo()
|
|
bounds = (1, float("+inf"))
|
|
|
|
|
|
class Gost2814789IV(OctetString):
|
|
bounds = (8, 8)
|
|
|
|
|
|
class Gost2814789Parameters(Sequence):
|
|
schema = (
|
|
("iv", Gost2814789IV()),
|
|
("encryptionParamSet", ObjectIdentifier()),
|
|
)
|
|
|
|
|
|
class Gost341215EncryptionParameters(Sequence):
|
|
schema = (
|
|
("ukm", OctetString()),
|
|
)
|
|
|
|
|
|
class ContentEncryptionAlgorithmIdentifier(AlgorithmIdentifier):
|
|
schema = (
|
|
("algorithm", ObjectIdentifier(defines=(
|
|
(("parameters",), {
|
|
id_Gost28147_89: Gost2814789Parameters(),
|
|
id_gostr3412_2015_magma_ctracpkm: Gost341215EncryptionParameters(),
|
|
id_gostr3412_2015_kuznyechik_ctracpkm: Gost341215EncryptionParameters(),
|
|
id_gostr3412_2015_magma_ctracpkm_omac: Gost341215EncryptionParameters(),
|
|
id_gostr3412_2015_kuznyechik_ctracpkm_omac: Gost341215EncryptionParameters(),
|
|
}),
|
|
))),
|
|
("parameters", Any(optional=True)),
|
|
)
|
|
|
|
|
|
class EncryptedContent(OctetString):
|
|
pass
|
|
|
|
|
|
class EncryptedContentInfo(Sequence):
|
|
schema = (
|
|
("contentType", ContentType()),
|
|
("contentEncryptionAlgorithm", ContentEncryptionAlgorithmIdentifier()),
|
|
("encryptedContent", EncryptedContent(impl=tag_ctxp(0), optional=True)),
|
|
)
|
|
|
|
|
|
class Digest(OctetString):
|
|
pass
|
|
|
|
|
|
class AttributeValue(Any):
|
|
pass
|
|
|
|
|
|
class AttributeValues(SetOf):
|
|
schema = AttributeValue()
|
|
|
|
|
|
class EncryptedMac(OctetString):
|
|
pass
|
|
|
|
|
|
class Attribute(Sequence):
|
|
schema = (
|
|
("attrType", ObjectIdentifier(defines=(
|
|
(("attrValues",), {
|
|
id_contentType: ObjectIdentifier(),
|
|
id_messageDigest: Digest(),
|
|
id_cms_mac_attr: EncryptedMac(),
|
|
},),
|
|
))),
|
|
("attrValues", AttributeValues()),
|
|
)
|
|
|
|
|
|
class UnprotectedAttributes(SetOf):
|
|
schema = Attribute()
|
|
bounds = (1, float("+inf"))
|
|
|
|
|
|
class CertificateChoices(Choice):
|
|
schema = (
|
|
("certificate", Certificate()),
|
|
# ("extendedCertificate", OctetString(impl=tag_ctxp(0))),
|
|
# ("v1AttrCert", AttributeCertificateV1(impl=tag_ctxc(1))), # V1 is osbolete
|
|
# ("v2AttrCert", AttributeCertificateV2(impl=tag_ctxc(2))),
|
|
# ("other", OtherCertificateFormat(impl=tag_ctxc(3))),
|
|
)
|
|
|
|
|
|
class CertificateSet(SetOf):
|
|
schema = CertificateChoices()
|
|
|
|
|
|
class OriginatorInfo(Sequence):
|
|
schema = (
|
|
("certs", CertificateSet(impl=tag_ctxc(0), optional=True)),
|
|
# ("crls", RevocationInfoChoices(impl=tag_ctxc(1), optional=True)),
|
|
)
|
|
|
|
|
|
class EnvelopedData(Sequence):
|
|
schema = (
|
|
("version", CMSVersion()),
|
|
("originatorInfo", OriginatorInfo(impl=tag_ctxc(0), optional=True)),
|
|
("recipientInfos", RecipientInfos()),
|
|
("encryptedContentInfo", EncryptedContentInfo()),
|
|
("unprotectedAttrs", UnprotectedAttributes(impl=tag_ctxc(1), optional=True)),
|
|
)
|
|
|
|
|
|
class EncapsulatedContentInfo(Sequence):
|
|
schema = (
|
|
("eContentType", ContentType()),
|
|
("eContent", OctetString(expl=tag_ctxc(0), optional=True)),
|
|
)
|
|
|
|
|
|
class SignerIdentifier(Choice):
|
|
schema = (
|
|
("issuerAndSerialNumber", IssuerAndSerialNumber()),
|
|
("subjectKeyIdentifier", SubjectKeyIdentifier(impl=tag_ctxp(0))),
|
|
)
|
|
|
|
|
|
class DigestAlgorithmIdentifiers(SetOf):
|
|
schema = AlgorithmIdentifier()
|
|
|
|
|
|
class DigestAlgorithmIdentifier(AlgorithmIdentifier):
|
|
pass
|
|
|
|
|
|
class SignatureAlgorithmIdentifier(AlgorithmIdentifier):
|
|
pass
|
|
|
|
|
|
class SignatureValue(OctetString):
|
|
pass
|
|
|
|
|
|
class SignedAttributes(SetOf):
|
|
schema = Attribute()
|
|
bounds = (1, float("+inf"))
|
|
|
|
|
|
class SignerInfo(Sequence):
|
|
schema = (
|
|
("version", CMSVersion()),
|
|
("sid", SignerIdentifier()),
|
|
("digestAlgorithm", DigestAlgorithmIdentifier()),
|
|
("signedAttrs", SignedAttributes(impl=tag_ctxc(0), optional=True)),
|
|
("signatureAlgorithm", SignatureAlgorithmIdentifier()),
|
|
("signature", SignatureValue()),
|
|
# ("unsignedAttrs", UnsignedAttributes(impl=tag_ctxc(1), optional=True)),
|
|
)
|
|
|
|
|
|
class SignerInfos(SetOf):
|
|
schema = SignerInfo()
|
|
|
|
|
|
class SignedData(Sequence):
|
|
schema = (
|
|
("version", CMSVersion()),
|
|
("digestAlgorithms", DigestAlgorithmIdentifiers()),
|
|
("encapContentInfo", EncapsulatedContentInfo()),
|
|
("certificates", CertificateSet(impl=tag_ctxc(0), optional=True)),
|
|
# ("crls", RevocationInfoChoices(impl=tag_ctxc(1), optional=True)),
|
|
("signerInfos", SignerInfos()),
|
|
)
|
|
|
|
|
|
class DigestedData(Sequence):
|
|
schema = (
|
|
("version", CMSVersion()),
|
|
("digestAlgorithm", DigestAlgorithmIdentifier()),
|
|
("encapContentInfo", EncapsulatedContentInfo()),
|
|
("digest", Digest()),
|
|
)
|
|
|
|
|
|
class EncryptedData(Sequence):
|
|
schema = (
|
|
("version", CMSVersion()),
|
|
("encryptedContentInfo", EncryptedContentInfo()),
|
|
("unprotectedAttrs", UnprotectedAttributes(impl=tag_ctxc(1), optional=True)),
|
|
)
|
|
|
|
|
|
class ContentInfo(Sequence):
|
|
schema = (
|
|
("contentType", ContentType(defines=(
|
|
(("content",), {
|
|
id_digestedData: DigestedData(),
|
|
id_encryptedData: EncryptedData(),
|
|
id_envelopedData: EnvelopedData(),
|
|
id_signedData: SignedData(),
|
|
}),
|
|
))),
|
|
("content", Any(expl=tag_ctxc(0))),
|
|
)
|