Exemplo n.º 1
0
 def verify_x509(self, paymntreq):
     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 make_payment_request(outputs, memo, time, expires, key_path, cert_path):
    pd = pb2.PaymentDetails()
    for script, amount in outputs:
        pd.outputs.add(amount=amount, script=script)
    pd.time = time
    pd.expires = expires
    pd.memo = memo
    pr = pb2.PaymentRequest()
    pr.serialized_payment_details = pd.SerializeToString()
    pr.signature = ''
    pr = pb2.PaymentRequest()
    pr.serialized_payment_details = pd.SerializeToString()
    pr.signature = ''
    if key_path and cert_path:
        import tlslite
        with open(key_path, 'r') as f:
            rsakey = tlslite.utils.python_rsakey.Python_RSAKey.parsePEM(
                f.read())
        with open(cert_path, 'r') as f:
            chain = tlslite.X509CertChain()
            chain.parsePemList(f.read())
        certificates = pb2.X509Certificates()
        certificates.certificate.extend(
            map(lambda x: str(x.bytes), chain.x509List))
        pr.pki_type = 'x509+sha256'
        pr.pki_data = certificates.SerializeToString()
        msgBytes = bytearray(pr.SerializeToString())
        hashBytes = bytearray(hashlib.sha256(msgBytes).digest())
        sig = rsakey.sign(x509.PREFIX_RSA_SHA256 + hashBytes)
        pr.signature = bytes(sig)
    return pr.SerializeToString()
Exemplo n.º 3
0
    def verify(self):
        u = urlparse.urlparse(self.url)
        self.domain = u.netloc

        try:
            connection = httplib.HTTPConnection(
                u.netloc) if u.scheme == 'http' else httplib.HTTPSConnection(
                    u.netloc)
            connection.request("GET", u.geturl(), headers=REQUEST_HEADERS)
            resp = connection.getresponse()
        except:
            self.error = "cannot read url"
            return

        paymntreq = paymentrequest_pb2.PaymentRequest()
        try:
            r = resp.read()
            paymntreq.ParseFromString(r)
        except:
            self.error = "cannot parse payment request"
            return

        sig = paymntreq.signature
        if not sig:
            self.error = "No signature"
            return

        cert = paymentrequest_pb2.X509Certificates()
        cert.ParseFromString(paymntreq.pki_data)
        cert_num = len(cert.certificate)

        x509_1 = X509.load_cert_der_string(cert.certificate[0])
        if self.domain != x509_1.get_subject().CN:
            validcert = False
            try:
                SANs = x509_1.get_ext("subjectAltName").get_value().split(",")
                for s in SANs:
                    s = s.strip()
                    if s.startswith("DNS:") and s[4:] == self.domain:
                        validcert = True
                        print "Match SAN DNS"
                    elif s.startswith("IP:") and s[3:] == self.domain:
                        validcert = True
                        print "Match SAN IP"
                    elif s.startswith("email:") and s[6:] == self.domain:
                        validcert = True
                        print "Match SAN email"
            except Exception, e:
                print "ERROR: No SAN data"
            if not validcert:
                ###TODO: check for wildcards
                self.error = "ERROR: Certificate Subject Domain Mismatch and SAN Mismatch"
                return
Exemplo n.º 4
0
def sign_request_with_x509(pr, key_path, cert_path):
    import tlslite
    with open(key_path, 'r') as f:
        rsakey = tlslite.utils.python_rsakey.Python_RSAKey.parsePEM(f.read())
    with open(cert_path, 'r') as f:
        chain = tlslite.X509CertChain()
        chain.parsePemList(f.read())
    certificates = pb2.X509Certificates()
    certificates.certificate.extend(map(lambda x: str(x.bytes), chain.x509List))
    pr.pki_type = 'x509+sha256'
    pr.pki_data = certificates.SerializeToString()
    msgBytes = bytearray(pr.SerializeToString())
    hashBytes = bytearray(hashlib.sha256(msgBytes).digest())
    sig = rsakey.sign(x509.PREFIX_RSA_SHA256 + hashBytes)
    pr.signature = bytes(sig)
Exemplo n.º 5
0
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)
Exemplo n.º 6
0
    def verify(self):
        try:
            from M2Crypto import X509
        except:
            self.error = "cannot import M2Crypto"
            return False

        if not ca_list:
            self.error = "Trusted certificate authorities list not found"
            return False

        paymntreq = self.data
        sig = paymntreq.signature
        if not sig:
            self.error = "No signature"
            return

        cert = paymentrequest_pb2.X509Certificates()
        cert.ParseFromString(paymntreq.pki_data)
        cert_num = len(cert.certificate)

        x509_1 = X509.load_cert_der_string(cert.certificate[0])
        if self.domain != x509_1.get_subject().CN:
            validcert = False
            try:
                SANs = x509_1.get_ext("subjectAltName").get_value().split(",")
                for s in SANs:
                    s = s.strip()
                    if s.startswith("DNS:") and s[4:] == self.domain:
                        validcert = True
                        print "Match SAN DNS"
                    elif s.startswith("IP:") and s[3:] == self.domain:
                        validcert = True
                        print "Match SAN IP"
                    elif s.startswith("email:") and s[6:] == self.domain:
                        validcert = True
                        print "Match SAN email"
            except Exception, e:
                print "ERROR: No SAN data"
            if not validcert:
                ###TODO: check for wildcards
                self.error = "ERROR: Certificate Subject Domain Mismatch and SAN Mismatch"
                return
Exemplo n.º 7
0
    def verify(self):

        if not ca_list:
            self.error = "Trusted certificate authorities list not found"
            return False

        paymntreq = self.data
        if not paymntreq.signature:
            self.error = "No signature"
            return

        cert = paymentrequest_pb2.X509Certificates()
        cert.ParseFromString(paymntreq.pki_data)
        cert_num = len(cert.certificate)

        x509_chain = []
        for i in range(cert_num):
            x = x509.X509()
            x.parseBinary(bytearray(cert.certificate[i]))
            x.slow_parse()
            x509_chain.append(x)
            if i == 0:
                try:
                    x.check_date()
                    x.check_name(self.domain)
                except Exception as e:
                    self.error = str(e)
                    return
            else:
                if not x.check_ca():
                    self.error = "ERROR: Supplied CA Certificate Error"
                    return

        if not cert_num > 1:
            self.error = "ERROR: CA Certificate Chain Not Provided by Payment Processor"
            return False

        for i in range(1, cert_num):
            x = x509_chain[i]
            prev_x = x509_chain[i - 1]

            algo, sig, data = prev_x.extract_sig()
            sig = bytearray(sig[5:])
            pubkey = x.publicKey
            if algo.getComponentByName('algorithm') == x509.ALGO_RSA_SHA1:
                verify = pubkey.hashAndVerify(sig, data)
            elif algo.getComponentByName('algorithm') == x509.ALGO_RSA_SHA256:
                hashBytes = bytearray(hashlib.sha256(data).digest())
                prefixBytes = bytearray([
                    0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
                    0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
                ])
                verify = pubkey.verify(sig, prefixBytes + hashBytes)
            else:
                self.error = "Algorithm not supported"
                util.print_error(self.error,
                                 algo.getComponentByName('algorithm'))
                return

            if not verify:
                self.error = "Certificate not Signed by Provided CA Certificate Chain"
                return

        ca = x509_chain[cert_num - 1]
        supplied_CA_fingerprint = ca.getFingerprint()
        supplied_CA_names = ca.extract_names()
        CA_OU = supplied_CA_names['OU']

        x = ca_list.get(supplied_CA_fingerprint)
        if x:
            x.slow_parse()
            names = x.extract_names()
            CA_match = True
            if names['CN'] != supplied_CA_names['CN']:
                print "ERROR: Trusted CA CN Mismatch; however CA has trusted fingerprint"
                print "Payment will continue with manual verification."
        else:
            CA_match = False

        pubkey0 = x509_chain[0].publicKey
        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())
            prefixBytes = bytearray([
                0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
                0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
            ])
            verify = pubkey0.verify(sigBytes, prefixBytes + hashBytes)
        elif paymntreq.pki_type == "x509+sha1":
            verify = pubkey0.hashAndVerify(sigBytes, msgBytes)
        else:
            self.error = "ERROR: Unsupported PKI Type for Message Signature"
            return False

        if not verify:
            self.error = "ERROR: Invalid Signature for Payment Request Data"
            return False

        ### SIG Verified
        self.details = pay_det = paymentrequest_pb2.PaymentDetails()
        self.details.ParseFromString(paymntreq.serialized_payment_details)

        for o in pay_det.outputs:
            addr = transaction.get_address_from_output_script(o.script)[1]
            self.outputs.append(('address', addr, o.amount))

        self.memo = self.details.memo

        if CA_match:
            self.status = 'Signed by Trusted CA:\n' + CA_OU
        else:
            self.status = "Supplied CA Not Found in Trusted CA Store."

        self.payment_url = self.details.payment_url

        return True
 def verify(self):
     if not ca_list:
         self.error = "Trusted certificate authorities list not found"
         return False
     paymntreq = pb2.PaymentRequest()
     paymntreq.ParseFromString(self.raw)
     if not paymntreq.signature:
         self.error = "No signature"
         return
     cert = pb2.X509Certificates()
     cert.ParseFromString(paymntreq.pki_data)
     cert_num = len(cert.certificate)
     x509_chain = []
     for i in range(cert_num):
         x = x509.X509()
         x.parseBinary(bytearray(cert.certificate[i]))
         x509_chain.append(x)
         if i == 0:
             try:
                 x.check_date()
             except Exception as e:
                 self.error = str(e)
                 return
             self.requestor = x.get_common_name()
             if self.requestor.startswith('*.'):
                 self.requestor = self.requestor[2:]
         else:
             if not x.check_ca():
                 self.error = "ERROR: Supplied CA Certificate Error"
                 return
     if not cert_num > 1:
         self.error = "ERROR: CA Certificate Chain Not Provided by Payment Processor"
         return False
     # if the root CA is not supplied, add it to the chain
     ca = x509_chain[cert_num - 1]
     if ca.getFingerprint() not in ca_list:
         keyID = ca.get_issuer_keyID()
         f = ca_keyID.get(keyID)
         if f:
             root = ca_list[f]
             x509_chain.append(root)
         else:
             self.error = "Supplied CA Not Found in Trusted CA Store."
             return False
     # verify the chain of signatures
     cert_num = len(x509_chain)
     for i in range(1, cert_num):
         x = x509_chain[i]
         prev_x = x509_chain[i - 1]
         algo, sig, data = prev_x.get_signature()
         sig = bytearray(sig)
         pubkey = x.publicKey
         if algo == x509.ALGO_RSA_SHA1:
             verify = pubkey.hashAndVerify(sig, data)
         elif algo == x509.ALGO_RSA_SHA256:
             hashBytes = bytearray(hashlib.sha256(data).digest())
             verify = pubkey.verify(sig, x509.PREFIX_RSA_SHA256 + hashBytes)
         elif algo == x509.ALGO_RSA_SHA384:
             hashBytes = bytearray(hashlib.sha384(data).digest())
             verify = pubkey.verify(sig, x509.PREFIX_RSA_SHA384 + hashBytes)
         elif algo == x509.ALGO_RSA_SHA512:
             hashBytes = bytearray(hashlib.sha512(data).digest())
             verify = pubkey.verify(sig, x509.PREFIX_RSA_SHA512 + hashBytes)
         else:
             self.error = "Algorithm not supported"
             util.print_error(self.error,
                              algo.getComponentByName('algorithm'))
             return False
         if not verify:
             self.error = "Certificate not Signed by Provided CA Certificate Chain"
             return False
     # verify the BIP70 signature
     pubkey0 = x509_chain[0].publicKey
     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)
     else:
         self.error = "ERROR: Unsupported PKI Type for Message Signature"
         return False
     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