Ensuring that acme and cryptography respect different key types (#554)

This commit is contained in:
kevgliss 2016-12-02 10:54:18 -08:00 committed by GitHub
parent 0f5e925a1a
commit 7f823a04cd
8 changed files with 89 additions and 55 deletions

View File

@ -13,12 +13,12 @@ from flask import current_app
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from lemur import database
from lemur.extensions import metrics
from lemur.plugins.base import plugins
from lemur.certificates.models import Certificate
from lemur.common.utils import generate_private_key
from lemur.destinations.models import Destination
from lemur.notifications.models import Notification
@ -317,13 +317,7 @@ def create_csr(**csr_config):
:param csr_config:
"""
if 'RSA' in csr_config.get('key_type'):
key_size = int(csr_config.get('key_type')[3:])
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=key_size,
backend=default_backend()
)
private_key = generate_private_key(csr_config.get('key_type'))
# TODO When we figure out a better way to validate these options they should be parsed as str
builder = x509.CertificateSigningRequestBuilder()

View File

@ -11,6 +11,7 @@ import random
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from flask_restful.reqparse import RequestParser
@ -37,12 +38,44 @@ def get_psuedo_random_string():
def parse_certificate(body):
"""
Helper function that parses a PEM certificate.
:param body:
:return:
"""
if isinstance(body, str):
body = body.encode('utf-8')
return x509.load_pem_x509_certificate(body, default_backend())
def generate_private_key(key_type):
"""
Generates a new private key based on key_type.
Valid key types: RSA2048, RSA4096
:param key_type:
:return:
"""
valid_key_types = ['RSA2048', 'RSA4096']
if key_type not in valid_key_types:
raise Exception("Invalid key type: {key_type}. Supported key types: {choices}".format(
key_type=key_type,
choices=",".join(valid_key_types)
))
if 'RSA' in key_type:
key_size = int(key_type[3:])
return rsa.generate_private_key(
public_exponent=65537,
key_size=key_size,
backend=default_backend()
)
def is_weekend(date):
"""
Determines if a given date is on a weekend.

View File

@ -16,9 +16,10 @@ from acme.client import Client
from acme import jose
from acme import messages
from lemur.common.utils import generate_private_key
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
import OpenSSL.crypto
@ -101,12 +102,6 @@ def request_certificate(acme_client, authorizations, csr):
return pem_certificate, pem_certificate_chain
def generate_rsa_private_key():
return rsa.generate_private_key(
public_exponent=65537, key_size=2048, backend=default_backend()
)
def setup_acme_client():
key = current_app.config.get('ACME_PRIVATE_KEY').strip()
acme_email = current_app.config.get('ACME_EMAIL')
@ -127,7 +122,7 @@ def acme_client_for_private_key(acme_directory_url, private_key):
def register(email):
private_key = generate_rsa_private_key()
private_key = generate_private_key('RSA2048')
acme_client = acme_client_for_private_key(current_app.config('ACME_DIRECTORY_URL'), private_key)
registration = acme_client.register(

View File

@ -13,19 +13,15 @@ from flask import current_app
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from lemur.plugins.bases import IssuerPlugin
from lemur.plugins import lemur_cryptography as cryptography_issuer
from lemur.common.utils import generate_private_key
def build_root_certificate(options):
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
private_key = generate_private_key(options.get('key_type'))
subject = issuer = x509.Name([
x509.NameAttribute(x509.OID_COUNTRY_NAME, options['country']),

View File

@ -0,0 +1,36 @@
import arrow
def test_build_root_certificate():
from lemur.plugins.lemur_cryptography.plugin import build_root_certificate
options = {
'key_type': 'RSA2048',
'country': 'US',
'state': 'CA',
'location': 'Example place',
'organization': 'Example, Inc.',
'organizational_unit': 'Example Unit',
'common_name': 'Example ROOT',
'validity_start': arrow.get('2016-12-01').datetime,
'validity_end': arrow.get('2016-12-02').datetime,
'first_serial': 1
}
cert_pem, private_key_pem = build_root_certificate(options)
assert cert_pem
assert private_key_pem
def test_issue_certificate(authority):
from lemur.tests.vectors import CSR_STR
from lemur.plugins.lemur_cryptography.plugin import issue_certificate
options = {
'authority': authority,
'validity_start': arrow.get('2016-12-01').datetime,
'validity_end': arrow.get('2016-12-02').datetime
}
cert = issue_certificate(CSR_STR, options)
assert cert

11
lemur/tests/test_utils.py Normal file
View File

@ -0,0 +1,11 @@
import pytest
def test_generate_private_key():
from lemur.common.utils import generate_private_key
assert generate_private_key('RSA2048')
assert generate_private_key('RSA4096')
with pytest.raises(Exception):
generate_private_key('ECC')

View File

@ -269,34 +269,3 @@ zm3Cn4Ul8DO26w9QS4fmZjmnPOZFXYMWoOR6osHzb62PWQ8FBMqXcdToBV2Q9Iw4
PiFAxlc0tVjlLqQ=
-----END CERTIFICATE REQUEST-----
"""
CSR_PEM_STR = """
-----BEGIN RSA PRIVATE KEY-----
MIIEpgIBAAKCAQEAzZ2PgKflffhIPzwLXe26tuw+7Q72y9dAMrDVEms8u4Cch3yc
hN6Il5tvM4xTc0UN+aobAhaVoPDN+haXT/XyBRvbFV1f8nvmDQZGdmkyYkZ2xK2X
MvKnPtjEXdiShPYNKSEqfYQBHhDy08EqBqn+VajmgXoQai+TijVK+yQMVUyB9aFV
PO8P+sYP1rFIsj6OPVl8Rf9w2TT9VDk2In38SIgEYU2/RLZV6beYjpYnN8P7wV+q
rB/vlySLrNlhPgAZQFVEEwr3Om4KbuM43PJ5ZtwpapACnMZ9rmxHXq/hYYWoDGBr
G2BvvyFqymDektAYxNurTTIjpZiHm4poxHRaZwIDAQABAoIBAQCm5MwVBrKtI/ko
colbbVoPngSZkHrcC9SNEKFyON7r5sGm64t0AdjnDgAd3DnkJ1nnm54efMxo/OyD
oRCik6QlZ23VkpwNi2m4iq5o8Iw33rAKhkhizzjXN0V0UxTinYEjMEt348ywZdtj
67c7/4F0cArhb32hYwqjtQwuex0Tofb37Aj5rNPv1n8ytbhz1vriAVZHZEcjdjdn
CSVeblufORQKRzK3wW5nRN721b9gSvEJHfHeNpXQO9X8Yl5tn7UxjoQWXLZK+khv
pawN8BFt7lVLkQR14Nq7bKwuJ6KR1ig698a1Ii8Luyh2BgfIc25ryuzs8fFCioKi
TK/nzMQ5AoGBAPxtbTrkTTNQ03hnfefRVKGwNHPqLhIQpI99FC4yLYYHsUwFmMVR
ccg4aqNUtI0zn1snKC58NICxIPP9c0NuHqBuNuwhuRPINfQfjg/aOpE2QycZcew1
BQxXH5d3zXWKLpN15kIS2s18/MpNgTFx2Z0EGqLezDXs6JaPJkqg04glAoGBANCG
h106B9hbuTPYCAlTwvaoWnbaxLmtlWzRpqYBuiiBPGvLc545faXkJKb5/zd002kK
wblGrPtCnhTvCtHbTg/KuR/R8EsAriPhpWK+N4hCADJ8SLOxMU5S9O24FEK50ltN
Q84LS2Wo9fWXQhojiBrctn/ws5ngRCfUbhQeA3ybAoGBAOW7vWaUswIZ9GwnXDon
lGuXDxXTslw0k2AXyM8GUdIinCSBD3m9Vt2PItZFWBEOQ2DVMUelOK9LBZ+pMkbT
KMJ/rDKZunQbiacFNOiOhzDzfohOKxV7Z33EqPbUTMRFn4ALFCVcPZA4yWRgx0y1
vgSd4JQMSzRkyYWFAKd42SuVAoGBAIG84aWQQGdNkin+Y+mhsrCSSE6giDtaE5jz
y7KHapJe7f/HQnUUIee/zUoSSsbvKcW2CpfCsEdXyFEP9PRidOwAXjO9A7s2fiIW
9zY7UQO2xLakevtJ6HppxLfOitSFFqr1pJUik9N5TyZw6JCowLqtzeJGGQhI7z60
vZRIpDS3AoGBAPYJgNB7EcWj5U39ol+8cofG1kPauoEaildTur5ftzyzjy4DXrOW
sfU/xhUp6EKLGSXEPqeXAWR6ARf1F4U9Ozp6KA93lGSrSY561jKoqhxxOXAf5il2
p7Fzh2CckUeiGd5el+h2WUCOcgtlPlfRyV/Mlvx1H0gFieGucXTP23Ox
-----END RSA PRIVATE KEY-----
"""

View File

@ -1,4 +1,4 @@
[pytest]
[tool:pytest]
python_files=test*.py
addopts=--tb=native -p no:doctest
norecursedirs=bin dist docs htmlcov script hooks node_modules .* {args}