Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/security/nss/lib/ssl/authcert.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * NSS utility functions
3
 *
4
 * This Source Code Form is subject to the terms of the Mozilla Public
5
 * License, v. 2.0. If a copy of the MPL was not distributed with this
6
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8
#include <stdio.h>
9
#include <string.h>
10
#include "prerror.h"
11
#include "secitem.h"
12
#include "prnetdb.h"
13
#include "cert.h"
14
#include "nspr.h"
15
#include "secder.h"
16
#include "keyhi.h"
17
#include "nss.h"
18
#include "ssl.h"
19
#include "pk11func.h" /* for PK11_ function calls */
20
#include "sslimpl.h"
21
22
/*
23
 * This callback used by SSL to pull client sertificate upon
24
 * server request
25
 */
26
SECStatus
27
NSS_GetClientAuthData(void *arg,
28
                      PRFileDesc *socket,
29
                      struct CERTDistNamesStr *caNames,
30
                      struct CERTCertificateStr **pRetCert,
31
                      struct SECKEYPrivateKeyStr **pRetKey)
32
0
{
33
0
    CERTCertificate *cert = NULL;
34
0
    SECKEYPrivateKey *privkey = NULL;
35
0
    char *chosenNickName = (char *)arg; /* CONST */
36
0
    void *proto_win = NULL;
37
0
    SECStatus rv = SECFailure;
38
0
39
0
    proto_win = SSL_RevealPinArg(socket);
40
0
41
0
    if (chosenNickName) {
42
0
        cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
43
0
                                        chosenNickName, certUsageSSLClient,
44
0
                                        PR_FALSE, proto_win);
45
0
        if (cert) {
46
0
            privkey = PK11_FindKeyByAnyCert(cert, proto_win);
47
0
            if (privkey) {
48
0
                rv = SECSuccess;
49
0
            } else {
50
0
                CERT_DestroyCertificate(cert);
51
0
            }
52
0
        }
53
0
    } else { /* no name given, automatically find the right cert. */
54
0
        CERTCertNicknames *names;
55
0
        int i;
56
0
57
0
        names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(),
58
0
                                      SEC_CERT_NICKNAMES_USER, proto_win);
59
0
        if (names != NULL) {
60
0
            for (i = 0; i < names->numnicknames; i++) {
61
0
                cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
62
0
                                                names->nicknames[i], certUsageSSLClient,
63
0
                                                PR_FALSE, proto_win);
64
0
                if (!cert)
65
0
                    continue;
66
0
                /* Only check unexpired certs */
67
0
                if (CERT_CheckCertValidTimes(cert, ssl_TimeUsec(), PR_TRUE) !=
68
0
                    secCertTimeValid) {
69
0
                    CERT_DestroyCertificate(cert);
70
0
                    continue;
71
0
                }
72
0
                rv = NSS_CmpCertChainWCANames(cert, caNames);
73
0
                if (rv == SECSuccess) {
74
0
                    privkey =
75
0
                        PK11_FindKeyByAnyCert(cert, proto_win);
76
0
                    if (privkey)
77
0
                        break;
78
0
                }
79
0
                rv = SECFailure;
80
0
                CERT_DestroyCertificate(cert);
81
0
            }
82
0
            CERT_FreeNicknames(names);
83
0
        }
84
0
    }
85
0
    if (rv == SECSuccess) {
86
0
        *pRetCert = cert;
87
0
        *pRetKey = privkey;
88
0
    }
89
0
    return rv;
90
0
}