certificates Package

exceptions Module

exception lemur.certificates.exceptions.InsufficientDomains

Bases: lemur.exceptions.LemurException

exception lemur.certificates.exceptions.InvalidCertificate

Bases: lemur.exceptions.LemurException

exception lemur.certificates.exceptions.MissingFiles(path)

Bases: lemur.exceptions.LemurException

exception lemur.certificates.exceptions.NoPersistanceFound

Bases: lemur.exceptions.LemurException

exception lemur.certificates.exceptions.UnableToCreateCSR

Bases: lemur.exceptions.LemurException

exception lemur.certificates.exceptions.UnableToCreatePrivateKey

Bases: lemur.exceptions.LemurException

exception lemur.certificates.exceptions.UnknownAuthority(authority)

Bases: lemur.exceptions.LemurException

models Module

class lemur.certificates.models.Certificate(body, private_key=None, chain=None)

Bases: flask_sqlalchemy.Model

active
authority_id
bits
body
chain
cn
date_created
deleted
description
destinations
domains
get_arn(account_number)

Generate a valid AWS IAM arn

:rtype : str :param account_number: :return:

id
is_expired
is_revoked
is_unused
issuer
name
not_after
not_before
notifications
owner
private_key
replaces
san
serial
signing_algorithm
sources
status
user_id
lemur.certificates.models.create_name(issuer, not_before, not_after, subject, san)

Create a name for our certificate. A naming standard is based on a series of templates. The name includes useful information such as Common Name, Validation dates, and Issuer.

Parameters:
  • san
  • subject
  • not_after
  • issuer
  • not_before

:rtype : str :return:

lemur.certificates.models.get_account_number(arn)

Extract the account number from an arn.

Parameters:arn – IAM SSL arn
Returns:account number associated with ARN
lemur.certificates.models.get_bitstrength(cert)

Calculates a certificates public key bit length.

Parameters:cert
Returns:Integer
lemur.certificates.models.get_cn(cert)

Attempts to get a sane common name from a given certificate.

Parameters:cert
Returns:Common name or None
lemur.certificates.models.get_domains(cert)

Attempts to get an domains listed in a certificate. If ‘subjectAltName’ extension is not available we simply return the common name.

Parameters:cert
Returns:List of domains
lemur.certificates.models.get_issuer(cert)

Gets a sane issuer from a given certificate.

Parameters:cert
Returns:Issuer
lemur.certificates.models.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.models.get_not_after(cert)

Gets the naive datetime of the certificates ‘not_after’ field. This field denotes the last date in time which the given certificate is valid.

Parameters:cert
Returns:Datetime
lemur.certificates.models.get_not_before(cert)

Gets the naive datetime of the certificates ‘not_before’ field. This field denotes the first date in time which the given certificate is valid.

Parameters:cert
Returns:Datetime
lemur.certificates.models.get_serial(cert)

Fetch the serial number from the certificate.

Parameters:cert
Returns:serial number
lemur.certificates.models.get_signing_algorithm(cert)
lemur.certificates.models.is_san(cert)

Determines if a given certificate is a SAN certificate. SAN certificates are simply certificates that cover multiple domains.

Parameters:cert
Returns:Bool
lemur.certificates.models.is_wildcard(cert)

Determines if certificate is a wildcard certificate.

Parameters:cert
Returns:Bool
lemur.certificates.models.protect_active(mapper, connection, target)

When a certificate has a replacement do not allow it to be marked as ‘active’

Parameters:
  • connection
  • mapper
  • target
Returns:

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

Attempt to upload the new 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’ it is then marked as in-active

Parameters:
  • target
  • value
  • initiator
Returns:

service Module

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

Creates a new certificate.

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_body)

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_body
Returns:
lemur.certificates.service.get(cert_id)

Retrieves certificate by it’s ID.

Parameters:cert_id
Returns:
lemur.certificates.service.get_all_certs()

Retrieves all certificates within Lemur.

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

Retrieves certificate by it’s Name.

Parameters:name
Returns:
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(issuer_options)

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

Parameters:issuer_options
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, owner, description, active, destinations, notifications, replaces)

Updates a certificate :param cert_id: :param owner: :param description: :param active: :param destinations: :param notifications: :param replaces: :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)
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(*args, **kwargs)
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

{
  "id": 1,
  "name": "cert1",
  "description": "this is cert1",
  "bits": 2048,
  "deleted": false,
  "issuer": "ExampeInc.",
  "serial": "123450",
  "chain": "-----Begin ...",
  "body": "-----Begin ...",
  "san": true,
  "owner": "bob@example.com",
  "active": true,
  "notBefore": "2015-06-05T17:09:39",
  "notAfter": "2015-06-10T17:09:39",
  "signingAlgorithm": "sha2",
  "cn": "example.com",
  "status": "unknown"
}
Request Headers:
 
Status Codes:
mediatypes(resource_cls)
methods = ['GET', 'PUT']
put(*args, **kwargs)
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

{
  "id": 1,
  "name": "cert1",
  "description": "this is cert1",
  "bits": 2048,
  "deleted": false,
  "issuer": "ExampeInc.",
  "serial": "123450",
  "chain": "-----Begin ...",
  "body": "-----Begin ...",
  "san": true,
  "owner": "jimbob@example.com",
  "active": false,
  "notBefore": "2015-06-05T17:09:39",
  "notAfter": "2015-06-10T17:09:39",
  "cn": "example.com",
  "status": "unknown",
}
Request Headers:
 
Status Codes:
class lemur.certificates.views.CertificatesList

Bases: lemur.auth.service.AuthenticatedResource

Defines the ‘certificates’ endpoint

endpoint = 'certificates'
get(*args, **kwargs)
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": [
      {
        "id": 1,
        "name": "cert1",
        "description": "this is cert1",
        "bits": 2048,
        "deleted": false,
        "issuer": "ExampeInc.",
        "serial": "123450",
        "chain": "-----Begin ...",
        "body": "-----Begin ...",
        "san": true,
        "owner": 'bob@example.com",
        "active": true,
        "notBefore": "2015-06-05T17:09:39",
        "notAfter": "2015-06-10T17:09:39",
        "cn": "example.com",
        "status": "unknown"
      }
    ]
  "total": 1
}
Query Parameters:
 
  • sortBy – field to sort on
  • sortDir – acs or desc
  • page – int. default is 1
  • filter – key value pair format is k;v
  • limit – limit number. default is 10
Request Headers:
 
Status Codes:
mediatypes(resource_cls)
methods = ['GET', 'POST']
post(*args, **kwargs)
POST /certificates

Creates a new certificate

Example request:

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

 {
   "country": "US",
   "state": "CA",
   "location": "A Place",
   "organization": "ExampleInc.",
   "organizationalUnit": "Operations",
   "owner": "bob@example.com",
   "description": "test",
   "selectedAuthority": "timetest2",
   "csr",
   "authority": {
       "body": "-----BEGIN...",
       "name": "timetest2",
       "chain": "",
       "notBefore": "2015-06-05T15:20:59",
       "active": true,
       "id": 50,
       "notAfter": "2015-06-17T15:21:08",
       "description": "dsfdsf"
   },
   "notifications": [
       {
         "description": "Default 30 day expiration notification",
         "notificationOptions": [
           {
             "name": "interval",
             "required": true,
             "value": 30,
             "helpMessage": "Number of days to be alert before expiration.",
             "validation": "^\d+$",
             "type": "int"
           },
           {
             "available": [
               "days",
               "weeks",
               "months"
             ],
             "name": "unit",
             "required": true,
             "value": "days",
             "helpMessage": "Interval unit",
             "validation": "",
             "type": "select"
           },
           {
             "name": "recipients",
             "required": true,
             "value": "bob@example.com",
             "helpMessage": "Comma delimited list of email addresses",
             "validation": "^([\w+-.%]+@[\w-.]+\.[A-Za-z]{2,4},?)+$",
               "type": "str"
             }
           ],
           "label": "DEFAULT_KGLISSON_30_DAY",
           "pluginName": "email-notification",
           "active": true,
           "id": 7
       }
   ],
   "extensions": {
       "basicConstraints": {},
       "keyUsage": {
           "isCritical": true,
           "useKeyEncipherment": true,
           "useDigitalSignature": true
       },
       "extendedKeyUsage": {
           "isCritical": true,
           "useServerAuthentication": true
       },
       "subjectKeyIdentifier": {
           "includeSKI": true
       },
       "subAltNames": {
           "names": []
       }
   },
   "commonName": "test",
   "validityStart": "2015-06-05T07:00:00.000Z",
   "validityEnd": "2015-06-16T07:00:00.000Z",
   "replacements": [
       {'id': 123}
   ]
}

Example response:

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

{
  "id": 1,
  "name": "cert1",
  "description": "this is cert1",
  "bits": 2048,
  "deleted": false,
  "issuer": "ExampeInc.",
  "serial": "123450",
  "chain": "-----Begin ...",
  "body": "-----Begin ...",
  "san": true,
  "owner": "jimbob@example.com",
  "active": false,
  "notBefore": "2015-06-05T17:09:39",
  "notAfter": "2015-06-10T17:09:39",
  "cn": "example.com",
  "status": "unknown"
}
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 – certiifcate common name
Request Headers:
 
Status Codes:
class lemur.certificates.views.CertificatesReplacementsList

Bases: lemur.auth.service.AuthenticatedResource

endpoint = 'replacements'
get(*args, **kwargs)
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

[{
  "id": 1,
  "name": "cert1",
  "description": "this is cert1",
  "bits": 2048,
  "deleted": false,
  "issuer": "ExampeInc.",
  "serial": "123450",
  "chain": "-----Begin ...",
  "body": "-----Begin ...",
  "san": true,
  "owner": "bob@example.com",
  "active": true,
  "notBefore": "2015-06-05T17:09:39",
  "notAfter": "2015-06-10T17:09:39",
  "signingAlgorithm": "sha2",
  "cn": "example.com",
  "status": "unknown"
}]
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(*args, **kwargs)
POST /certificates/upload

Upload a certificate

Example request:

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

{
   "owner": "joe@exmaple.com",
   "publicCert": "---Begin Public...",
   "intermediateCert": "---Begin Public...",
   "privateKey": "---Begin Private..."
   "destinations": [],
   "notifications": [],
   "replacements": [],
   "name": "cert1"
}

Example response:

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

{
   "id": 1,
   "name": "cert1",
   "description": "this is cert1",
   "bits": 2048,
   "deleted": false,
   "issuer": "ExampeInc.",
   "serial": "123450",
   "chain": "-----Begin ...",
   "body": "-----Begin ...",
   "san": true,
   "owner": "joe@example.com",
   "active": true,
   "notBefore": "2015-06-05T17:09:39",
   "notAfter": "2015-06-10T17:09:39",
   "signingAlgorithm": "sha2"
   "cn": "example.com",
   "status": "unknown"
}
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(*args, **kwargs)
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": [
      {
        "id": 1,
        "name": "cert1",
        "description": "this is cert1",
        "bits": 2048,
        "deleted": false,
        "issuer": "ExampeInc.",
        "serial": "123450",
        "chain": "-----Begin ...",
        "body": "-----Begin ...",
        "san": true,
        "owner": 'bob@example.com",
        "active": true,
        "notBefore": "2015-06-05T17:09:39",
        "notAfter": "2015-06-10T17:09:39",
        "signingAlgorithm": "sha2",
        "cn": "example.com",
        "status": "unknown"
      }
    ]
  "total": 1
}
Query Parameters:
 
  • sortBy – field to sort on
  • sortDir – acs or desc
  • page – int default is 1
  • filter – key value pair format is k;v
  • limit – limit number default is 10
Request Headers:
 
Status Codes:
mediatypes(resource_cls)
methods = ['GET']
lemur.certificates.views.check_sensitive_domains(domains)

Determines if any certificates in the given certificate are marked as sensitive :param domains: :return:

lemur.certificates.views.get_domains_from_options(options)

Retrive all domains from certificate options :param options: :return:

lemur.certificates.views.pem_str(value, name)

Used to validate that the given string is a PEM formatted string

Parameters:
  • value
  • name
Returns:

raise ValueError:
 

lemur.certificates.views.private_key_str(value, name)

User to validate that a given string is a RSA private key

Parameters:
  • value
  • name
Returns:

raise ValueError:
 

lemur.certificates.views.valid_authority(authority_options)

Defends against invalid authorities

Parameters:authority_options
Returns:
raise ValueError: