Пример #1
0
int
tls_verify_peer_cert(SSLContext *ctx)
{
    int err = 0;
    OSStatus st;

    /* Note: A verification failure here does not cause the function to return an error.
       This will allow the handshake to continue, coreTLS will eventually returns an error,
       after sending the appropriate alert messages, based on the trust value set with the
       call to tls_handshake_set_peer_trust(). In some case a verification failure here is 
       normal, for example if there is no cert (eg: PSK and Anon DH ciphersuites) */

    st = sslVerifyCertChain(ctx);
    tls_handshake_trust_t trust;
    switch (st) {
        case errSecSuccess:
            trust = tls_handshake_trust_ok;
            break;
        case errSSLUnknownRootCert:
        case errSSLNoRootCert:
            trust = tls_handshake_trust_unknown_root;
            break;
        case errSSLCertExpired:
        case errSSLCertNotYetValid:
            trust = tls_handshake_trust_cert_expired;
            break;
        case errSSLXCertChainInvalid:
        default:
            trust = tls_handshake_trust_cert_invalid;
            break;
    }

    tls_handshake_set_peer_trust(ctx->hdsk, trust);

    /* Now that trust has been (possibly) evaluated,
       we check if we need to break out of the handshake */
    if(ctx->protocolSide == kSSLServerSide) {
        /*
         * Schedule return to the caller to verify the client's identity.
         * This will return even if there was no client cert sent.
         */
        if (ctx->breakOnClientAuth) {
            err = errSSLClientAuthCompleted;
        }
    } else if(ctx->peerSecTrust) {
        /*
         * Schedule return to the caller to verify the server's identity.
         * This will only return if a server cert was sent. In other cases
         * such as PSK and AnonDH, we don't want to break out of the handshake.
         */
        if (ctx->breakOnServerAuth) {
            err = errSSLServerAuthCompleted;
        }
    }

    return err;
}
Пример #2
0
int
tls_verify_peer_cert(SSLContext *ctx)
{
    int err;
    const SSLCertificate *certs;

    certs = tls_handshake_get_peer_certificates(ctx->hdsk);
    CFReleaseNull(ctx->peerCert);
    ctx->peerCert = tls_get_peer_certs(certs);

    err = sslVerifyCertChain(ctx, ctx->peerCert, true);
    tls_handshake_trust_t trust;
    switch (err) {
    case errSecSuccess:
        trust = tls_handshake_trust_ok;
        break;
    case errSSLUnknownRootCert:
    case errSSLNoRootCert:
        trust = tls_handshake_trust_unknown_root;
        break;
    case errSSLCertExpired:
    case errSSLCertNotYetValid:
        trust = tls_handshake_trust_cert_expired;
        break;
    case errSSLXCertChainInvalid:
    default:
        trust = tls_handshake_trust_cert_invalid;
        break;
    }

    tls_handshake_set_peer_trust(ctx->hdsk, trust);

    if(err)
        goto out;

    /* Set the public key, only if we have certs.
       We don't return an handshake error if there is no cert,
       The fact that there is no cert should be reflected in the
       trust results above, or will be handle when the application
       does its own trust evaluation. */
    if(certs) {
        require_noerr(err=tls_set_peer_pubkey(ctx->hdsk, certs), out);
    }

    /* Now that cert verification is done, update context state */
    /* (this code was formerly in SSLProcessHandshakeMessage, */
    /* directly after the return from SSLProcessCertificate) */
    if(ctx->protocolSide == kSSLServerSide) {
        /*
         * Schedule return to the caller to verify the client's identity.
         * Note that an error during processing will cause early
         * termination of the handshake.
         */
        if (ctx->breakOnClientAuth) {
            err = errSSLClientAuthCompleted;
        }
    } else {
        /*
         * Schedule return to the caller to verify the server's identity.
         * Note that an error during processing will cause early
         * termination of the handshake.
         */
        if (ctx->breakOnServerAuth) {
            err = errSSLServerAuthCompleted;
        }
    }

out:

    return err;
}