예제 #1
0
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)
예제 #2
0
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)