def parse_ocsp_resp(ocsp_resp): ocspResponse, _ = decoder.decode(ocsp_resp, asn1Spec=rfc2560.OCSPResponse()) responseStatus = ocspResponse.getComponentByName('responseStatus') assert responseStatus == rfc2560.OCSPResponseStatus( 'successful'), responseStatus.prettyPrint() responseBytes = ocspResponse.getComponentByName('responseBytes') responseType = responseBytes.getComponentByName('responseType') assert responseType == rfc2560.id_pkix_ocsp_basic, responseType.prettyPrint( ) response = responseBytes.getComponentByName('response') basicOCSPResponse, _ = decoder.decode(response, asn1Spec=rfc2560.BasicOCSPResponse()) tbsResponseData = basicOCSPResponse.getComponentByName('tbsResponseData') response0 = tbsResponseData.getComponentByName( 'responses').getComponentByPosition(0) producedAt = datetime.datetime.strptime( str(tbsResponseData.getComponentByName('producedAt')), '%Y%m%d%H%M%SZ') certID = response0.getComponentByName('certID') certStatus = response0.getComponentByName('certStatus').getName() thisUpdate = datetime.datetime.strptime( str(response0.getComponentByName('thisUpdate')), '%Y%m%d%H%M%SZ') # let's assume that certID in response matches the certID sent in the request # let's assume that response signed by trusted responder print("[+] OCSP producedAt:", producedAt) print("[+] OCSP thisUpdate:", thisUpdate) print("[+] OCSP status:", certStatus)
def parse_ocsp_response(ocsp_resp): # extracts from an OCSP response certID_serial, certStatus and thisUpdate ocspResponse, _ = decoder.decode(ocsp_resp, asn1Spec=rfc2560.OCSPResponse()) responseStatus = ocspResponse.getComponentByName('responseStatus') assert responseStatus == rfc2560.OCSPResponseStatus( 'successful'), responseStatus.prettyPrint() responseBytes = ocspResponse.getComponentByName('responseBytes') responseType = responseBytes.getComponentByName('responseType') assert responseType == rfc2560.id_pkix_ocsp_basic, responseType.prettyPrint( ) response = responseBytes.getComponentByName('response') basicOCSPResponse, _ = decoder.decode(response, asn1Spec=rfc2560.BasicOCSPResponse()) tbsResponseData = basicOCSPResponse.getComponentByName('tbsResponseData') response0 = tbsResponseData.getComponentByName( 'responses').getComponentByPosition(0) # let's assume that the OCSP response has been signed by a trusted OCSP responder certID = response0.getComponentByName('certID') # let's assume that the issuer name and key hashes in certID are correct certID_serial = certID[3] certStatus = response0.getComponentByName('certStatus').getName() thisUpdate = datetime.datetime.strptime( str(response0.getComponentByName('thisUpdate')), '%Y%m%d%H%M%SZ') return certID_serial, certStatus, thisUpdate
def parseOcspResponse(ocspResponse): responseStatus = ocspResponse.getComponentByName('responseStatus') assert responseStatus == rfc2560.OCSPResponseStatus( 'successful'), responseStatus.prettyPrint() responseBytes = ocspResponse.getComponentByName('responseBytes') responseType = responseBytes.getComponentByName('responseType') assert responseType == id_pkix_ocsp_basic, responseType.prettyPrint() response = responseBytes.getComponentByName('response') basicOCSPResponse, _ = decoder.decode(response, asn1Spec=rfc2560.BasicOCSPResponse()) tbsResponseData = basicOCSPResponse.getComponentByName('tbsResponseData') response0 = tbsResponseData.getComponentByName( 'responses').getComponentByPosition(0) return (tbsResponseData.getComponentByName('producedAt'), response0.getComponentByName('certID'), response0.getComponentByName('certStatus').getName(), response0.getComponentByName('thisUpdate'))
def Create(signer=None, response_status=0, response_type='1.3.6.1.5.5.7.48.1.1', signature=None, version=1, responder=None, responses=None, extensions=None, certs=None, sigAlg='sha1'): ocsp = rfc2560.OCSPResponse() ocsp.setComponentByName('responseStatus', response_status) if response_status != 0: return ocsp tbs = rfc2560.ResponseData() if version != 1: tbs.setComponentByName('version', version) if not signer: signer = CA if not responder: responder = GetName(signer) tbs.setComponentByName('responderID', responder) tbs.setComponentByName( 'producedAt', useful.GeneralizedTime(PRODUCED_DATE.strftime('%Y%m%d%H%M%SZ'))) rlist = tbs.setComponentByName('responses').getComponentByName('responses') if responses == None: responses = [CreateSingleResponse(CERT, 0)] if responses: for i in range(len(responses)): rlist.setComponentByPosition(i, responses[i]) if extensions: elist = tbs.setComponentByName( 'responseExtensions').getComponentByName('responseExtensions') for i in range(len(extensions)): elist.setComponentByPosition(i, extensions[i]) sa = rfc2459.AlgorithmIdentifier() sa.setComponentByName('algorithm', SigAlgOid(sigAlg)) # TODO(mattm): If pyasn1 gives an error # "Component value is tag-incompatible: Null() vs Any()", try hacking # pyasn1_modules/rfc2459.py's AlgorithmIdentifier to specify univ.Null as the # type for 'parameters'. (Which is an ugly hack, but lets the script work.) sa.setComponentByName('parameters', univ.Null()) basic = rfc2560.BasicOCSPResponse() basic.setComponentByName('tbsResponseData', tbs) basic.setComponentByName('signatureAlgorithm', sa) if not signature: signature = crypto.sign(signer[2], encoder.encode(tbs), sigAlg) basic.setComponentByName( 'signature', univ.BitString("'%s'H" % (signature.encode('hex')))) if certs: cs = basic.setComponentByName('certs').getComponentByName('certs') for i in range(len(certs)): cs.setComponentByPosition(i, certs[i][0]) rbytes = ocsp.componentType.getTypeByPosition(1) rbytes.setComponentByName('responseType', univ.ObjectIdentifier(response_type)) rbytes.setComponentByName('response', encoder.encode(basic)) ocsp.setComponentByName('responseBytes', rbytes) return ocsp