Viewing file: x509.py (5.73 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# Read ASN.1/PEM X.509 certificates on stdin, parse each into plain text, # then build substrate from it import sys, string, base64 from pyasn1.type import tag,namedtype,namedval,univ,constraint,char,useful from pyasn1.codec.der import decoder, encoder from pyasn1 import error
# Would be autogenerated from ASN.1 source by a ASN.1 parser # X.509 spec (rfc2459)
MAX = 64 # XXX ?
class DirectoryString(univ.Choice): componentType = namedtype.NamedTypes( namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), namedtype.NamedType('ia5String', char.IA5String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))) # hm, this should not be here!? XXX )
class AttributeValue(DirectoryString): pass
class AttributeType(univ.ObjectIdentifier): pass
class AttributeTypeAndValue(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('type', AttributeType()), namedtype.NamedType('value', AttributeValue()) )
class RelativeDistinguishedName(univ.SetOf): componentType = AttributeTypeAndValue()
class RDNSequence(univ.SequenceOf): componentType = RelativeDistinguishedName()
class Name(univ.Choice): componentType = namedtype.NamedTypes( namedtype.NamedType('', RDNSequence()) ) class AlgorithmIdentifier(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('algorithm', univ.ObjectIdentifier()), namedtype.OptionalNamedType('parameters', univ.Null()) # XXX syntax screwed? # namedtype.OptionalNamedType('parameters', univ.ObjectIdentifier()) )
class Extension(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('extnID', univ.ObjectIdentifier()), namedtype.DefaultedNamedType('critical', univ.Boolean('False')), namedtype.NamedType('extnValue', univ.OctetString()) )
class Extensions(univ.SequenceOf): componentType = Extension() sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX)
class SubjectPublicKeyInfo(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('algorithm', AlgorithmIdentifier()), namedtype.NamedType('subjectPublicKey', univ.BitString()) )
class UniqueIdentifier(univ.BitString): pass
class Time(univ.Choice): componentType = namedtype.NamedTypes( namedtype.NamedType('utcTime', useful.UTCTime()), namedtype.NamedType('generalTime', useful.GeneralizedTime()) ) class Validity(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('notBefore', Time()), namedtype.NamedType('notAfter', Time()) )
class CertificateSerialNumber(univ.Integer): pass
class Version(univ.Integer): namedValues = namedval.NamedValues( ('v1', 0), ('v2', 1), ('v3', 2) )
class TBSCertificate(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.DefaultedNamedType('version', Version('v1', tagSet=Version.tagSet.tagExplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)))), namedtype.NamedType('serialNumber', CertificateSerialNumber()), namedtype.NamedType('signature', AlgorithmIdentifier()), namedtype.NamedType('issuer', Name()), namedtype.NamedType('validity', Validity()), namedtype.NamedType('subject', Name()), namedtype.NamedType('subjectPublicKeyInfo', SubjectPublicKeyInfo()), namedtype.OptionalNamedType('issuerUniqueID', UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), namedtype.OptionalNamedType('subjectUniqueID', UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), namedtype.OptionalNamedType('extensions', Extensions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) )
class Certificate(univ.Sequence): componentType = namedtype.NamedTypes( namedtype.NamedType('tbsCertificate', TBSCertificate()), namedtype.NamedType('signatureAlgorithm', AlgorithmIdentifier()), namedtype.NamedType('signatureValue', univ.BitString()) )
# end of ASN.1 data structures
certType = Certificate()
# Read PEM certs from stdin and print them out in plain text
stSpam, stHam, stDump = 0, 1, 2 state = stSpam certCnt = 0
for certLine in sys.stdin.readlines(): certLine = string.strip(certLine) if state == stSpam: if state == stSpam: if certLine == '-----BEGIN CERTIFICATE-----': certLines = [] state = stHam continue if state == stHam: if certLine == '-----END CERTIFICATE-----': state = stDump else: certLines.append(certLine) if state == stDump: substrate = '' for certLine in certLines: substrate = substrate + base64.b64decode(certLine)
cert = decoder.decode(substrate, asn1Spec=certType)[0] print cert.prettyPrint() assert encoder.encode(cert) == substrate, 'cert recode fails' certCnt = certCnt + 1 state = stSpam
print '*** %s PEM cert(s) de/serialized' % certCnt
|