source: fedd/federation/asn1_raw.py @ 3ce6b20

compt_changesinfo-ops
Last change on this file since 3ce6b20 was 5d3f239, checked in by Ted Faber <faber@…>, 16 years ago

change package name to avoid conflicts with fedd on install

  • Property mode set to 100644
File size: 5.8 KB
Line 
1# Modified from an example in the Python ASN.1 package to read certificate
2# files and extract key bits.  More recent versions of m2crypto support this
3# more directly.
4
5import sys, string, base64
6from pyasn1.type import tag,namedtype,namedval,univ,constraint,char,useful
7from pyasn1.codec.der import decoder, encoder
8from pyasn1 import error
9
10from M2Crypto import EVP
11
12# Would be autogenerated from ASN.1 source by a ASN.1 parser
13# X.509 spec (rfc2459)
14
15MAX = 64  # XXX ?
16
17class DirectoryString(univ.Choice):
18    componentType = namedtype.NamedTypes(
19        namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
20        namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
21        namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
22        namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
23        namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
24        namedtype.NamedType('ia5String', char.IA5String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))) # hm, this should not be here!? XXX
25        )
26
27class AttributeValue(DirectoryString): pass
28
29class AttributeType(univ.ObjectIdentifier): pass
30
31class AttributeTypeAndValue(univ.Sequence):
32    componentType = namedtype.NamedTypes(
33        namedtype.NamedType('type', AttributeType()),
34        namedtype.NamedType('value', AttributeValue())
35        )
36
37class RelativeDistinguishedName(univ.SetOf):
38    componentType = AttributeTypeAndValue()
39
40class RDNSequence(univ.SequenceOf):
41    componentType = RelativeDistinguishedName()
42
43class Name(univ.Choice):
44    componentType = namedtype.NamedTypes(
45        namedtype.NamedType('', RDNSequence())
46        )
47                         
48class AlgorithmIdentifier(univ.Sequence):
49    componentType = namedtype.NamedTypes(
50        namedtype.NamedType('algorithm', univ.ObjectIdentifier()),
51        namedtype.OptionalNamedType('parameters', univ.Null())
52        # XXX syntax screwed?
53#        namedtype.OptionalNamedType('parameters', univ.ObjectIdentifier())
54        )
55
56class Extension(univ.Sequence):
57    componentType = namedtype.NamedTypes(
58        namedtype.NamedType('extnID', univ.ObjectIdentifier()),
59        namedtype.DefaultedNamedType('critical', univ.Boolean('False')),
60        namedtype.NamedType('extnValue', univ.OctetString())
61        )
62
63class Extensions(univ.SequenceOf):
64    componentType = Extension()
65    sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX)
66
67class SubjectPublicKeyInfo(univ.Sequence):
68     componentType = namedtype.NamedTypes(
69         namedtype.NamedType('algorithm', AlgorithmIdentifier()),
70         namedtype.NamedType('subjectPublicKey', univ.BitString())
71         )
72
73class UniqueIdentifier(univ.BitString): pass
74
75class Time(univ.Choice):
76    componentType = namedtype.NamedTypes(
77        namedtype.NamedType('utcTime', useful.UTCTime()),
78        namedtype.NamedType('generalTime', useful.GeneralizedTime())
79        )
80   
81class Validity(univ.Sequence):
82    componentType = namedtype.NamedTypes(
83        namedtype.NamedType('notBefore', Time()),
84        namedtype.NamedType('notAfter', Time())
85        )
86
87class CertificateSerialNumber(univ.Integer): pass
88
89class Version(univ.Integer):
90    namedValues = namedval.NamedValues(
91        ('v1', 0), ('v2', 1), ('v3', 2)
92        )
93
94class TBSCertificate(univ.Sequence):
95    componentType = namedtype.NamedTypes(
96        namedtype.DefaultedNamedType('version', Version('v1', tagSet=Version.tagSet.tagExplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)))),
97        namedtype.NamedType('serialNumber', CertificateSerialNumber()),
98        namedtype.NamedType('signature', AlgorithmIdentifier()),
99        namedtype.NamedType('issuer', Name()),
100        namedtype.NamedType('validity', Validity()),
101        namedtype.NamedType('subject', Name()),
102        namedtype.NamedType('subjectPublicKeyInfo', SubjectPublicKeyInfo()),
103        namedtype.OptionalNamedType('issuerUniqueID', UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
104        namedtype.OptionalNamedType('subjectUniqueID', UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))),
105        namedtype.OptionalNamedType('extensions', Extensions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)))
106        )
107
108class Certificate(univ.Sequence):
109    componentType = namedtype.NamedTypes(
110        namedtype.NamedType('tbsCertificate', TBSCertificate()),
111        namedtype.NamedType('signatureAlgorithm', AlgorithmIdentifier()),
112        namedtype.NamedType('signatureValue', univ.BitString())
113        )
114
115# end of ASN.1 data structures
116
117
118def get_bits(substrate):
119    certType = Certificate()
120    cert = decoder.decode(substrate, asn1Spec=certType)[0]
121    n = cert
122    for name in ('tbsCertificate', 'subjectPublicKeyInfo', 
123            'subjectPublicKey'):
124        n = n.getComponentByName(name)
125        if n == None: raise RuntimeException("Bad cert")
126
127    b = []
128    for i in range(0, len(n), 8):
129        v = 0
130        for j in range(0, 8):
131            v = (v << 1) + n[i+j]
132        b.append(v)
133
134    return str().join([chr(x) for x in b])
135
136
137def get_key_bits_from_file(fname):
138    stSpam, stHam, stDump = 0, 1, 2
139    state = stSpam
140
141    f = open(fname)
142
143    for certLine in f:
144        certLine = string.strip(certLine)
145        if state == stSpam:
146            if certLine == '-----BEGIN CERTIFICATE-----':
147                substrate = ""
148                state = stHam
149                continue
150        if state == stHam:
151            if certLine == '-----END CERTIFICATE-----':
152                state = stDump
153            else:
154                substrate = substrate + base64.b64decode(certLine)
155        if state == stDump:
156            f.close()
157            return get_bits(substrate)
158
159def get_key_bits_from_cert(cert):
160    return get_bits(cert.as_der())
Note: See TracBrowser for help on using the repository browser.