Last active
October 6, 2016 11:39
-
-
Save apettinen/def48e39ff6e01f622be3ffe3db53cb6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: utf-8 -*- | |
# pylint: disable=C0301, C0103, W0702, W1201 | |
# Antti Pettinen (Tampere University of Technology) | |
# Ilkka Vanhatalo (Helsinki University) | |
# Copyright: Tampere University of Technology and University of Helsinki | |
# License: Apache 2.0 | |
''' | |
Parse CSRs for Custom Attributes and Requested Extensions with pyASN1 | |
''' | |
import sys | |
try: | |
from pyasn1.codec.der import decoder as der_decoder | |
from pyasn1_modules import rfc2314, rfc2459, pem | |
from pyasn1.type import univ, namedtype, tag | |
except ImportError: | |
sys.exit(1) | |
def _parseAndMapToOIDs(csr, OIDs): | |
''' | |
Map ASN.1 type CSR attributes and extensions to provided OID values. In ASN.1 CSR structure the requested extensions are mapped under attributes with predifined and fixed OID of 1.2.840.113549.1.9.14. Thus they can be reached with similar methods than custom attributes in CSR. | |
''' | |
# This is the OID for Extension Requests in CSRs: | |
extReqOID = '1.2.840.113549.1.9.14' | |
extReqOIDObj = univ.ObjectIdentifier(extReqOID) | |
# make sure that OID for requested extensions is in the list of OIDs | |
if extReqOID not in OIDs: | |
OIDs.append(extReqOID) | |
OIDToValue = dict() | |
try: | |
for attribute in csr['certificationRequestInfo']['attributes']: | |
# change the attribute to octet representation: | |
attributeOctet = attribute['vals'].getComponentByPosition(0).asOctets() | |
attributeOIDObj = attribute['type'] | |
attributeOID = attributeOIDObj.prettyPrint() | |
# if a custom attribute is found amongst the provided OIDs, map | |
# the custom attribute to the corresponding OID... | |
if attributeOID in OIDs and attributeOIDObj != extReqOIDObj: | |
attributeValue, _attrRest= der_decoder.decode(attributeOctet) | |
OIDToValue[attributeOID] = attributeValue.prettyPrint() | |
print('Mapped custom attribute {AO} to value {AV}...').format(AO=attributeOID, AV=attributeValue.prettyPrint()) | |
# unless attribute is extension request... Then we need to | |
# transform the rfc2314 type CSR attribute information to rfc2459 | |
# type requested extension information | |
elif attributeOIDObj == extReqOIDObj: | |
extReqs, _extRest = der_decoder.decode(attributeOctet, asn1Spec=rfc2459.Extensions()) | |
# Dict in dict for requested extensions: | |
OIDToValue[attributeOID] = {} | |
for extReq in extReqs: | |
# get OID and value for the requested extension | |
extOID = extReq['extnID'].prettyPrint() | |
extValue = der_decoder.decode(der_decoder.decode(univ.OctetString(extReq['extnValue'].asOctets()))[0])[0].prettyPrint() | |
# map the value | |
OIDToValue[attributeOID][extOID] = extValue | |
print('Mapped requested extension {EO} to value {EV}...').format(EO=extOID, EV=extValue) | |
print('CSR parsing succesfull!') | |
except: | |
print('Error parsing attributes and extensions from CSR.') | |
sys.exit(1) | |
return OIDToValue | |
def main(): | |
'''It's me, main.''' | |
#Example: myOIDs = ['1.3.6.1.4.1.34380.1.2.2.2', '1.3.6.1.4.1.34380.1.2.2.3'] | |
# myCSR= what ever way you get your CSR substrate (e.g pem.readPemBlocksFromFile(sys.stdin, ('-----BEGIN CERTIFICATE REQUEST-----', '-----END CERTIFICATE REQUEST-----')) | |
OIDsToValues=_parseAndMapToOIDs(myCSR, myOIDs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment