185 lines
7.9 KiB
Python
185 lines
7.9 KiB
Python
from pyasn1.type import univ, namedtype, tag, namedval, constraint, char, useful
|
|
from pyasn1_modules.rfc2459 import AlgorithmIdentifier, Extensions, MAX
|
|
from pyasn1_modules.rfc2315 import ContentInfo, signedData, SignedData
|
|
from pyasn1.codec.ber import decoder
|
|
|
|
__all__ = ( 'TimeStampReq', 'MessageImprint', 'PKIFreeText', 'PKIStatus', 'PKIFailureInfo', 'PKIStatusInfo', 'TimeStampResp', 'Accuracy', 'AnotherName', 'GeneralName', 'TimeStampToken', 'TSTInfo')
|
|
|
|
# Request
|
|
|
|
class TSAPolicyId(univ.ObjectIdentifier):
|
|
pass
|
|
|
|
class MessageImprint(univ.Sequence):
|
|
componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('hashAlgorithm', AlgorithmIdentifier()),
|
|
namedtype.NamedType('hashedMessage', univ.OctetString()),)
|
|
|
|
@property
|
|
def hash_algorithm(self):
|
|
return self[0]
|
|
|
|
@property
|
|
def hashed_message(self):
|
|
return self[1]
|
|
|
|
class TimeStampReq(univ.Sequence):
|
|
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(False)),
|
|
namedtype.OptionalNamedType('extensions',
|
|
Extensions().subtype(implicitTag=tag.Tag(tag.tagClassContext,
|
|
tag.tagFormatSimple, 0)))
|
|
)
|
|
|
|
# Reponse
|
|
|
|
class PKIFreeText(univ.SequenceOf):
|
|
componentType = char.UTF8String()
|
|
sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX)
|
|
|
|
class PKIStatus(univ.Integer):
|
|
namedValues = namedval.NamedValues(
|
|
('granted', 0),
|
|
# -- when the PKIStatus contains the value zero a TimeStampToken, as
|
|
# requested, is present.
|
|
('grantedWithMods', 1),
|
|
# -- when the PKIStatus contains the value one a TimeStampToken,
|
|
# with modifications, is present.
|
|
('rejection', 2), ('waiting', 3), ('revocationWarning', 4),
|
|
# -- this message contains a warning that a revocation is
|
|
# -- imminent
|
|
('revocationNotification', 5),)
|
|
|
|
class PKIFailureInfo(univ.BitString):
|
|
namedValues = namedval.NamedValues(
|
|
('badAlg', 0),
|
|
# -- unrecognized or unsupported Algorithm Identifier
|
|
('badRequest' ,2),
|
|
# -- transaction not permitted or supported
|
|
('badDataFormat' ,5),
|
|
# -- the data submitted has the wrong format
|
|
('timeNotAvailable' ,14),
|
|
# -- the TSA's time source is not available
|
|
('unacceptedPolicy' ,15),
|
|
# -- the requested TSA policy is not supported by the TSA
|
|
('unacceptedExtension' ,16),
|
|
# -- the requested extension is not supported by the TSA
|
|
('addInfoNotAvailable' ,17),
|
|
# -- the additional information requested could not be understood
|
|
# -- or is not available
|
|
('systemFailure' ,25))
|
|
# -- the request cannot be handled due to system failure }
|
|
|
|
class PKIStatusInfo(univ.Sequence):
|
|
componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('status', PKIStatus()),
|
|
namedtype.OptionalNamedType('statusString', PKIFreeText()),
|
|
namedtype.OptionalNamedType('failInfo', PKIFailureInfo()))
|
|
|
|
class TimeStampToken(ContentInfo):
|
|
componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('contentType', signedData),
|
|
namedtype.OptionalNamedType('content',
|
|
SignedData().subtype(explicitTag=tag.Tag(tag.tagClassContext,
|
|
tag.tagFormatConstructed, 0))))
|
|
|
|
@property
|
|
def content(self):
|
|
return self[1]
|
|
|
|
@property
|
|
def tst_info(self):
|
|
x, substrate = decoder.decode(str(self.content['contentInfo']['content']))
|
|
if substrate:
|
|
raise ValueError('Incomplete decoding')
|
|
x, substrate = decoder.decode(str(x), asn1Spec=TSTInfo())
|
|
if substrate:
|
|
raise ValueError('Incomplete decoding')
|
|
return x
|
|
|
|
class TimeStampResp(univ.Sequence):
|
|
componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('status', PKIStatusInfo()),
|
|
namedtype.OptionalNamedType('timeStampToken', TimeStampToken()))
|
|
|
|
@property
|
|
def status(self):
|
|
return self[0]
|
|
|
|
@property
|
|
def time_stamp_token(self):
|
|
return self[1]
|
|
|
|
class Accuracy(univ.Sequence):
|
|
componentType = namedtype.NamedTypes(
|
|
namedtype.OptionalNamedType('seconds', univ.Integer()),
|
|
namedtype.OptionalNamedType('millis', univ.Integer().subtype(
|
|
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
|
|
namedtype.OptionalNamedType('micros', univ.Integer().subtype(
|
|
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))))
|
|
|
|
# import from
|
|
class AnotherName(univ.Sequence):
|
|
componentType = namedtype.NamedTypes(
|
|
namedtype.OptionalNamedType('type-id', univ.ObjectIdentifier()),
|
|
namedtype.OptionalNamedType('value', univ.Any().subtype(
|
|
explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))))
|
|
|
|
class GeneralName(univ.Choice):
|
|
componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('rfc822Name', char.IA5String().subtype(
|
|
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
|
|
# namedtype.NamedType('dNSName', univ.Any().subtype(
|
|
# implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))),
|
|
# namedtype.NamedType('x400Address', univ.Any().subtype(
|
|
# implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))),
|
|
namedtype.NamedType('directoryName', univ.Any().subtype(
|
|
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))),
|
|
# namedtype.NamedType('ediPartyName', univ.Any().subtype(
|
|
# implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))),
|
|
# namedtype.NamedType('uniformResourceIdentifier', char.IA5String().subtype(
|
|
# implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))),
|
|
# namedtype.NamedType('iPAddress', univ.OctetString().subtype(
|
|
# implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7))),
|
|
namedtype.NamedType('registeredID', univ.ObjectIdentifier().subtype(
|
|
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8))))
|
|
|
|
class TSTInfo(univ.Sequence):
|
|
componentType = namedtype.NamedTypes(
|
|
namedtype.NamedType('version',
|
|
univ.Integer(namedValues=namedval.NamedValues(('v1', 1)))),
|
|
namedtype.OptionalNamedType('policy', TSAPolicyId()),
|
|
namedtype.NamedType('messageImprint', MessageImprint()),
|
|
# -- MUST have the same value as the similar field in
|
|
# -- TimeStampReq
|
|
namedtype.NamedType('serialNumber', univ.Integer()),
|
|
# -- Time-Stamping users MUST be ready to accommodate integers
|
|
# -- up to 160 bits.
|
|
namedtype.NamedType('genTime', useful.GeneralizedTime()),
|
|
namedtype.OptionalNamedType('accuracy', Accuracy()),
|
|
namedtype.DefaultedNamedType('ordering', univ.Boolean(False)),
|
|
namedtype.OptionalNamedType('nonce', univ.Integer()),
|
|
# -- MUST be present if the similar field was present
|
|
# -- in TimeStampReq. In that case it MUST have the same value.
|
|
namedtype.OptionalNamedType('tsa', GeneralName().subtype(
|
|
explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
|
|
namedtype.OptionalNamedType('extensions', Extensions().subtype(
|
|
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))))
|
|
|
|
@property
|
|
def version(self):
|
|
return self[0]
|
|
|
|
@property
|
|
def policy(self):
|
|
return self[1]
|
|
|
|
@property
|
|
def message_imprint(self):
|
|
return self[2]
|