certificates Package

exceptions Module

models Module

class lemur.certificates.models.Certificate(**kwargs)

Bases: flask_sqlalchemy.Model

active
authority_id
bits
body
chain
cn
country
date_created
deleted
description
destinations
domains
endpoints
expired = <sqlalchemy.sql.elements.Case object>
extensions
get_arn(account_number)

Generate a valid AWS IAM arn

:rtype : str :param account_number: :return:

id
issuer
key_type
location
logs
name
not_after
not_before
notifications
notify
organization
organizational_unit
owner
private_key
public_key
replaces
revoked = <sqlalchemy.sql.elements.Case object>
roles
root_authority_id
rotation
san
serial
signing_algorithm
sources
state
status
subject
user_id
validity_range
validity_remaining
lemur.certificates.models.get_or_increase_name(name)
lemur.certificates.models.get_sequence(name)
lemur.certificates.models.update_destinations(target, value, initiator)

Attempt to upload certificate to the new destination

Parameters:
  • target
  • value
  • initiator
Returns:

lemur.certificates.models.update_replacement(target, value, initiator)

When a certificate is marked as ‘replaced’ we should not notify.

Parameters:
  • target
  • value
  • initiator
Returns:

service Module

lemur.certificates.service.calculate_reissue_range(start, end)

Determine what the new validity_start and validity_end dates should be. :param start: :param end: :return:

lemur.certificates.service.create(**kwargs)

Creates a new certificate.

lemur.certificates.service.create_certificate_roles(**kwargs)
lemur.certificates.service.create_csr(**csr_config)

Given a list of domains create the appropriate csr for those domains

Parameters:csr_config
lemur.certificates.service.delete(cert_id)

Delete’s a certificate.

Parameters:cert_id
lemur.certificates.service.export(cert, export_plugin)

Exports a certificate to the requested format. This format may be a binary format.

Parameters:
  • export_plugin
  • cert
Returns:

lemur.certificates.service.find_duplicates(cert)

Finds certificates that already exist within Lemur. We do this by looking for certificate bodies that are the same. This is the most reliable way to determine if a certificate is already being tracked by Lemur.

Parameters:cert
Returns:
lemur.certificates.service.get(cert_id)

Retrieves certificate by its ID.

Parameters:cert_id
Returns:
lemur.certificates.service.get_account_number(arn)

Extract the account number from an arn.

Parameters:arn – IAM SSL arn
Returns:account number associated with ARN
lemur.certificates.service.get_all_certs()

Retrieves all certificates within Lemur.

Returns:
lemur.certificates.service.get_all_pending_cleaning(source)

Retrieves all certificates that are available for cleaning.

Parameters:source
Returns:
lemur.certificates.service.get_all_pending_reissue()

Retrieves all certificates that need to be rotated.

Must be X days from expiration, uses LEMUR_DEFAULT_ROTATION_INTERVAL to determine how many days from expiration the certificate must be for rotation to be pending.

Returns:
lemur.certificates.service.get_by_name(name)

Retrieves certificate by its Name.

Parameters:name
Returns:
lemur.certificates.service.get_certificate_primitives(certificate)

Retrieve key primitive from a certificate such that the certificate could be recreated with new expiration or be used to build upon. :param certificate: :return: dict of certificate primitives, should be enough to effectively re-issue certificate via create.

lemur.certificates.service.get_name_from_arn(arn)

Extract the certificate name from an arn.

Parameters:arn – IAM SSL arn
Returns:name of the certificate as uploaded to AWS
lemur.certificates.service.import_certificate(**kwargs)

Uploads already minted certificates and pulls the required information into Lemur.

This is to be used for certificates that are created outside of Lemur but should still be tracked.

Internally this is used to bootstrap Lemur with external certificates, and used when certificates are ‘discovered’ through various discovery techniques. was still in aws.

Parameters:kwargs
lemur.certificates.service.mint(**kwargs)

Minting is slightly different for each authority. Support for multiple authorities is handled by individual plugins.

lemur.certificates.service.reissue_certificate(certificate, replace=None, user=None)

Reissue certificate with the same properties of the given certificate. :param certificate: :param replace: :param user: :return:

lemur.certificates.service.render(args)

Helper function that allows use to render our REST Api.

Parameters:args
Returns:
lemur.certificates.service.stats(**kwargs)

Helper that defines some useful statistics about certifications.

Parameters:kwargs
Returns:
lemur.certificates.service.update(cert_id, **kwargs)

Updates a certificate :param cert_id: :return:

lemur.certificates.service.upload(**kwargs)

Allows for pre-made certificates to be imported into Lemur.

verify Module

lemur.certificates.verify.crl_verify(cert_path)

Attempts to verify a certificate using CRL.

Parameters:cert_path
Returns:True if certificate is valid, False otherwise
Raises:Exception – If certificate does not have CRL
lemur.certificates.verify.ocsp_verify(cert_path, issuer_chain_path)

Attempts to verify a certificate via OCSP. OCSP is a more modern version of CRL in that it will query the OCSP URI in order to determine if the certificate as been revoked

Parameters:
  • cert_path
  • issuer_chain_path
Return bool:

True if certificate is valid, False otherwise

lemur.certificates.verify.verify(cert_path, issuer_chain_path)

Verify a certificate using OCSP and CRL

Parameters:
  • cert_path
  • issuer_chain_path
Returns:

True if valid, False otherwise

lemur.certificates.verify.verify_string(cert_string, issuer_string)

Verify a certificate given only it’s string value

Parameters:
  • cert_string
  • issuer_string
Returns:

True if valid, False otherwise

views Module

class lemur.certificates.views.CertificateExport

Bases: lemur.auth.service.AuthenticatedResource

endpoint = 'exportCertificate'
mediatypes(resource_cls)
methods = ['POST']
post(certificate_id, data=None)
POST /certificates/1/export

Export a certificate

Example request:

PUT /certificates/1/export HTTP/1.1
Host: example.com
Accept: application/json, text/javascript

{
  "export": {
      "plugin": {
          "pluginOptions": [{
              "available": ["Java Key Store (JKS)"],
              "required": true,
              "type": "select",
              "name": "type",
              "helpMessage": "Choose the format you wish to export",
              "value": "Java Key Store (JKS)"
          }, {
              "required": false,
              "type": "str",
              "name": "passphrase",
              "validation": "^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$",
              "helpMessage": "If no passphrase is given one will be generated for you, we highly recommend this. Minimum length is 8."
          }, {
              "required": false,
              "type": "str",
              "name": "alias",
              "helpMessage": "Enter the alias you wish to use for the keystore."
          }],
          "version": "unknown",
          "description": "Attempts to generate a JKS keystore or truststore",
          "title": "Java",
          "author": "Kevin Glisson",
          "type": "export",
          "slug": "java-export"
      }
  }
}

Example response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript

{
  "data": "base64encodedstring",
  "passphrase": "UAWOHW#&@_%!tnwmxh832025",
  "extension": "jks"
}
Request Headers:
 
Status Codes:
class lemur.certificates.views.CertificatePrivateKey

Bases: lemur.auth.service.AuthenticatedResource

endpoint = 'privateKeyCertificates'
get(certificate_id)
GET /certificates/1/key

Retrieves the private key for a given certificate

Example request:

GET /certificates/1/key HTTP/1.1
Host: example.com
Accept: application/json, text/javascript

Example response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript

{
   "key": "-----BEGIN ...",
}
Request Headers:
 
Status Codes:
mediatypes(resource_cls)
methods = ['GET']
class lemur.certificates.views.Certificates

Bases: lemur.auth.service.AuthenticatedResource

endpoint = 'certificate'
get(certificate_id)
GET /certificates/1

One certificate

Example request:

GET /certificates/1 HTTP/1.1
Host: example.com
Accept: application/json, text/javascript

Example response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript

{
  "status": null,
  "cn": "*.test.example.net",
  "chain": "",
  "authority": {
      "active": true,
      "owner": "secure@example.com",
      "id": 1,
      "description": "verisign test authority",
      "name": "verisign"
  },
  "owner": "joe@example.com",
  "serial": "82311058732025924142789179368889309156",
  "id": 2288,
  "issuer": "SymantecCorporation",
  "notBefore": "2016-06-03T00:00:00+00:00",
  "notAfter": "2018-01-12T23:59:59+00:00",
  "destinations": [],
  "bits": 2048,
  "body": "-----BEGIN CERTIFICATE-----...",
  "description": null,
  "deleted": null,
  "notifications": [{
      "id": 1
  }]
  "signingAlgorithm": "sha256",
  "user": {
      "username": "jane",
      "active": true,
      "email": "jane@example.com",
      "id": 2
  },
  "active": true,
  "domains": [{
      "sensitive": false,
      "id": 1090,
      "name": "*.test.example.net"
  }],
  "replaces": [],
  "replaced": [],
  "name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112",
  "roles": [{
      "id": 464,
      "description": "This is a google group based role created by Lemur",
      "name": "joe@example.com"
  }],
  "san": null
}
Request Headers:
 
Status Codes:
mediatypes(resource_cls)
methods = ['GET', 'PUT']
put(certificate_id, data=None)
PUT /certificates/1

Update a certificate

Example request:

PUT /certificates/1 HTTP/1.1
Host: example.com
Accept: application/json, text/javascript

{
   "owner": "jimbob@example.com",
   "active": false
   "notifications": [],
   "destinations": [],
   "replacements": []
}

Example response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript

{
  "status": null,
  "cn": "*.test.example.net",
  "chain": "",
  "authority": {
      "active": true,
      "owner": "secure@example.com",
      "id": 1,
      "description": "verisign test authority",
      "name": "verisign"
  },
  "owner": "joe@example.com",
  "serial": "82311058732025924142789179368889309156",
  "id": 2288,
  "issuer": "SymantecCorporation",
  "notBefore": "2016-06-03T00:00:00+00:00",
  "notAfter": "2018-01-12T23:59:59+00:00",
  "destinations": [],
  "bits": 2048,
  "body": "-----BEGIN CERTIFICATE-----...",
  "description": null,
  "deleted": null,
  "notifications": [{
      "id": 1
  }]
  "signingAlgorithm": "sha256",
  "user": {
      "username": "jane",
      "active": true,
      "email": "jane@example.com",
      "id": 2
  },
  "active": true,
  "domains": [{
      "sensitive": false,
      "id": 1090,
      "name": "*.test.example.net"
  }],
  "replaces": [],
  "name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112",
  "roles": [{
      "id": 464,
      "description": "This is a google group based role created by Lemur",
      "name": "joe@example.com"
  }],
  "san": null
}
Request Headers:
 
Status Codes:
class lemur.certificates.views.CertificatesList

Bases: lemur.auth.service.AuthenticatedResource

Defines the ‘certificates’ endpoint

endpoint = 'certificates'
get()
GET /certificates

The current list of certificates

Example request:

GET /certificates HTTP/1.1
Host: example.com
Accept: application/json, text/javascript

Example response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript

{
  "items": [{
      "status": null,
      "cn": "*.test.example.net",
      "chain": "",
      "authority": {
          "active": true,
          "owner": "secure@example.com",
          "id": 1,
          "description": "verisign test authority",
          "name": "verisign"
      },
      "owner": "joe@example.com",
      "serial": "82311058732025924142789179368889309156",
      "id": 2288,
      "issuer": "SymantecCorporation",
      "notBefore": "2016-06-03T00:00:00+00:00",
      "notAfter": "2018-01-12T23:59:59+00:00",
      "destinations": [],
      "bits": 2048,
      "body": "-----BEGIN CERTIFICATE-----...",
      "description": null,
      "deleted": null,
      "notifications": [{
          "id": 1
      }]
      "signingAlgorithm": "sha256",
      "user": {
          "username": "jane",
          "active": true,
          "email": "jane@example.com",
          "id": 2
      },
      "active": true,
      "domains": [{
          "sensitive": false,
          "id": 1090,
          "name": "*.test.example.net"
      }],
      "replaces": [],
      "replaced": [],
      "name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112",
      "roles": [{
          "id": 464,
          "description": "This is a google group based role created by Lemur",
          "name": "joe@example.com"
      }],
      "san": null
  }],
  "total": 1
}
Query Parameters:
 
  • sortBy – field to sort on
  • sortDir – asc or desc
  • page – int. default is 1
  • filter – key value pair format is k;v
  • count – count number. default is 10
Request Headers:
 
Status Codes:
mediatypes(resource_cls)
methods = ['GET', 'POST']
post(data=None)
POST /certificates

Creates a new certificate

Example request:

POST /certificates HTTP/1.1
Host: example.com
Accept: application/json, text/javascript

{
    "owner": "secure@example.net",
    "commonName": "test.example.net",
    "country": "US",
    "extensions": {
      "subAltNames": {
        "names": [
          {
            "nameType": "DNSName",
            "value": "*.test.example.net"
          },
          {
            "nameType": "DNSName",
            "value": "www.test.example.net"
          }
        ]
      }
    },
    "replacements": [{
      "id": 1
    },
    "notify": true,
    "validityEnd": "2026-01-01T08:00:00.000Z",
    "authority": {
      "name": "verisign"
    },
    "organization": "Netflix, Inc.",
    "location": "Los Gatos",
    "state": "California",
    "validityStart": "2016-11-11T04:19:48.000Z",
    "organizationalUnit": "Operations"
}

Example response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript

{
  "status": null,
  "cn": "*.test.example.net",
  "chain": "",
  "authority": {
      "active": true,
      "owner": "secure@example.com",
      "id": 1,
      "description": "verisign test authority",
      "name": "verisign"
  },
  "owner": "joe@example.com",
  "serial": "82311058732025924142789179368889309156",
  "id": 2288,
  "issuer": "SymantecCorporation",
  "notBefore": "2016-06-03T00:00:00+00:00",
  "notAfter": "2018-01-12T23:59:59+00:00",
  "destinations": [],
  "bits": 2048,
  "body": "-----BEGIN CERTIFICATE-----...",
  "description": null,
  "deleted": null,
  "notifications": [{
      "id": 1
  }]
  "signingAlgorithm": "sha256",
  "user": {
      "username": "jane",
      "active": true,
      "email": "jane@example.com",
      "id": 2
  },
  "active": true,
  "domains": [{
      "sensitive": false,
      "id": 1090,
      "name": "*.test.example.net"
  }],
  "replaces": [{
      "id": 1
  }],
  "name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112",
  "roles": [{
      "id": 464,
      "description": "This is a google group based role created by Lemur",
      "name": "joe@example.com"
  }],
  "san": null
}
Parameters:
  • extensions – extensions to be used in the certificate
  • description – description for new certificate
  • owner – owner email
  • validityStart – when the certificate should start being valid
  • validityEnd – when the certificate should expire
  • authority – authority that should issue the certificate
  • country – country for the CSR
  • state – state for the CSR
  • location – location for the CSR
  • organization – organization for CSR
  • commonName – certificate common name
Request Headers:
 
Status Codes:
class lemur.certificates.views.CertificatesReplacementsList

Bases: lemur.auth.service.AuthenticatedResource

endpoint = 'replacements'
get(certificate_id)
GET /certificates/1/replacements

One certificate

Example request:

GET /certificates/1/replacements HTTP/1.1
Host: example.com
Accept: application/json, text/javascript

Example response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript

{
  "items": [{
      "status": null,
      "cn": "*.test.example.net",
      "chain": "",
      "authority": {
          "active": true,
          "owner": "secure@example.com",
          "id": 1,
          "description": "verisign test authority",
          "name": "verisign"
      },
      "owner": "joe@example.com",
      "serial": "82311058732025924142789179368889309156",
      "id": 2288,
      "issuer": "SymantecCorporation",
      "notBefore": "2016-06-03T00:00:00+00:00",
      "notAfter": "2018-01-12T23:59:59+00:00",
      "destinations": [],
      "bits": 2048,
      "body": "-----BEGIN CERTIFICATE-----...",
      "description": null,
      "deleted": null,
      "notifications": [{
          "id": 1
      }]
      "signingAlgorithm": "sha256",
      "user": {
          "username": "jane",
          "active": true,
          "email": "jane@example.com",
          "id": 2
      },
      "active": true,
      "domains": [{
          "sensitive": false,
          "id": 1090,
          "name": "*.test.example.net"
      }],
      "replaces": [],
      "replaced": [],
      "name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112",
      "roles": [{
          "id": 464,
          "description": "This is a google group based role created by Lemur",
          "name": "joe@example.com"
      }],
      "san": null
  }],
  "total": 1
}
Request Headers:
 
Status Codes:
mediatypes(resource_cls)
methods = ['GET']
class lemur.certificates.views.CertificatesStats

Bases: lemur.auth.service.AuthenticatedResource

Defines the ‘certificates’ stats endpoint

endpoint = 'certificateStats'
get()
mediatypes(resource_cls)
methods = ['GET']
class lemur.certificates.views.CertificatesUpload

Bases: lemur.auth.service.AuthenticatedResource

Defines the ‘certificates’ upload endpoint

endpoint = 'certificateUpload'
mediatypes(resource_cls)
methods = ['POST']
post(data=None)
POST /certificates/upload

Upload a certificate

Example request:

POST /certificates/upload HTTP/1.1
Host: example.com
Accept: application/json, text/javascript

{
   "owner": "joe@example.com",
   "publicCert": "-----BEGIN CERTIFICATE-----...",
   "intermediateCert": "-----BEGIN CERTIFICATE-----...",
   "privateKey": "-----BEGIN RSA PRIVATE KEY-----..."
   "destinations": [],
   "notifications": [],
   "replacements": [],
   "name": "cert1"
}

Example response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript

{
  "status": null,
  "cn": "*.test.example.net",
  "chain": "",
  "authority": {
      "active": true,
      "owner": "secure@example.com",
      "id": 1,
      "description": "verisign test authority",
      "name": "verisign"
  },
  "owner": "joe@example.com",
  "serial": "82311058732025924142789179368889309156",
  "id": 2288,
  "issuer": "SymantecCorporation",
  "notBefore": "2016-06-03T00:00:00+00:00",
  "notAfter": "2018-01-12T23:59:59+00:00",
  "destinations": [],
  "bits": 2048,
  "body": "-----BEGIN CERTIFICATE-----...",
  "description": null,
  "deleted": null,
  "notifications": [{
      "id": 1
  }]
  "signingAlgorithm": "sha256",
  "user": {
      "username": "jane",
      "active": true,
      "email": "jane@example.com",
      "id": 2
  },
  "active": true,
  "domains": [{
      "sensitive": false,
      "id": 1090,
      "name": "*.test.example.net"
  }],
  "replaces": [],
  "name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112",
  "roles": [{
      "id": 464,
      "description": "This is a google group based role created by Lemur",
      "name": "joe@example.com"
  }],
  "san": null
}
Parameters:
  • owner – owner email for certificate
  • publicCert – valid PEM public key for certificate

:arg intermediateCert valid PEM intermediate key for certificate :arg privateKey: valid PEM private key for certificate :arg destinations: list of aws destinations to upload the certificate to :reqheader Authorization: OAuth token to authenticate :statuscode 403: unauthenticated :statuscode 200: no error

class lemur.certificates.views.NotificationCertificatesList

Bases: lemur.auth.service.AuthenticatedResource

Defines the ‘certificates’ endpoint

endpoint = 'notificationCertificates'
get(notification_id)
GET /notifications/1/certificates

The current list of certificates for a given notification

Example request:

GET /notifications/1/certificates HTTP/1.1
Host: example.com
Accept: application/json, text/javascript

Example response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript

{
  "items": [{
      "status": null,
      "cn": "*.test.example.net",
      "chain": "",
      "authority": {
          "active": true,
          "owner": "secure@example.com",
          "id": 1,
          "description": "verisign test authority",
          "name": "verisign"
      },
      "owner": "joe@example.com",
      "serial": "82311058732025924142789179368889309156",
      "id": 2288,
      "issuer": "SymantecCorporation",
      "notBefore": "2016-06-03T00:00:00+00:00",
      "notAfter": "2018-01-12T23:59:59+00:00",
      "destinations": [],
      "bits": 2048,
      "body": "-----BEGIN CERTIFICATE-----...",
      "description": null,
      "deleted": null,
      "notifications": [{
          "id": 1
      }]
      "signingAlgorithm": "sha256",
      "user": {
          "username": "jane",
          "active": true,
          "email": "jane@example.com",
          "id": 2
      },
      "active": true,
      "domains": [{
          "sensitive": false,
          "id": 1090,
          "name": "*.test.example.net"
      }],
      "replaces": [],
      "replaced": [],
      "name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112",
      "roles": [{
          "id": 464,
          "description": "This is a google group based role created by Lemur",
          "name": "joe@example.com"
      }],
      "san": null
  }],
  "total": 1
}
Query Parameters:
 
  • sortBy – field to sort on
  • sortDir – asc or desc
  • page – int default is 1
  • filter – key value pair format is k;v
  • count – count number default is 10
Request Headers:
 
Status Codes:
mediatypes(resource_cls)
methods = ['GET']