def execute_put(cert, key, key_export, name_to_save=None, passphrase=None):
    certificate_client = CertificateClient()

    crt_export = cert.public_bytes(serialization.Encoding.PEM)
    crt_bin = cert.public_bytes(serialization.Encoding.DER).hex()
    crt_hash = hashlib.sha512(crt_bin.encode('utf-8')).hexdigest()
    rem_sig = certificate_client.sign_text(crt_hash)
    crt_sig = get_certificate_signature(key, rem_sig)

    try:
        saved_to = save_p12(cert, key, name_to_save, passphrase)
    except ValueError:
        return {'error': 'The file already exists in specified location'}, 409

    status, _ = certificate_client.store_certificate(crt_bin, rem_sig,
                                                     crt_sig.hex())

    response = {
        'certificate': crt_export.decode('utf-8'),
        'priv_key': key_export.decode('utf-8'),
        'batch_id': re.search(r'id=([0-9a-f]+)', status['link']).group(1)
    }
    if saved_to:
        response['saved_to'] = saved_to

    return response
def execute_post(certificate_address):
    client = CertificateClient()
    try:
        certificate_data = client.get_status(certificate_address)
        return {
            'revoked': certificate_data.revoked,
            'owner': certificate_data.owner
        }
    except KeyNotFound:
        return NoContent, 404
def execute_delete(certificate_address):
    client = CertificateClient()
    try:
        certificate_data = client.get_status(certificate_address)
        if certificate_data.revoked:
            return {'error': 'The certificate was already revoked'}, 409
        client.revoke_certificate(certificate_address)
        return NoContent, 200
    except KeyNotFound:
        return NoContent, 404
Exemple #4
0
def build_certificate(parameters, payload, key):
    name_oid = [x509.NameAttribute(NameOID.ORGANIZATION_NAME, CERT_ORGANIZATION),
                x509.NameAttribute(NameOID.USER_ID, CertificateClient().get_signer_pubkey())]

    for k, v in parameters.items():
        if k in payload.keys():
            name_oid.append(x509.NameAttribute(v, payload[k]))

    subject = issuer = x509.Name(name_oid)

    not_valid_before, not_valid_after = get_dates_from_payload(payload)

    return x509.CertificateBuilder().subject_name(
        subject
    ).issuer_name(
        issuer
    ).public_key(
        key.public_key()
    ).serial_number(
        x509.random_serial_number()
    ).not_valid_before(
        not_valid_before
    ).not_valid_after(
        not_valid_after
    ).sign(key, hashes.SHA256(), default_backend())
Exemple #5
0
    def validation_logic(payload):
        try:
            certificate = x509.load_pem_x509_certificate(payload['certificate'].encode('utf-8'),
                                                         default_backend())
            crt_bin = certificate.public_bytes(serialization.Encoding.DER).hex()
            address = CertificateClient().make_address_from_data(crt_bin)
        except ValueError:
            return {'error': 'Unable to load certificate entity'}, 422

        return func(address)
Exemple #6
0
    def validation_logic(certificate, passphrase=''):
        try:
            p12 = crypto.load_pkcs12(certificate.read(), passphrase)
            pub_cert = p12.get_certificate().to_cryptography()
            crt_bin = pub_cert.public_bytes(serialization.Encoding.DER).hex()
            address = CertificateClient().make_address_from_data(crt_bin)
        except ValueError:
            return {'error': 'Unable to load certificate entity'}, 422
        except crypto.Error:
            return {'error': 'Incorrect passphrase'}, 403

        return func(address)
def execute_store(cert_request):
    certificate_client = CertificateClient()

    key = get_keys_to_sign()
    cert = certificate_client.process_csr(cert_request, key)

    crt_export = cert.public_bytes(serialization.Encoding.PEM)
    crt_bin = cert.public_bytes(serialization.Encoding.DER).hex()
    crt_hash = hashlib.sha512(crt_bin.encode('utf-8')).hexdigest()
    rem_sig = certificate_client.sign_text(crt_hash)
    crt_sig = get_certificate_signature(key, rem_sig)

    certificate_public_key = key.public_key().public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo)
    status, _ = certificate_client.store_certificate(crt_bin, rem_sig,
                                                     crt_sig.hex(),
                                                     certificate_public_key)

    return {
        'certificate': crt_export.decode('utf-8'),
        'batch_id': re.search(r'id=([0-9a-f]+)', status['link']).group(1)
    }
Exemple #8
0
 def __init__(self):
     self.client = CertificateClient()
Exemple #9
0
class CertificateCli(BasicCli):
    def __init__(self):
        self.client = CertificateClient()

    def parser_certificate(self, subparsers, parent_parser):
        message = 'Generate a certificate on the REMME blockchain.'

        subparsers.add_parser(
            'generate',
            parents=[parent_parser],
            description=message,
            help='Generate and register a new certificate.')

    def parser_revoke(self, subparsers, parent_parser):
        message = 'Revoke a certificate on the REMME blockchain.'

        parser = subparsers.add_parser(
            'revoke',
            parents=[parent_parser],
            description=message,
            help='Revoke a certificate.')

        parser.add_argument(
            'address',
            type=str,
        )

    def parser_status(self, subparsers, parent_parser):
        message = 'Check a certificate status.'

        parser = subparsers.add_parser(
            'check',
            parents=[parent_parser],
            description=message,
            help='Check a certificate status..')

        parser.add_argument(
            'address',
            type=str,
        )

    def revoke(self, args):
        self.client.revoke_certificate(args.address)

    def check_status(self, args):
        try:
            status = self.client.get_status(args.address)
            if status:
                print('Certificate on address {} is revoked.'.format(args.address))
            else:
                print('Certificate on address {} is valid.'.format(args.address))
        except KeyNotFound:
            print('No certificate registered on address {}.'.format(args.address))

    def generate_and_register(self, args):
        # GET USER DATA
        country_name = input('Country name: ')
        state_name = input('State or province name: ')
        locality_name = input('Locality name: ')
        common_name = input('Common name: ')
        validity = int(input('Certificate should be valid for (number of days): '))
        passphrase = getpass('Enter passphrase (leave empty for no passphrase): ')
        passphrase_repeat = getpass('Repeat passphrase: ')

        if passphrase != passphrase_repeat:
            print('Passphrase mismatch!')
            exit(0)

        if passphrase:
            encryption_algorithm = serialization.BestAvailableEncryption(passphrase.encode('utf-8'))
        else:
            encryption_algorithm = serialization.NoEncryption()

        # GENERATE KEY AND CERTIFICATE
        key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=2048,
            backend=default_backend()
        )
        with open('key.pem', 'wb') as f:
            f.write(key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.TraditionalOpenSSL,
                encryption_algorithm=encryption_algorithm,
            ))
        subject = issuer = x509.Name([
            x509.NameAttribute(NameOID.COUNTRY_NAME, country_name),
            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, state_name),
            x509.NameAttribute(NameOID.LOCALITY_NAME, locality_name),
            x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'REMME'),
            x509.NameAttribute(NameOID.COMMON_NAME, common_name),
            x509.NameAttribute(NameOID.USER_ID, self.client.get_signer_pubkey())
        ])
        cert = x509.CertificateBuilder().subject_name(
            subject
        ).issuer_name(
            issuer
        ).public_key(
            key.public_key()
        ).serial_number(
            x509.random_serial_number()
        ).not_valid_before(
            datetime.datetime.utcnow()
        ).not_valid_after(
            datetime.datetime.utcnow() + datetime.timedelta(days=validity)
        ).sign(key, hashes.SHA256(), default_backend())

        # Write our certificate out to disk.
        with open('certificate.pem', 'wb') as f:
            f.write(cert.public_bytes(serialization.Encoding.PEM))

        crt_bin = cert.public_bytes(serialization.Encoding.DER).hex()
        crt_hash = hashlib.sha512(crt_bin.encode('utf-8')).hexdigest()
        rem_sig = self.client.sign_text(crt_hash)

        crt_sig = key.sign(
            bytes.fromhex(rem_sig),
            padding.PSS(
                mgf=padding.MGF1(hashes.SHA256()),
                salt_length=padding.PSS.MAX_LENGTH
            ),
            hashes.SHA256()
        )

        status, address = self.client.store_certificate(crt_bin, rem_sig, crt_sig.hex())
        print('Certificate status check: {}'.format(status['link']))
        print('Certificate storage address: {}'.format(address))

    def run(self):
        commands = [{
            'name': 'generate',
            'parser': self.parser_certificate,
            'action': self.generate_and_register
        }, {
            'name': 'revoke',
            'parser': self.parser_revoke,
            'action': self.revoke
        }, {
            'name': 'check',
            'parser': self.parser_status,
            'action': self.check_status
        }]
        self.main_wrapper(commands)