2 * ssl_init.c Common OpenSSL initialization code for the various
3 * programs which use it.
5 * Moved from ntpd/ntp_crypto.c crypto_setup()
12 #include <ntp_debug.h>
13 #include <lib_strbuf.h>
16 # include "openssl/cmac.h"
17 # include "openssl/crypto.h"
18 # include "openssl/err.h"
19 # include "openssl/evp.h"
20 # include "openssl/opensslv.h"
21 # include "libssl_compat.h"
23 # define CMAC_LENGTH 16
24 # define CMAC "AES128CMAC"
28 #if OPENSSL_VERSION_NUMBER < 0x10100000L
31 atexit_ssl_cleanup(void)
37 ssl_init_done = FALSE;
47 if ( ! ssl_init_done) {
48 ERR_load_crypto_strings();
49 OpenSSL_add_all_algorithms();
50 atexit(&atexit_ssl_cleanup);
55 #else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
64 #endif /* OPENSSL_VERSION_NUMBER */
68 ssl_check_version(void)
72 v = OpenSSL_version_num();
73 if ((v ^ OPENSSL_VERSION_NUMBER) & ~0xff0L) {
75 "OpenSSL version mismatch. Built against %lx, you have %lx",
76 (u_long)OPENSSL_VERSION_NUMBER, v);
78 "OpenSSL version mismatch. Built against %lx, you have %lx\n",
79 (u_long)OPENSSL_VERSION_NUMBER, v);
86 # define MD5_LENGTH 16
91 * keytype_from_text returns OpenSSL NID for digest by name, and
92 * optionally the associated digest length.
94 * Used by ntpd authreadkeys(), ntpq and ntpdc keytype()
104 #ifdef OPENSSL /* --*-- OpenSSL code --*-- */
105 const u_long max_digest_len = MAX_MAC_LEN - sizeof(keyid_t);
111 * OpenSSL digest short names are capitalized, so uppercase the
112 * digest name before passing to OBJ_sn2nid(). If it is not
113 * recognized but matches our CMAC string use NID_cmac, or if
114 * it begins with 'M' or 'm' use NID_md5 to be consistent with
119 /* get name in uppercase */
121 strlcpy(upcased, text, LIB_BUFLENGTH);
123 for (pch = upcased; '\0' != *pch; pch++) {
124 *pch = (char)toupper((unsigned char)*pch);
127 key_type = OBJ_sn2nid(upcased);
129 if (!key_type && !strncmp(CMAC, upcased, strlen(CMAC) + 1)) {
133 fprintf(stderr, "%s:%d:%s():%s:key\n",
134 __FILE__, __LINE__, __func__, CMAC);
142 if (!key_type && 'm' == tolower((unsigned char)text[0])) {
150 if (NULL != pdigest_len) {
152 md = EVP_get_digestbynid(key_type);
153 digest_len = (md) ? EVP_MD_size(md) : 0;
155 if (!md || digest_len <= 0) {
156 if (key_type == NID_cmac) {
157 digest_len = CMAC_LENGTH;
160 fprintf(stderr, "%s:%d:%s():%s:len\n",
161 __FILE__, __LINE__, __func__, CMAC);
165 "key type %s is not supported by OpenSSL\n",
166 keytype_name(key_type));
168 "key type %s is not supported by OpenSSL\n",
169 keytype_name(key_type));
174 if (digest_len > max_digest_len) {
176 "key type %s %u octet digests are too big, max %lu\n",
177 keytype_name(key_type), digest_len,
180 "key type %s %u octet digests are too big, max %lu",
181 keytype_name(key_type), digest_len,
186 digest_len = MD5_LENGTH;
188 *pdigest_len = digest_len;
196 * keytype_name returns OpenSSL short name for digest by NID.
198 * Used by ntpq and ntpdc keytype()
205 static const char unknown_type[] = "(unknown key type)";
210 name = OBJ_nid2sn(nid);
212 if (NID_cmac == nid) {
216 fprintf(stderr, "%s:%d:%s():%s:nid\n",
217 __FILE__, __LINE__, __func__, CMAC);
223 #else /* !OPENSSL follows */
234 * Use getpassphrase() if configure.ac detected it, as Suns that
235 * have it truncate the password in getpass() to 8 characters.
237 #ifdef HAVE_GETPASSPHRASE
238 # define getpass(str) getpassphrase(str)
242 * getpass_keytype() -- shared between ntpq and ntpdc, only vaguely
243 * related to the rest of ssl_init.c.
250 char pass_prompt[64 + 11 + 1]; /* 11 for " Password: " */
252 snprintf(pass_prompt, sizeof(pass_prompt),
253 "%.64s Password: ", keytype_name(keytype));
255 return getpass(pass_prompt);