forked from acl-dev/acl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtls_certkey.c
166 lines (152 loc) · 4.93 KB
/
tls_certkey.c
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*++
* NAME
* tls_certkey 3
* SUMMARY
* public key certificate and private key loader
* SYNOPSIS
* #include <tls.h>
* #include <tls_private.h>
*
* int tls_set_ca_certificate_info(ctx, CAfile, CApath)
* SSL_CTX *ctx;
* const char *CAfile;
* const char *CApath;
*
* int tls_set_my_certificate_key_info(ctx, cert_file, key_file,
* dcert_file, dkey_file,
* eccert_file, eckey_file)
* SSL_CTX *ctx;
* const char *cert_file;
* const char *key_file;
* const char *dcert_file;
* const char *dkey_file;
* const char *eccert_file;
* const char *eckey_file;
* DESCRIPTION
* OpenSSL supports two options to specify CA certificates:
* either one file CAfile that contains all CA certificates,
* or a directory CApath with separate files for each
* individual CA, with symbolic links named after the hash
* values of the certificates. The second option is not
* convenient with a chrooted process.
*
* tls_set_ca_certificate_info() loads the CA certificate
* information for the specified TLS server or client context.
* The result is -1 on failure, 0 on success.
*
* tls_set_my_certificate_key_info() loads the public key
* certificates and private keys for the specified TLS server
* or client context. Up to 3 pairs of key pairs (RSA, DSA and
* ECDSA) may be specified; each certificate and key pair must
* match. The result is -1 on failure, 0 on success.
* LICENSE
* .ad
* .fi
* This software is free. You can do with it whatever you want.
* The original author kindly requests that you acknowledge
* the use of his software.
* AUTHOR(S)
* Originally written by:
* Lutz Jaenicke
* BTU Cottbus
* Allgemeine Elektrotechnik
* Universitaetsplatz 3-4
* D-03044 Cottbus, Germany
*
* Updated by:
* Wietse Venema
* IBM T.J. Watson Research
* P.O. Box 704
* Yorktown Heights, NY 10598, USA
*--*/
#include "StdAfx.h"
#ifdef USE_TLS
/* TLS library. */
#include "tls.h"
#include "tls_private.h"
/* tls_set_ca_certificate_info - load certificate authority certificates */
int tls_set_ca_certificate_info(SSL_CTX *ctx, const char *CAfile, const char *CApath)
{
if (*CAfile == 0)
CAfile = 0;
if (*CApath == 0)
CApath = 0;
if (CAfile || CApath) {
if (!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) {
acl_msg_info("cannot load Certificate Authority data: "
"disabling TLS support");
tls_print_errors();
return (-1);
}
if (!SSL_CTX_set_default_verify_paths(ctx)) {
acl_msg_info("cannot set certificate verification paths: "
"disabling TLS support");
tls_print_errors();
return (-1);
}
}
return (0);
}
/* set_cert_stuff - specify certificate and key information */
static int set_cert_stuff(SSL_CTX *ctx, const char *cert_type,
const char *cert_file, const char *key_file)
{
const char *myname = "set_cert_stuff";
/*
* We need both the private key (in key_file) and the public key
* certificate (in cert_file). Both may specify the same file.
*
* Code adapted from OpenSSL apps/s_cb.c.
*/
ERR_clear_error();
if (SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) {
acl_msg_warn("%s: cannot get %s certificate from file %s: "
"disabling TLS support", myname, cert_type, cert_file);
tls_print_errors();
return (0);
}
if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) {
acl_msg_warn("%s: cannot get %s private key from file %s: "
"disabling TLS support", myname, cert_type, key_file);
tls_print_errors();
return (0);
}
/*
* Sanity check.
*/
if (!SSL_CTX_check_private_key(ctx)) {
acl_msg_warn("%s: %s private key in %s does not match public key in %s: "
"disabling TLS support", myname, cert_type, key_file, cert_file);
return (0);
}
return (1);
}
/* tls_set_my_certificate_key_info - load client or server certificates/keys */
int tls_set_my_certificate_key_info(SSL_CTX *ctx,
const char *cert_file,
const char *key_file,
const char *dcert_file,
const char *dkey_file,
const char *eccert_file,
const char *eckey_file acl_unused)
{
const char *myname = "tls_set_my_certificate_key_info";
/*
* Lack of certificates is fine so long as we are prepared to use
* anonymous ciphers.
*/
if (cert_file && *cert_file && !set_cert_stuff(ctx, "RSA", cert_file, key_file))
return (-1); /* logged */
if (dcert_file && *dcert_file && !set_cert_stuff(ctx, "DSA", dcert_file, dkey_file))
return (-1); /* logged */
#if OPENSSL_VERSION_NUMBER >= 0x00909000 && !defined(OPENSSL_NO_ECDH)
if (eccert_file && *eccert_file && !set_cert_stuff(ctx, "ECDSA", eccert_file, eckey_file))
return (-1); /* logged */
#else
if (eccert_file && *eccert_file)
acl_msg_warn("%s: ECDSA not supported. Ignoring ECDSA certificate file \"%s\"",
myname, eccert_file);
#endif
return (0);
}
#endif