class CertUtilsTest(TestCase): """ Tests to exercise splice.common.certs.CertUtils """ def setUp(self): super(CertUtilsTest, self).setUp() # Test Certificate Data # invalid cert, signed by a CA other than 'root_ca_pem' self.invalid_key_path = os.path.join(TEST_DATA_DIR, 'invalid_cert', 'invalid.key') self.invalid_identity_cert_path = os.path.join(TEST_DATA_DIR, "invalid_cert", "invalid.cert") self.invalid_identity_cert_pem = open(self.invalid_identity_cert_path, "r").read() # a valid cert, signed by the below CA, 'root_ca_pem' self.valid_identity_cert_path = os.path.join(TEST_DATA_DIR, "valid_cert", "valid.cert") self.valid_identity_cert_pem = open(self.valid_identity_cert_path, "r").read() # CA self.root_ca_crt_path = os.path.join(TEST_DATA_DIR, 'ca', 'ca.crt') self.root_ca_key_path = os.path.join(TEST_DATA_DIR, 'ca', 'ca.key') self.root_ca_srl_path = os.path.join(TEST_DATA_DIR, 'ca', 'ca.srl') self.root_ca_crt = open(self.root_ca_crt_path).read() self.root_ca_key = open(self.root_ca_key_path).read() self.root_ca_pem = open(self.root_ca_srl_path).read() self.root_ca_pem = self.root_ca_crt + self.root_ca_key self.expected_valid_identity_uuid = "fb647f68-aa01-4171-b62b-35c2984a5328" self.cert_utils = CertUtils() def tearDown(self): super(CertUtilsTest, self).tearDown() def test_validate_certificate_pem_valid(self): self.assertTrue(self.cert_utils.validate_certificate( self.valid_identity_cert_pem, self.root_ca_pem)) def test_validate_certificate_pem_invalid(self): self.assertFalse(self.cert_utils.validate_certificate( self.invalid_identity_cert_pem, self.root_ca_pem)) def test_get_subject_pieces(self): pieces = self.cert_utils.get_subject_pieces(self.valid_identity_cert_pem) self.assertTrue(pieces["CN"]) self.assertEquals(pieces["CN"], self.expected_valid_identity_uuid) def test_get_subject_pieces_with_filepath(self): caught = False try: pieces = self.cert_utils.get_subject_pieces(self.valid_identity_cert_path) except CertificateParseException, e: caught = True self.assertTrue(caught)
def __init__(self, verification_ca): """ @param verification_ca: CA to be used in verifying client certificates were signed correctly. This is the actual string PEM encoded certificate, not a path to a file @type verification_ca: str, contents in PEM encoded format @return: """ super(X509CertificateAuthentication, self).__init__(require_active=False) self.verification_ca = verification_ca self.cert_utils = CertUtils()
def get_identifier_from_cert(x509_cert): """ Returns the 'CN' and 'O' pieces of the passed in Certificate if available @param x509_cert: @return: (str, str) """ cn = None o = None cert_utils = CertUtils() try: subj_pieces = cert_utils.get_subject_pieces(x509_cert) except CertificateParseException: return None, None if subj_pieces: if subj_pieces.has_key("CN"): cn = subj_pieces["CN"] if subj_pieces.has_key("O"): o = subj_pieces["O"] return (cn, o)
def pre_save(cls, sender, document, **kwargs): """ pre_save signal hook. """ # Verify a UUID is always set before we save. If one is not, generate a # new one and set it. if not document.uuid: document.uuid = cls._generate_uuid() # Generate a certificate and private key for this RHIC. if not document.public_cert: # Fields are validated in save(), but we need to validate # account_id was set here since we need to use it in the X509 # request. if not document.account_id: raise ValidationError('account_id is not set') cu = CertUtils() ca_crt_path = config.CONFIG.get('security', 'rhic_ca_cert') ca_key_path = config.CONFIG.get('security', 'rhic_ca_key') sign_days = config.CONFIG.get('security', 'sign_days') public_cert, private_key = cu.generate( ca_crt_path, ca_key_path, sign_days, dict(CN=str(document.uuid), O=document.account_id)) document.public_cert.new_file() document.public_cert.write(public_cert) document.public_cert.close() # private key is saved as an attribute on the document, but it is # not a field. It will not be kept after this instance is GC'd. document.private_key = private_key # Created Date if not document.created_date: document.created_date = datetime.now(tzutc()) # Modified Date. # This will get updated whether or not anything changed. I guess # that's ok. document.modified_date = datetime.now(tzutc())
class X509CertificateAuthentication(Authentication): """ Class will perform authentication based on the X509 certificate used to form the SSL connection. The certificate will be found from the context of the request. If the certificate has been signed by the configured CA and it is valid the request will be authenticated. """ def __init__(self, verification_ca): """ @param verification_ca: CA to be used in verifying client certificates were signed correctly. This is the actual string PEM encoded certificate, not a path to a file @type verification_ca: str, contents in PEM encoded format @return: """ super(X509CertificateAuthentication, self).__init__(require_active=False) self.verification_ca = verification_ca self.cert_utils = CertUtils() def is_authenticated(self, request, **kwargs): """ Verify that the SSL client certificate used to form this SSL Connection has been signed by the configured CA. @param request: @type django.http.HttpRequest @param kwargs: @return: """ x509_cert_from_request = get_client_cert_from_request(request) if x509_cert_from_request: if self.cert_utils.validate_certificate(x509_cert_from_request, self.verification_ca): return True return HttpResponse( content="Unable to verify SSL client's identity certificate was signed by configured CA", status=httplib.UNAUTHORIZED) # Optional but recommended def get_identifier(self, request): """ Return the UUID and Account number embedded in the certificate @param request: @return: (CN, O) corresponds to CN being the UUID of the certificate and O being the account number """ x509_cert_from_request = get_client_cert_from_request(request) return get_identifier_from_cert(x509_cert_from_request)
def setUp(self): super(CertUtilsTest, self).setUp() # Test Certificate Data # invalid cert, signed by a CA other than 'root_ca_pem' self.invalid_key_path = os.path.join(TEST_DATA_DIR, 'invalid_cert', 'invalid.key') self.invalid_identity_cert_path = os.path.join(TEST_DATA_DIR, "invalid_cert", "invalid.cert") self.invalid_identity_cert_pem = open(self.invalid_identity_cert_path, "r").read() # a valid cert, signed by the below CA, 'root_ca_pem' self.valid_identity_cert_path = os.path.join(TEST_DATA_DIR, "valid_cert", "valid.cert") self.valid_identity_cert_pem = open(self.valid_identity_cert_path, "r").read() # CA self.root_ca_crt_path = os.path.join(TEST_DATA_DIR, 'ca', 'ca.crt') self.root_ca_key_path = os.path.join(TEST_DATA_DIR, 'ca', 'ca.key') self.root_ca_srl_path = os.path.join(TEST_DATA_DIR, 'ca', 'ca.srl') self.root_ca_crt = open(self.root_ca_crt_path).read() self.root_ca_key = open(self.root_ca_key_path).read() self.root_ca_pem = open(self.root_ca_srl_path).read() self.root_ca_pem = self.root_ca_crt + self.root_ca_key self.expected_valid_identity_uuid = "fb647f68-aa01-4171-b62b-35c2984a5328" self.cert_utils = CertUtils()