def create_certificate(pending_certificate, certificate, user): """ Create and store a certificate with pending certificate's info :arg pending_certificate: PendingCertificate which will populate the certificate :arg certificate: dict from Authority, which contains the body, chain and external id :arg user: User that called this function, used as 'creator' of the certificate if it does not have an owner """ certificate["owner"] = pending_certificate.owner data, errors = CertificateUploadInputSchema().load(certificate) if errors: raise Exception( "Unable to create certificate: {reasons}".format(reasons=errors)) data.update(vars(pending_certificate)) # Copy relationships, vars doesn't copy this without explicit fields data["notifications"] = list(pending_certificate.notifications) data["destinations"] = list(pending_certificate.destinations) data["sources"] = list(pending_certificate.sources) data["roles"] = list(pending_certificate.roles) data["replaces"] = list(pending_certificate.replaces) data["rotation_policy"] = pending_certificate.rotation_policy # Replace external id and chain with the one fetched from source data["external_id"] = certificate["external_id"] data["chain"] = certificate["chain"] creator = user_service.get_by_email(pending_certificate.owner) if not creator: # Owner of the pending certificate is not the creator, so use the current user who called # this as the creator (usually lemur) creator = user if pending_certificate.rename: # If generating name from certificate, remove the one from pending certificate del data["name"] data["creator"] = creator cert = certificate_service.import_certificate(**data) database.update(cert) metrics.send("certificate_issued", "counter", 1, metric_tags=dict(owner=cert.owner, issuer=cert.issuer)) log_service.audit_log( "certificate_from_pending_certificate", cert.name, f"Created from the pending certificate {pending_certificate.name}") log_data = { "function": "lemur.certificates.service.create", "owner": cert.owner, "name": cert.name, "serial": cert.serial, "issuer": cert.issuer, "not_after": cert.not_after.format('YYYY-MM-DD HH:mm:ss'), "not_before": cert.not_before.format('YYYY-MM-DD HH:mm:ss'), "sans": cert.san, } current_app.logger.info(log_data) return cert
def create_certificate(pending_certificate, certificate, user): """ Create and store a certificate with pending certificate's info Args: pending_certificate: PendingCertificate which will populate the certificate certificate: dict from Authority, which contains the body, chain and external id user: User that called this function, used as 'creator' of the certificate if it does not have an owner """ # check if the pending_certificate already has been resolved, in that case return # existing certificate maybe_resolved_cert = get(pending_certificate.id) if maybe_resolved_cert and maybe_resolved_cert.resolved and maybe_resolved_cert.resolved_cert_id: current_app.logger.warning( "Trying to resolve an already resolved certificate, returning existing resolved certificate" ) return certificate_service.get(maybe_resolved_cert.resolved_cert_id) certificate["owner"] = pending_certificate.owner data, errors = CertificateUploadInputSchema().load(certificate) if errors: raise Exception( "Unable to create certificate: {reasons}".format(reasons=errors)) data.update(vars(pending_certificate)) # Copy relationships, vars doesn't copy this without explicit fields data["notifications"] = list(pending_certificate.notifications) data["destinations"] = list(pending_certificate.destinations) data["sources"] = list(pending_certificate.sources) data["roles"] = list(pending_certificate.roles) data["replaces"] = list(pending_certificate.replaces) data["rotation_policy"] = pending_certificate.rotation_policy data["authority"] = pending_certificate.authority # Replace external id and chain with the one fetched from source data["external_id"] = certificate["external_id"] data["chain"] = certificate["chain"] creator = user_service.get_by_email(pending_certificate.owner) if not creator: # Owner of the pending certificate is not the creator, so use the current user who called # this as the creator (usually lemur) creator = user if pending_certificate.rename: # If generating name from certificate, remove the one from pending certificate del data["name"] data["creator"] = creator cert = certificate_service.import_certificate(**data) database.update(cert) return cert
def test_certificate_upload_schema_minimal(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { 'owner': '*****@*****.**', 'body': SAN_CERT_STR, } data, errors = CertificateUploadInputSchema().load(data) assert not errors
def test_certificate_upload_schema_invalid_body(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { 'owner': '*****@*****.**', 'body': 'Hereby I certify that this is a valid body', } data, errors = CertificateUploadInputSchema().load(data) assert errors == {'body': ['Public certificate presented is not valid.']}
def test_certificate_upload_schema_long_chain(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { 'owner': '*****@*****.**', 'body': SAN_CERT_STR, 'chain': INTERMEDIATE_CERT_STR + '\n' + ROOTCA_CERT_STR } data, errors = CertificateUploadInputSchema().load(data) assert not errors
def test_certificate_upload_schema_invalid_body(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { "owner": "*****@*****.**", "body": "Hereby I certify that this is a valid body", } data, errors = CertificateUploadInputSchema().load(data) assert errors == {"body": ["Public certificate presented is not valid."]}
def test_certificate_upload_schema_invalid_pkey(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { 'owner': '*****@*****.**', 'body': SAN_CERT_STR, 'privateKey': 'Look at me Im a private key!!111', } data, errors = CertificateUploadInputSchema().load(data) assert errors == {'private_key': ['Private key presented is not valid.']}
def test_certificate_upload_schema_invalid_chain(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { 'body': SAN_CERT_STR, 'chain': 'CHAINSAW', 'owner': '*****@*****.**', } data, errors = CertificateUploadInputSchema().load(data) assert errors == {'chain': ['Public certificate presented is not valid.']}
def test_certificate_upload_schema_invalid_chain(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { "body": SAN_CERT_STR, "chain": "CHAINSAW", "owner": "*****@*****.**" } data, errors = CertificateUploadInputSchema().load(data) assert errors == {"chain": ["Invalid certificate in certificate chain."]}
def test_certificate_upload_schema_invalid_pkey(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { "owner": "*****@*****.**", "body": SAN_CERT_STR, "privateKey": "Look at me Im a private key!!111", } data, errors = CertificateUploadInputSchema().load(data) assert errors == {"private_key": ["Private key presented is not valid."]}
def test_certificate_upload_schema_long_chain(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { "owner": "*****@*****.**", "body": SAN_CERT_STR, "chain": INTERMEDIATE_CERT_STR + "\n" + ROOTCA_CERT_STR, } data, errors = CertificateUploadInputSchema().load(data) assert not errors
def test_certificate_upload_schema_wrong_pkey(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { 'body': SAN_CERT_STR, 'privateKey': ROOTCA_KEY, 'chain': INTERMEDIATE_CERT_STR, 'owner': '*****@*****.**', } data, errors = CertificateUploadInputSchema().load(data) assert errors == {'_schema': ['Private key does not match certificate.']}
def test_certificate_upload_schema_wrong_pkey(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { "body": SAN_CERT_STR, "privateKey": ROOTCA_KEY, "chain": INTERMEDIATE_CERT_STR, "owner": "*****@*****.**", } data, errors = CertificateUploadInputSchema().load(data) assert errors == {"_schema": ["Private key does not match certificate."]}
def create_certificate(pending_certificate, certificate, user): """ Create and store a certificate with pending certificate's info Args: pending_certificate: PendingCertificate which will populate the certificate certificate: dict from Authority, which contains the body, chain and external id user: User that called this function, used as 'creator' of the certificate if it does not have an owner """ certificate['owner'] = pending_certificate.owner data, errors = CertificateUploadInputSchema().load(certificate) if errors: raise Exception( "Unable to create certificate: {reasons}".format(reasons=errors)) data.update(vars(pending_certificate)) # Copy relationships, vars doesn't copy this without explicit fields data['notifications'] = list(pending_certificate.notifications) data['destinations'] = list(pending_certificate.destinations) data['sources'] = list(pending_certificate.sources) data['roles'] = list(pending_certificate.roles) data['replaces'] = list(pending_certificate.replaces) data['rotation_policy'] = pending_certificate.rotation_policy # Replace external id and chain with the one fetched from source data['external_id'] = certificate['external_id'] data['chain'] = certificate['chain'] creator = user_service.get_by_email(pending_certificate.owner) if not creator: # Owner of the pending certificate is not the creator, so use the current user who called # this as the creator (usually lemur) creator = user if pending_certificate.rename: # If generating name from certificate, remove the one from pending certificate del data['name'] data['creator'] = creator cert = certificate_service.import_certificate(**data) database.update(cert) return cert
def test_certificate_upload_schema_ok(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { 'name': 'Jane', 'owner': '*****@*****.**', 'body': SAN_CERT_STR, 'privateKey': SAN_CERT_KEY, 'chain': INTERMEDIATE_CERT_STR, 'external_id': '1234', } data, errors = CertificateUploadInputSchema().load(data) assert not errors
def create_certificate(pending_certificate, certificate, user): """ Create and store a certificate with pending certificate's info Args: pending_certificate: PendingCertificate which will populate the certificate certificate: dict from Authority, which contains the body, chain and external id user: User that called this function, used as 'creator' of the certificate if it does not have an owner """ certificate['owner'] = pending_certificate.owner data, errors = CertificateUploadInputSchema().load(certificate) if errors: raise Exception("Unable to create certificate: {reasons}".format(reasons=errors)) data.update(vars(pending_certificate)) # Copy relationships, vars doesn't copy this without explicit fields data['notifications'] = list(pending_certificate.notifications) data['destinations'] = list(pending_certificate.destinations) data['sources'] = list(pending_certificate.sources) data['roles'] = list(pending_certificate.roles) data['replaces'] = list(pending_certificate.replaces) data['rotation_policy'] = pending_certificate.rotation_policy # Replace external id and chain with the one fetched from source data['external_id'] = certificate['external_id'] data['chain'] = certificate['chain'] creator = user_service.get_by_email(pending_certificate.owner) if not creator: # Owner of the pending certificate is not the creator, so use the current user who called # this as the creator (usually lemur) creator = user if pending_certificate.rename: # If generating name from certificate, remove the one from pending certificate del data['name'] data['creator'] = creator cert = certificate_service.import_certificate(**data) database.update(cert) return cert
def certificate_create(certificate, source): data, errors = CertificateUploadInputSchema().load(certificate) if errors: raise Exception( "Unable to import certificate: {reasons}".format(reasons=errors)) cert = cert_service.import_certificate(**data) cert.description = "This certificate was automatically discovered by Lemur" cert.sources.append(source) sync_update_destination(cert, source) database.update(cert) return cert
def test_certificate_upload_schema_wrong_chain(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { 'owner': '*****@*****.**', 'body': SAN_CERT_STR, 'chain': ROOTCA_CERT_STR, } data, errors = CertificateUploadInputSchema().load(data) assert errors == { '_schema': [ "Incorrect chain certificate(s) provided: 'san.example.org' is not signed by " "'LemurTrust Unittests Root CA 2018'" ] }
def test_certificate_upload_schema_ok(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { "name": "Jane", "owner": "*****@*****.**", "body": SAN_CERT_STR, "privateKey": SAN_CERT_KEY, "chain": INTERMEDIATE_CERT_STR, "csr": SAN_CERT_CSR, "external_id": "1234", } data, errors = CertificateUploadInputSchema().load(data) assert not errors
def test_certificate_upload_schema_wrong_chain_2nd(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { 'owner': '*****@*****.**', 'body': SAN_CERT_STR, 'chain': INTERMEDIATE_CERT_STR + '\n' + SAN_CERT_STR, } data, errors = CertificateUploadInputSchema().load(data) assert errors == { '_schema': [ "Incorrect chain certificate(s) provided: 'LemurTrust Unittests Class 1 CA 2018' is " "not signed by 'san.example.org'" ] }
def certificate_create(certificate, source): data, errors = CertificateUploadInputSchema().load(certificate) if errors: current_app.logger.error(f"Unable to import certificate: {errors}") return data["creator"] = certificate["creator"] cert = certificate_service.import_certificate(**data) cert.description = "This certificate was automatically discovered by Lemur" cert.sources.append(source) sync_update_destination(cert, source) database.update(cert) return cert
def test_certificate_upload_schema_wrong_chain_2nd(client): from lemur.certificates.schemas import CertificateUploadInputSchema data = { "owner": "*****@*****.**", "body": SAN_CERT_STR, "chain": INTERMEDIATE_CERT_STR + "\n" + SAN_CERT_STR, } data, errors = CertificateUploadInputSchema().load(data) assert errors == { "_schema": [ "Incorrect chain certificate(s) provided: 'LemurTrust Unittests Class 1 CA 2018' is " "not signed by 'san.example.org'" ] }