def GenerateCertKeyAndOCSP(subject = "127.0.0.1", ocsp_url = "http://127.0.0.1", ocsp_states = None, ocsp_dates = None, ocsp_produced = OCSP_PRODUCED_VALID, ip_sans = ["\x7F\x00\x00\x01"], dns_sans = None, serial = 0): '''GenerateCertKeyAndOCSP returns a (cert_and_key_pem, ocsp_der) where: * cert_and_key_pem contains a certificate and private key in PEM format with the given subject common name and OCSP URL. * ocsp_der contains a DER encoded OCSP response or None if ocsp_url is None''' if ocsp_states is None: ocsp_states = [OCSP_STATE_GOOD] if ocsp_dates is None: ocsp_dates = [OCSP_DATE_VALID] if serial == 0: serial = RandomNumber(16) cert_der = MakeCertificate(ROOT_CN, bytes(subject), serial, LEAF_KEY, ROOT_KEY, bytes(ocsp_url), ip_sans=ip_sans, dns_sans=dns_sans) cert_pem = DERToPEM(cert_der) ocsp_der = None if ocsp_url is not None: if ocsp_states[0] == OCSP_STATE_UNAUTHORIZED: ocsp_der = unauthorizedDER elif ocsp_states[0] == OCSP_STATE_INVALID_RESPONSE: ocsp_der = '3' elif ocsp_states[0] == OCSP_STATE_TRY_LATER: resp = asn1.SEQUENCE([ asn1.ENUMERATED(3), ]) ocsp_der = asn1.ToDER(resp) elif ocsp_states[0] == OCSP_STATE_INVALID_RESPONSE_DATA: invalid_data = asn1.ToDER(asn1.OCTETSTRING('not ocsp data')) basic_resp = asn1.SEQUENCE([ asn1.Raw(invalid_data), asn1.SEQUENCE([ SHA256_WITH_RSA_ENCRYPTION, None, ]), asn1.BitString(ROOT_KEY.Sign(invalid_data)), ]) resp = asn1.SEQUENCE([ asn1.ENUMERATED(0), asn1.Explicit(0, asn1.SEQUENCE([ OCSP_TYPE_BASIC, asn1.OCTETSTRING(asn1.ToDER(basic_resp)), ])), ]) ocsp_der = asn1.ToDER(resp) else: ocsp_der = MakeOCSPResponse( ROOT_CN, ROOT_KEY, serial, ocsp_states, ocsp_dates, ocsp_produced) return (cert_pem + LEAF_KEY_PEM, ocsp_der)
def _encode(self): """ _encode() -> octet stream Bind together encoded object IDs and their associated values (lists of strings) into bindings. """ # Initialize stuff index = 0 encoded_oid_pairs = '' # XXX handle unequal pairs # Encode encoded objid's and encoded values together while index < len(self['encoded_oids']): # Encode and concatinate one oid_pair if self['encoded_vals'] and \ self['encoded_vals'][index]: # Merge oid with value oid_pairs = self['encoded_oids'][index] + \ self['encoded_vals'][index] else: # Merge oid with value oid_pairs = self['encoded_oids'][index] + \ asn1.NULL().encode() # Encode merged pairs encoded_oid_pairs = encoded_oid_pairs + \ asn1.SEQUENCE(oid_pairs).encode() # Progress index index = index + 1 # Return encoded bindings return asn1.SEQUENCE(encoded_oid_pairs).encode()
def _decode(self, input): """ _decode(input) Decode input octet stream (string) into lists or encoded Object IDs and their associated values (lists of strings). """ (bindings, rest) = asn1.SEQUENCE().decode(input) # Initialize objids and vals lists self['encoded_oids'] = [] self['encoded_vals'] = [] # Walk over bindings while bindings: # Unpack one binding (binding, bindings) = asn1.SEQUENCE().decode(bindings) # Get OID oid = asn1.OBJECTID() binding = oid.decode(binding)[1] self['encoded_oids'].append(oid.encode()) # Get value (val, binding) = asn1.decode(binding) self['encoded_vals'].append(val.encode()) # Nothing should left out if binding: raise TypeError('Trailing garbage in binding: %s' % repr(binding)) return rest
def Name(cn = None, c = None, o = None): names = asn1.SEQUENCE([]) if cn is not None: names.children.append( asn1.SET([ asn1.SEQUENCE([ COMMON_NAME, cn, ]) ]) ) if c is not None: names.children.append( asn1.SET([ asn1.SEQUENCE([ COUNTRY, c, ]) ]) ) if o is not None: names.children.append( asn1.SET([ asn1.SEQUENCE([ ORGANIZATION, o, ]) ]) ) return names
def Name(cn): return asn1.SEQUENCE([ asn1.SET([ asn1.SEQUENCE([ COMMON_NAME, cn, ]) ]) ])
def packASN1(self): # yuck what a horrid library! dssParms = ''.join([asn1.INTEGER(x).encode() for x in [self.dsa.p, self.dsa.q, self.dsa.g]]) keyInfo = ''.join([asn1.SEQUENCE(''.join([idDSA.encode(), asn1.SEQUENCE(dssParms).encode()])).encode(), asn1.INTEGER(self.dsa.y).encode()]) return asn1.SEQUENCE(keyInfo).encode()
def Name(cn, utf8_cn=False): # This module historically used PrintableString for most strings, so maintain # that default. if utf8_cn: cn_encoded = asn1.UTF8String(cn.encode('utf-8')) else: cn_encoded = asn1.PrintableString(cn.encode('ascii')) return asn1.SEQUENCE([asn1.SET([asn1.SEQUENCE([ COMMON_NAME, cn_encoded, ])])])
def MakeOCSPResponse(issuer_cn, issuer_key, serial, revoked): # https://tools.ietf.org/html/rfc2560 issuer_name_hash = asn1.OCTETSTRING( hashlib.sha1(asn1.ToDER(Name(cn=issuer_cn))).digest()) issuer_key_hash = asn1.OCTETSTRING( hashlib.sha1(asn1.ToDER(issuer_key)).digest()) cert_status = None if revoked: cert_status = asn1.Explicit(1, asn1.GeneralizedTime("20100101060000Z")) else: cert_status = asn1.Raw(asn1.TagAndLength(0x80 | 0, 0)) basic_resp_data_der = asn1.ToDER( asn1.SEQUENCE([ asn1.Explicit(2, issuer_key_hash), asn1.GeneralizedTime("20100101060000Z"), # producedAt asn1.SEQUENCE([ asn1.SEQUENCE([ # SingleResponse asn1.SEQUENCE([ # CertID asn1.SEQUENCE([ # hashAlgorithm HASH_SHA1, None, ]), issuer_name_hash, issuer_key_hash, serial, ]), cert_status, asn1.GeneralizedTime("20100101060000Z"), # thisUpdate asn1.Explicit( 0, asn1.GeneralizedTime("20300101060000Z")), # nextUpdate ]), ]), ])) basic_resp = asn1.SEQUENCE([ asn1.Raw(basic_resp_data_der), asn1.SEQUENCE([ SHA1_WITH_RSA_ENCRYPTION, None, ]), asn1.BitString(issuer_key.Sign(basic_resp_data_der)), ]) resp = asn1.SEQUENCE([ asn1.ENUMERATED(0), asn1.Explicit( 0, asn1.SEQUENCE([ OCSP_TYPE_BASIC, asn1.OCTETSTRING(asn1.ToDER(basic_resp)), ])) ]) return asn1.ToDER(resp)
def MakeOCSPSingleResponse(issuer_name_hash, issuer_key_hash, serial, ocsp_state, ocsp_date): cert_status = None if ocsp_state == OCSP_STATE_REVOKED: cert_status = asn1.Explicit(1, asn1.GeneralizedTime("20100101060000Z")) elif ocsp_state == OCSP_STATE_UNKNOWN: cert_status = asn1.Raw(asn1.TagAndLength(0x80 | 2, 0)) elif ocsp_state == OCSP_STATE_GOOD: cert_status = asn1.Raw(asn1.TagAndLength(0x80 | 0, 0)) elif ocsp_state == OCSP_STATE_MISMATCHED_SERIAL: cert_status = asn1.Raw(asn1.TagAndLength(0x80 | 0, 0)) serial -= 1 else: raise ValueError('Bad OCSP state: ' + str(ocsp_state)) now = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())) if ocsp_date == OCSP_DATE_VALID: thisUpdate = now - datetime.timedelta(days=1) nextUpdate = thisUpdate + datetime.timedelta(weeks=1) elif ocsp_date == OCSP_DATE_OLD: thisUpdate = now - datetime.timedelta(days=1, weeks=1) nextUpdate = thisUpdate + datetime.timedelta(weeks=1) elif ocsp_date == OCSP_DATE_EARLY: thisUpdate = now + datetime.timedelta(days=1) nextUpdate = thisUpdate + datetime.timedelta(weeks=1) elif ocsp_date == OCSP_DATE_LONG: thisUpdate = now - datetime.timedelta(days=365) nextUpdate = thisUpdate + datetime.timedelta(days=366) elif ocsp_date == OCSP_DATE_LONGER: thisUpdate = now - datetime.timedelta(days=367) nextUpdate = thisUpdate + datetime.timedelta(days=368) else: raise ValueError('Bad OCSP date: ' + str(ocsp_date)) return asn1.SEQUENCE([ # SingleResponse asn1.SEQUENCE([ # CertID asn1.SEQUENCE([ # hashAlgorithm HASH_SHA1, None, ]), issuer_name_hash, issuer_key_hash, serial, ]), cert_status, asn1.GeneralizedTime( # thisUpdate thisUpdate.strftime(GENERALIZED_TIME_FORMAT)), asn1.Explicit( # nextUpdate 0, asn1.GeneralizedTime( nextUpdate.strftime(GENERALIZED_TIME_FORMAT))), ])
def _encode(self): """ _encode() -> octet stream Encode SNMP version, community name and PDU into SNMP message. """ return asn1.SEQUENCE( \ asn1.INTEGER(self['version']).encode() + \ asn1.OCTETSTRING(self['community']).encode() + \ self['pdu']).encode()
def signASN1(self, str): t = chr((len(long_to_bytes(self.dsa.p))/64)-1) r, s = self.dsa.sign(bytes_to_long(sha.new(str).digest()), HIPutils.RandomPool.get_bytes( len(long_to_bytes(self.dsa.q))-1)) ## print 'HI.sign' ## print binascii.hexlify(long_to_bytes(r)), binascii.hexlify(long_to_bytes(s)) ## print binascii.hexlify(sha.new(str).digest()) ## print repr(self.dsa.__dict__) ## print self.dsa.size() #print len(r), binascii.hexlify(r), len(s), binascii.hexlify(s) sigInfo = ''.join([asn1.INTEGER().encode(r), asn1.INTEGER().encode(s)]) sig = asn1.SEQUENCE(sigInfo).encode() ## print repr(sig) return sig
def MakeOCSPResponse(issuer_cn, issuer_key, serial, ocsp_states, ocsp_dates, ocsp_produced): # https://tools.ietf.org/html/rfc2560 issuer_name_hash = asn1.OCTETSTRING( hashlib.sha1(asn1.ToDER(Name(cn=issuer_cn))).digest()) issuer_key_hash = asn1.OCTETSTRING( hashlib.sha1(asn1.ToDER(issuer_key)).digest()) now = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())) if ocsp_produced == OCSP_PRODUCED_VALID: producedAt = now - datetime.timedelta(days=1) elif ocsp_produced == OCSP_PRODUCED_BEFORE_CERT: producedAt = datetime.datetime.strptime("19100101050000Z", GENERALIZED_TIME_FORMAT) elif ocsp_produced == OCSP_PRODUCED_AFTER_CERT: producedAt = datetime.datetime.strptime("20321201070000Z", GENERALIZED_TIME_FORMAT) else: raise ValueError('Bad OCSP produced: ' + str(ocsp_produced)) single_responses = [ MakeOCSPSingleResponse(issuer_name_hash, issuer_key_hash, serial, ocsp_state, ocsp_date) for ocsp_state, ocsp_date in itertools.izip(ocsp_states, ocsp_dates) ] basic_resp_data_der = asn1.ToDER( asn1.SEQUENCE([ asn1.Explicit(2, issuer_key_hash), asn1.GeneralizedTime(producedAt.strftime(GENERALIZED_TIME_FORMAT)), asn1.SEQUENCE(single_responses), ])) basic_resp = asn1.SEQUENCE([ asn1.Raw(basic_resp_data_der), asn1.SEQUENCE([ SHA256_WITH_RSA_ENCRYPTION, None, ]), asn1.BitString(issuer_key.Sign(basic_resp_data_der)), ]) resp = asn1.SEQUENCE([ asn1.ENUMERATED(0), asn1.Explicit( 0, asn1.SEQUENCE([ OCSP_TYPE_BASIC, asn1.OCTETSTRING(asn1.ToDER(basic_resp)), ])) ]) return asn1.ToDER(resp)
def _decode(self, input): """ _decode(input) -> (value, rest) Parse SNMP message (string), return SNMP protocol version used (integer), community name (string) and SNMP PDU (string). """ # Unpack message (message, rest) = asn1.SEQUENCE().decode(input) # Get SNMP version (self['version'], message) = asn1.INTEGER().decode(message) # Get SNMP community name (self['community'], self['pdu']) = \ asn1.OCTETSTRING().decode(message) return rest
def decode_header(self, input): """ _decode(input) -> (value, rest) Parse SNMP message (string), return SNMP protocol version used (integer) and community name (string). """ # Unpack message (message, rest) = asn1.SEQUENCE().decode(input) # Get SNMP version (self['version'], message) = asn1.INTEGER().decode(message) # Get SNMP community name (self['community'], pdu) = \ asn1.OCTETSTRING().decode(message) if pdu: return (pdu, rest) else: return (None, rest)
def MakeCertificate(issuer_cn, subject_cn, serial, pubkey, privkey, ocsp_url=None): '''MakeCertificate returns a DER encoded certificate, signed by privkey.''' extensions = asn1.SEQUENCE([]) # Default subject name fields c = "XX" o = "Testing Org" if issuer_cn == subject_cn: # Root certificate. c = None o = None extensions.children.append( asn1.SEQUENCE([ BASIC_CONSTRAINTS, True, asn1.OCTETSTRING( asn1.ToDER(asn1.SEQUENCE([ True, # IsCA 0, # Path len ]))), ])) if ocsp_url is not None: extensions.children.append( asn1.SEQUENCE([ AUTHORITY_INFORMATION_ACCESS, # There is implicitly a critical=False here. Since false is the default, # encoding the value would be invalid DER. asn1.OCTETSTRING( asn1.ToDER( asn1.SEQUENCE([ asn1.SEQUENCE([ AIA_OCSP, asn1.Raw( asn1.TagAndLength(0x86, len(ocsp_url)) + ocsp_url), ]), ]))), ])) extensions.children.append( asn1.SEQUENCE([ CERT_POLICIES, # There is implicitly a critical=False here. Since false is the default, # encoding the value would be invalid DER. asn1.OCTETSTRING( asn1.ToDER( asn1.SEQUENCE([ asn1.SEQUENCE([ # PolicyInformation CERT_POLICY_OID, ]), ]))), ])) tbsCert = asn1.ToDER( asn1.SEQUENCE([ asn1.Explicit(0, 2), # Version serial, asn1.SEQUENCE([SHA256_WITH_RSA_ENCRYPTION, None]), # SignatureAlgorithm Name(cn=issuer_cn), # Issuer asn1.SEQUENCE([ # Validity asn1.UTCTime("100101060000Z"), # NotBefore asn1.UTCTime("321201060000Z"), # NotAfter ]), Name(cn=subject_cn, c=c, o=o), # Subject asn1.SEQUENCE([ # SubjectPublicKeyInfo asn1.SEQUENCE([ # Algorithm PUBLIC_KEY_RSA, None, ]), asn1.BitString(asn1.ToDER(pubkey)), ]), asn1.Explicit(3, extensions), ])) return asn1.ToDER( asn1.SEQUENCE([ asn1.Raw(tbsCert), asn1.SEQUENCE([ SHA256_WITH_RSA_ENCRYPTION, None, ]), asn1.BitString(privkey.Sign(tbsCert)), ]))
def ToDER(self): return asn1.ToDER(asn1.SEQUENCE([self.m, self.e]))
def MakeCertificate( issuer_cn, subject_cn, serial, pubkey, privkey, ocsp_url = None, ca_issuers_url = None, is_ca=False, path_len=None, ip_sans=None, dns_sans=None): '''MakeCertificate returns a DER encoded certificate, signed by privkey.''' extensions = asn1.SEQUENCE([]) # Default subject name fields c = "XX" o = "Testing Org" if is_ca: # Root certificate. c = None o = None extensions.children.append( asn1.SEQUENCE([ BASIC_CONSTRAINTS, True, asn1.OCTETSTRING(asn1.ToDER(asn1.SEQUENCE([ True, # IsCA ] + ([path_len] if path_len is not None else []) # Path len ))), ])) if ip_sans is not None or dns_sans is not None: sans = [] if dns_sans is not None: for dns_name in dns_sans: sans.append( asn1.Raw(asn1.TagAndLength(0x82, len(dns_name)) + dns_name)) if ip_sans is not None: for ip_addr in ip_sans: sans.append( asn1.Raw(asn1.TagAndLength(0x87, len(ip_addr)) + ip_addr)) extensions.children.append( asn1.SEQUENCE([ SUBJECT_ALTERNATIVE_NAME, # There is implicitly a critical=False here. Since false is the # default, encoding the value would be invalid DER. asn1.OCTETSTRING(asn1.ToDER(asn1.SEQUENCE(sans))) ])) if ocsp_url is not None or ca_issuers_url is not None: aia_entries = [] if ocsp_url is not None: aia_entries.append( asn1.SEQUENCE([ AIA_OCSP, asn1.Raw(asn1.TagAndLength(0x86, len(ocsp_url)) + ocsp_url), ])) if ca_issuers_url is not None: aia_entries.append( asn1.SEQUENCE([ AIA_CA_ISSUERS, asn1.Raw(asn1.TagAndLength(0x86, len(ca_issuers_url)) + ca_issuers_url), ])) extensions.children.append( asn1.SEQUENCE([ AUTHORITY_INFORMATION_ACCESS, # There is implicitly a critical=False here. Since false is the default, # encoding the value would be invalid DER. asn1.OCTETSTRING(asn1.ToDER(asn1.SEQUENCE(aia_entries))), ])) extensions.children.append( asn1.SEQUENCE([ CERT_POLICIES, # There is implicitly a critical=False here. Since false is the default, # encoding the value would be invalid DER. asn1.OCTETSTRING(asn1.ToDER(asn1.SEQUENCE([ asn1.SEQUENCE([ # PolicyInformation CERT_POLICY_OID, ]), ]))), ]) ) tbsCert = asn1.ToDER(asn1.SEQUENCE([ asn1.Explicit(0, 2), # Version serial, asn1.SEQUENCE([SHA256_WITH_RSA_ENCRYPTION, None]), # SignatureAlgorithm Name(cn = issuer_cn), # Issuer asn1.SEQUENCE([ # Validity asn1.UTCTime("100101060000Z"), # NotBefore asn1.UTCTime("321201060000Z"), # NotAfter ]), Name(cn = subject_cn, c = c, o = o), # Subject asn1.SEQUENCE([ # SubjectPublicKeyInfo asn1.SEQUENCE([ # Algorithm PUBLIC_KEY_RSA, None, ]), asn1.BitString(asn1.ToDER(pubkey)), ]), asn1.Explicit(3, extensions), ])) return asn1.ToDER(asn1.SEQUENCE([ asn1.Raw(tbsCert), asn1.SEQUENCE([ SHA256_WITH_RSA_ENCRYPTION, None, ]), asn1.BitString(privkey.Sign(tbsCert)), ]))
#!/usr/bin/env python assert (0) # XXX shouldn't use, absorbed into z3950_2001.py #from PyZ3950 import asn1 import asn1 InitialSet = asn1.SEQUENCE([ ('g0', None, asn1.TYPE(asn1.IMPLICIT(0, cls=asn1.CONTEXT_FLAG), asn1.INTEGER), 1), ('g1', None, asn1.TYPE(asn1.IMPLICIT(1, cls=asn1.CONTEXT_FLAG), asn1.INTEGER), 1), ('g2', None, asn1.TYPE(asn1.IMPLICIT(2, cls=asn1.CONTEXT_FLAG), asn1.INTEGER), 1), ('g3', None, asn1.TYPE(asn1.IMPLICIT(3, cls=asn1.CONTEXT_FLAG), asn1.INTEGER), 1), ('c0', None, asn1.TYPE(asn1.IMPLICIT(4, cls=asn1.CONTEXT_FLAG), asn1.INTEGER), 0), ('c1', None, asn1.TYPE(asn1.IMPLICIT(5, cls=asn1.CONTEXT_FLAG), asn1.INTEGER), 1) ]) PrivateCharacterSet = asn1.CHOICE([ ('viaOid', None, asn1.TYPE(asn1.IMPLICIT(1, cls=asn1.CONTEXT_FLAG), asn1.SEQUENCE_OF(asn1.OBJECT_IDENTIFIER))), ('externallySpecified', None, asn1.TYPE(asn1.IMPLICIT(2, cls=asn1.CONTEXT_FLAG), asn1.EXTERNAL)), ('previouslyAgreedUpon', None, asn1.TYPE(asn1.IMPLICIT(3, cls=asn1.CONTEXT_FLAG), asn1.NULL))