File: get_issuers.py

package info (click to toggle)
golang-github-google-certificate-transparency 0.0~git20160709.0.0f6e3d1~ds1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 5,676 kB
  • sloc: cpp: 35,278; python: 11,838; java: 1,911; sh: 1,885; makefile: 950; xml: 520; ansic: 225
file content (111 lines) | stat: -rwxr-xr-x 3,019 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env python

# Get the issuers for the supplied certificates from the AIA
# extension. Note that this is not very clever and may supply
# intermediates that are not needed and fail to supply intermediates
# that are needed.

# Based on pyasn1 example code.

from base64 import b64encode
from pyasn1.codec.der import decoder
from pyasn1.codec.der import encoder
from pyasn1.type import namedtype
from pyasn1.type import univ
from pyasn1_modules import pem
from pyasn1_modules import rfc2459
import sys
from urllib2 import urlopen

if len(sys.argv) != 1:
  print """Usage:
  $ %s < somecertificates.pem""" % sys.argv[0]
  sys.exit(-1)

cStart = '-----BEGIN CERTIFICATE-----'
cEnd = '-----END CERTIFICATE-----'

certType = rfc2459.Certificate()

# RFC 2459 is not sufficient for X509v3 certificates, extra stuff here.
# RFC 5280 4.2.2.1

id_pe_authorityInfoAccess = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.1')

class AccessDescription(univ.Sequence):
  """
     AccessDescription  ::=  SEQUENCE {
                accessMethod          OBJECT IDENTIFIER,
                accessLocation        GeneralName  }
  """
  componentType = namedtype.NamedTypes(
    namedtype.NamedType('accessMethod', univ.ObjectIdentifier()),
    namedtype.NamedType('accessLocation', rfc2459.GeneralName()))

class AuthorityInfoAccessSyntax(univ.SequenceOf):
  """
  AuthorityInfoAccessSyntax  ::=
             SEQUENCE SIZE (1..MAX) OF AccessDescription
  """
  # FIXME: SIZE not encoded.
  componentType = AccessDescription()

id_ad_caIssuers = univ.ObjectIdentifier('1.3.6.1.5.5.7.48.2')

# End of RFC 5280 4.2.2.1

certCnt = 0

while 1:
  idx, substrate = pem.readPemBlocksFromFile(
    sys.stdin, (cStart, cEnd)
    )
  if not substrate:
    break

  cert, rest = decoder.decode(substrate, asn1Spec=certType)

  if rest: substrate = substrate[:-len(rest)]

  print cert.prettyPrint()

  tbs = cert.getComponentByName('tbsCertificate')
  extensions = tbs.getComponentByName('extensions') or []

  for extension in extensions:
    oid = extension.getComponentByName('extnID')
    if oid != id_pe_authorityInfoAccess:
      continue
    
    print extension.prettyPrint()

    value, rest = decoder.decode(extension.getComponentByName('extnValue'),
                                 asn1Spec=univ.OctetString())
    assert rest == ""
    aia, rest = decoder.decode(value, asn1Spec=AuthorityInfoAccessSyntax())
    assert rest == ""

    print aia.prettyPrint()

    for ad in aia:
      oid = ad.getComponentByName('accessMethod')
      if oid != id_ad_caIssuers:
        continue
      
      print ad.prettyPrint()

      loc = ad.getComponentByName('accessLocation').\
        getComponentByName('uniformResourceIdentifier')
      print type(loc), loc

      certHandle = urlopen(str(loc))
      cert = certHandle.read()
      print cStart
      b64 = b64encode(cert)
      for n in range(0, len(b64), 64):
        print b64[n:n+64]
      print cEnd
    
  certCnt = certCnt + 1

print('*** %s PEM cert(s) de/serialized' % certCnt)