def sign_request_with_x509(pr, key_path, cert_path): import pem with open(key_path, 'r') as f: params = pem.parse_private_key(f.read()) privkey = rsakey.RSAKey(*params) with open(cert_path, 'r') as f: s = f.read() bList = pem.dePemList(s, "CERTIFICATE") certificates = pb2.X509Certificates() certificates.certificate.extend(map(str, bList)) pr.pki_type = 'x509+sha256' pr.pki_data = certificates.SerializeToString() msgBytes = bytearray(pr.SerializeToString()) hashBytes = bytearray(hashlib.sha256(msgBytes).digest()) sig = privkey.sign(x509.PREFIX_RSA_SHA256 + hashBytes) pr.signature = bytes(sig)
def verify_x509(self, paymntreq): load_ca_list() if not ca_list: self.error = "Trusted certificate authorities list not found" return False cert = pb2.X509Certificates() cert.ParseFromString(paymntreq.pki_data) # verify the chain of certificates try: x, ca = verify_cert_chain(cert.certificate) except BaseException as e: traceback.print_exc(file=sys.stderr) self.error = str(e) return False # get requestor name self.requestor = x.get_common_name() if self.requestor.startswith('*.'): self.requestor = self.requestor[2:] # verify the BIP70 signature pubkey0 = rsakey.RSAKey(x.modulus, x.exponent) sig = paymntreq.signature paymntreq.signature = '' s = paymntreq.SerializeToString() sigBytes = bytearray(sig) msgBytes = bytearray(s) if paymntreq.pki_type == "x509+sha256": hashBytes = bytearray(hashlib.sha256(msgBytes).digest()) verify = pubkey0.verify(sigBytes, x509.PREFIX_RSA_SHA256 + hashBytes) elif paymntreq.pki_type == "x509+sha1": verify = pubkey0.hashAndVerify(sigBytes, msgBytes) if not verify: self.error = "ERROR: Invalid Signature for Payment Request Data" return False ### SIG Verified self.error = 'Signed by Trusted CA: ' + ca.get_common_name() return True
def python_validate_rrsig(rrset, rrsig, keys, origin=None, now=None): from dns.dnssec import ValidationFailure, ECDSAP256SHA256, ECDSAP384SHA384 from dns.dnssec import _find_candidate_keys, _make_hash, _is_ecdsa, _is_rsa, _to_rdata, _make_algorithm_id if isinstance(origin, (str, unicode)): origin = dns.name.from_text(origin, dns.name.root) for candidate_key in _find_candidate_keys(keys, rrsig): if not candidate_key: raise ValidationFailure, 'unknown key' # For convenience, allow the rrset to be specified as a (name, rdataset) # tuple as well as a proper rrset if isinstance(rrset, tuple): rrname = rrset[0] rdataset = rrset[1] else: rrname = rrset.name rdataset = rrset if now is None: now = time.time() if rrsig.expiration < now: raise ValidationFailure, 'expired' if rrsig.inception > now: raise ValidationFailure, 'not yet valid' hash = _make_hash(rrsig.algorithm) if _is_rsa(rrsig.algorithm): keyptr = candidate_key.key (bytes, ) = struct.unpack('!B', keyptr[0:1]) keyptr = keyptr[1:] if bytes == 0: (bytes, ) = struct.unpack('!H', keyptr[0:2]) keyptr = keyptr[2:] rsa_e = keyptr[0:bytes] rsa_n = keyptr[bytes:] n = ecdsa.util.string_to_number(rsa_n) e = ecdsa.util.string_to_number(rsa_e) pubkey = rsakey.RSAKey(n, e) sig = rrsig.signature elif _is_ecdsa(rrsig.algorithm): if rrsig.algorithm == ECDSAP256SHA256: curve = ecdsa.curves.NIST256p key_len = 32 digest_len = 32 elif rrsig.algorithm == ECDSAP384SHA384: curve = ecdsa.curves.NIST384p key_len = 48 digest_len = 48 else: # shouldn't happen raise ValidationFailure, 'unknown ECDSA curve' keyptr = candidate_key.key x = ecdsa.util.string_to_number(keyptr[0:key_len]) y = ecdsa.util.string_to_number(keyptr[key_len:key_len * 2]) assert ecdsa.ecdsa.point_is_valid(curve.generator, x, y) point = ecdsa.ellipticcurve.Point(curve.curve, x, y, curve.order) verifying_key = ecdsa.keys.VerifyingKey.from_public_point( point, curve) r = rrsig.signature[:key_len] s = rrsig.signature[key_len:] sig = ecdsa.ecdsa.Signature(ecdsa.util.string_to_number(r), ecdsa.util.string_to_number(s)) else: raise ValidationFailure, 'unknown algorithm %u' % rrsig.algorithm hash.update(_to_rdata(rrsig, origin)[:18]) hash.update(rrsig.signer.to_digestable(origin)) if rrsig.labels < len(rrname) - 1: suffix = rrname.split(rrsig.labels + 1)[1] rrname = dns.name.from_text('*', suffix) rrnamebuf = rrname.to_digestable(origin) rrfixed = struct.pack('!HHI', rdataset.rdtype, rdataset.rdclass, rrsig.original_ttl) rrlist = sorted(rdataset) for rr in rrlist: hash.update(rrnamebuf) hash.update(rrfixed) rrdata = rr.to_digestable(origin) rrlen = struct.pack('!H', len(rrdata)) hash.update(rrlen) hash.update(rrdata) digest = hash.digest() if _is_rsa(rrsig.algorithm): digest = _make_algorithm_id(rrsig.algorithm) + digest if pubkey.verify(bytearray(sig), bytearray(digest)): return elif _is_ecdsa(rrsig.algorithm): diglong = ecdsa.util.string_to_number(digest) if verifying_key.pubkey.verifies(diglong, sig): return else: raise ValidationFailure, 'unknown algorithm %u' % rrsig.algorithm raise ValidationFailure, 'verify failure'