diff --git a/server-ca/CSR.py b/server-ca/CSR.py index 1d7a8d3b9..9b866b328 100644 --- a/server-ca/CSR.py +++ b/server-ca/CSR.py @@ -2,7 +2,7 @@ # use OpenSSL to provide CSR-related operations -import subprocess, tempfile, re, pkcs10 +import subprocess, tempfile, re import M2Crypto # we can use tempfile.NamedTemporaryFile() to get tempfiles # to pass to OpenSSL subprocesses. @@ -99,8 +99,23 @@ def subject_names(csr): @return: array of strings of subject (CN) and subject alternative names (x509 extension) """ + names = [] + names.append(cn(csr)) - return pkcs10.subject_names(csr) + req = M2Crypto.X509.load_request_string(csr) + for ext in req.get_extensions(): # requires M3Crypto modification + if ext.get_name() == 'subjectAltName': # TODO: can we trust this? + + # 'DNS:example.com, DNS:www.example.com' + sans = ext.get_value().split(',') + for san in sans: + san = san.strip() # remove leading space + if san.startswith('DNS:'): + names.append(san[len('DNS:'):]) + + # Don't exit loop - support multiple SAN extensions?? + + return names def can_sign(name): """Does this CA's policy forbid signing this name via Chocolate DV?""" diff --git a/server-ca/Makefile b/server-ca/Makefile index e220d2239..4ceba3070 100644 --- a/server-ca/Makefile +++ b/server-ca/Makefile @@ -1,5 +1,5 @@ -deploy: chocolate_protocol_pb2.py chocolate.py CSR.py pkcs10.py daemon.py CA.sh - scp chocolate_protocol.proto chocolate.py CSR.py pkcs10.py daemon.py CA.sh ${CHOCOLATESERVER}: +deploy: chocolate_protocol_pb2.py chocolate.py CSR.py daemon.py CA.sh + scp chocolate_protocol.proto chocolate.py CSR.py daemon.py CA.sh ${CHOCOLATESERVER}: ssh ${CHOCOLATESERVER} protoc chocolate_protocol.proto --python_out=. rsync -av --delete sni_challenge demoCA ${CHOCOLATESERVER}: ssh ${CHOCOLATESERVER} make -C sni_challenge clean all diff --git a/server-ca/pkcs10.py b/server-ca/pkcs10.py deleted file mode 100644 index 7bbca537e..000000000 --- a/server-ca/pkcs10.py +++ /dev/null @@ -1,83 +0,0 @@ -# Authors: -# Rob Crittenden -# -# Copyright (C) 2010 Red Hat -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; version 2 only -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -import os -import sys -import base64 -import nss.nss as nss - -def get_subjectaltname(request): - """ - Given a CSR return the subjectaltname value, if any. - - The return value is a tuple of strings or None - """ - for extension in request.extensions: - if extension.oid_tag == nss.SEC_OID_X509_SUBJECT_ALT_NAME: - return nss.x509_alt_name(extension.value) - return None - -def get_subject(request): - """ - Given a CSR return the subject value. - - This returns an nss.DN object. - """ - return request.subject - -def strip_header(csr): - """ - Remove the header and footer from a CSR. - """ - headerlen = 40 - s = csr.find("-----BEGIN NEW CERTIFICATE REQUEST-----") - if s == -1: - headerlen = 36 - s = csr.find("-----BEGIN CERTIFICATE REQUEST-----") - if s >= 0: - e = csr.find("-----END") - csr = csr[s+headerlen:e] - - return csr - -def load_certificate_request(csr): - """ - Given a base64-encoded certificate request, with or without the - header/footer, return a request object. - """ - csr = strip_header(csr) - - substrate = base64.b64decode(csr) - - # A fail-safe so we can always read a CSR. python-nss/NSS will segfault - # otherwise - if not nss.nss_is_initialized(): - nss.nss_init_nodb() - - return nss.CertificateRequest(substrate) - -def subject_names(csr): - if not nss.nss_is_initialized(): - nss.nss_init_nodb() - - csr = load_certificate_request(csr) - - sans = get_subjectaltname(csr) - if not sans: sans = [] - return [x.split("=")[1] for x in [f for f in str(get_subject(csr)).split(",") if f[:3] == "CN="]] + list(sans)