Add CSR to certificiates

Add csr column to certificates field, as pending certificates have
exposed the CSR already.  This is required as generating CSR from
existing certificate is will not include SANs due to OpenSSL bug:
https://github.com/openssl/openssl/issues/6481

Change-Id: I9ea86c4f87067ee6d791d77dc1cce8f469cb2a22
This commit is contained in:
James Chuong 2018-10-11 16:29:35 -07:00
parent 9d7ad28ca1
commit 75069cd52a
7 changed files with 41 additions and 2 deletions

View File

@ -87,6 +87,7 @@ class Certificate(db.Model):
body = Column(Text(), nullable=False) body = Column(Text(), nullable=False)
chain = Column(Text()) chain = Column(Text())
csr = Column(Text())
private_key = Column(Vault) private_key = Column(Vault)
issuer = Column(String(128)) issuer = Column(String(128))
@ -158,6 +159,9 @@ class Certificate(db.Model):
if kwargs.get('chain'): if kwargs.get('chain'):
self.chain = kwargs['chain'].strip() self.chain = kwargs['chain'].strip()
if kwargs.get('csr'):
self.csr = kwargs['csr'].strip()
self.notify = kwargs.get('notify', True) self.notify = kwargs.get('notify', True)
self.destinations = kwargs.get('destinations', []) self.destinations = kwargs.get('destinations', [])
self.notifications = kwargs.get('notifications', []) self.notifications = kwargs.get('notifications', [])

View File

@ -74,7 +74,7 @@ class CertificateInputSchema(CertificateCreationSchema):
roles = fields.Nested(AssociatedRoleSchema, missing=[], many=True) roles = fields.Nested(AssociatedRoleSchema, missing=[], many=True)
dns_provider = fields.Nested(AssociatedDnsProviderSchema, missing=None, allow_none=True, required=False) dns_provider = fields.Nested(AssociatedDnsProviderSchema, missing=None, allow_none=True, required=False)
csr = fields.String(validate=validators.csr) csr = fields.String(allow_none=True, validate=validators.csr)
key_type = fields.String( key_type = fields.String(
validate=validate.OneOf(CERTIFICATE_KEY_TYPES), validate=validate.OneOf(CERTIFICATE_KEY_TYPES),
@ -156,6 +156,7 @@ class CertificateNestedOutputSchema(LemurOutputSchema):
bits = fields.Integer() bits = fields.Integer()
body = fields.String() body = fields.String()
chain = fields.String() chain = fields.String()
csr = fields.String()
active = fields.Boolean() active = fields.Boolean()
rotation = fields.Boolean() rotation = fields.Boolean()
@ -187,6 +188,7 @@ class CertificateOutputSchema(LemurOutputSchema):
bits = fields.Integer() bits = fields.Integer()
body = fields.String() body = fields.String()
chain = fields.String() chain = fields.String()
csr = fields.String()
deleted = fields.Boolean(default=False) deleted = fields.Boolean(default=False)
description = fields.String() description = fields.String()
issuer = fields.String() issuer = fields.String()

View File

@ -72,6 +72,7 @@ class CertificatesList(AuthenticatedResource):
"status": null, "status": null,
"cn": "*.test.example.net", "cn": "*.test.example.net",
"chain": "", "chain": "",
"csr": "-----BEGIN CERTIFICATE REQUEST-----"
"authority": { "authority": {
"active": true, "active": true,
"owner": "secure@example.com", "owner": "secure@example.com",
@ -490,6 +491,7 @@ class Certificates(AuthenticatedResource):
"status": null, "status": null,
"cn": "*.test.example.net", "cn": "*.test.example.net",
"chain": "", "chain": "",
"csr": "-----BEGIN CERTIFICATE REQUEST-----"
"authority": { "authority": {
"active": true, "active": true,
"owner": "secure@example.com", "owner": "secure@example.com",
@ -694,6 +696,7 @@ class NotificationCertificatesList(AuthenticatedResource):
"status": null, "status": null,
"cn": "*.test.example.net", "cn": "*.test.example.net",
"chain": "", "chain": "",
"csr": "-----BEGIN CERTIFICATE REQUEST-----"
"authority": { "authority": {
"active": true, "active": true,
"owner": "secure@example.com", "owner": "secure@example.com",
@ -802,6 +805,7 @@ class CertificatesReplacementsList(AuthenticatedResource):
"status": null, "status": null,
"cn": "*.test.example.net", "cn": "*.test.example.net",
"chain": "", "chain": "",
"csr": "-----BEGIN CERTIFICATE REQUEST-----",
"authority": { "authority": {
"active": true, "active": true,
"owner": "secure@example.com", "owner": "secure@example.com",

View File

@ -0,0 +1,21 @@
"""Add csr to certificates table
Revision ID: 7ead443ba911
Revises: 6006c79b6011
Create Date: 2018-10-21 22:06:23.056906
"""
# revision identifiers, used by Alembic.
revision = '7ead443ba911'
down_revision = '6006c79b6011'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.add_column('certificates', sa.Column('csr', sa.TEXT(), nullable=True))
def downgrade():
op.drop_column('certificates', 'csr')

View File

@ -215,6 +215,7 @@ angular.module('lemur')
CertificateApi.get(editId).then(function (certificate) { CertificateApi.get(editId).then(function (certificate) {
$scope.certificate = certificate; $scope.certificate = certificate;
$scope.certificate.name = ''; // we should prefer the generated name $scope.certificate.name = ''; // we should prefer the generated name
$scope.certificate.csr = null; // should not clone CSR in case other settings are changed in clone
$scope.certificate.validityStart = null; $scope.certificate.validityStart = null;
$scope.certificate.validityEnd = null; $scope.certificate.validityEnd = null;
CertificateService.getDefaults($scope.certificate); CertificateService.getDefaults($scope.certificate);

View File

@ -182,6 +182,13 @@
</uib-tab-heading> </uib-tab-heading>
<pre style="width: 100%">{{ certificate.chain }}</pre> <pre style="width: 100%">{{ certificate.chain }}</pre>
</uib-tab> </uib-tab>
<uib-tab>
<uib-tab-heading>
CSR
<i class="glyphicon glyphicon-copy" style="cursor: pointer" clipboard text="certificate.csr"></i>
</uib-tab-heading>
<pre style="width: 100%">{{ certificate.csr }}</pre>
</uib-tab>
<uib-tab> <uib-tab>
<uib-tab-heading> <uib-tab-heading>
Public Certificate Public Certificate

View File

@ -48,7 +48,7 @@ def test_get_certificate_primitives(certificate):
with freeze_time(datetime.date(year=2016, month=10, day=30)): with freeze_time(datetime.date(year=2016, month=10, day=30)):
primitives = get_certificate_primitives(certificate) primitives = get_certificate_primitives(certificate)
assert len(primitives) == 25 assert len(primitives) == 26
def test_certificate_output_schema(session, certificate, issuer_plugin): def test_certificate_output_schema(session, certificate, issuer_plugin):