summaryrefslogtreecommitdiff
path: root/cpp/src/IceSSL/DefaultCertificateVerifier.cpp
blob: a38e701d8a09aa2062ee51c71cc7647c0e3c157e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// **********************************************************************
//
// Copyright (c) 2002
// Mutable Realms, Inc.
// Huntsville, AL, USA
//
// All Rights Reserved
//
// **********************************************************************

#include <Ice/Logger.h>
#include <IceSSL/OpenSSL.h>
#include <IceSSL/DefaultCertificateVerifier.h>
#include <IceSSL/OpenSSLUtils.h>
#include <IceSSL/TraceLevels.h>

#include <ostream>

using namespace std;

IceSSL::OpenSSL::DefaultCertificateVerifier::DefaultCertificateVerifier(const IceSSL::TraceLevelsPtr& traceLevels,
                                                                        const Ice::LoggerPtr& logger) :
    _traceLevels(traceLevels),
    _logger(logger)
{
}

int
IceSSL::OpenSSL::DefaultCertificateVerifier::verify(int preVerifyOkay, X509_STORE_CTX* x509StoreContext,
                                                    SSL* sslConnection)
{
    //
    // Default verification steps.
    //

    int verifyError = X509_STORE_CTX_get_error(x509StoreContext);
    int errorDepth = X509_STORE_CTX_get_error_depth(x509StoreContext);
    int verifyDepth = SSL_get_verify_depth(sslConnection);

    // A verify error has been encountered.
    if(verifyError != X509_V_OK)
    {
        // We have a limited verify depth, and we have had to delve too deeply
        // into the certificate chain to find an acceptable root certificate.
        if((verifyDepth != -1) && (verifyDepth < errorDepth))
        {
            verifyError = X509_V_ERR_CERT_CHAIN_TOO_LONG;
            X509_STORE_CTX_set_error(x509StoreContext, verifyError);
        }

        // If we have ANY errors, we bail out.
        preVerifyOkay = 0;
    }

    // Only if ICE_PROTOCOL level logging is on do we worry about this.
    if(_traceLevels->security >= IceSSL::SECURITY_PROTOCOL)
    {
        char buf[256];

        X509* err_cert = X509_STORE_CTX_get_current_cert(x509StoreContext);

        X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));

        ostringstream outStringStream;

        outStringStream << "depth = " << dec << errorDepth << ":" << buf << std::endl;

        if(!preVerifyOkay)
        {
            outStringStream << "verify error: num = " << verifyError << " : " 
			    << X509_verify_cert_error_string(verifyError) << endl;

        }

        switch(verifyError)
        {
            case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
            {
                X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, sizeof(buf));
                outStringStream << "issuer = " << buf << endl;
                break;
            }

            case X509_V_ERR_CERT_NOT_YET_VALID:
            case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
            {
                outStringStream << "notBefore = " << getASN1time(X509_get_notBefore(err_cert)) << endl;
                break;
            }

            case X509_V_ERR_CERT_HAS_EXPIRED:
            case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
            {
                outStringStream << "notAfter = " << getASN1time(X509_get_notAfter(err_cert)) << endl;
                break;
            }
        }

        outStringStream << "verify return = " << preVerifyOkay << endl;

        _logger->trace(_traceLevels->securityCat, outStringStream.str());
    }

    return preVerifyOkay;
}