12b15cb3dSCy Schubert /*
22b15cb3dSCy Schubert * ssl_init.c Common OpenSSL initialization code for the various
32b15cb3dSCy Schubert * programs which use it.
42b15cb3dSCy Schubert *
52b15cb3dSCy Schubert * Moved from ntpd/ntp_crypto.c crypto_setup()
62b15cb3dSCy Schubert */
72b15cb3dSCy Schubert #ifdef HAVE_CONFIG_H
82b15cb3dSCy Schubert # include <config.h>
92b15cb3dSCy Schubert #endif
102b15cb3dSCy Schubert #include <ctype.h>
112b15cb3dSCy Schubert #include <ntp.h>
122b15cb3dSCy Schubert #include <ntp_debug.h>
132b15cb3dSCy Schubert #include <lib_strbuf.h>
142b15cb3dSCy Schubert
152b15cb3dSCy Schubert #ifdef OPENSSL
164e1ef62aSXin LI # include <openssl/crypto.h>
174e1ef62aSXin LI # include <openssl/err.h>
184e1ef62aSXin LI # include <openssl/evp.h>
194e1ef62aSXin LI # include <openssl/opensslv.h>
20f391d6bcSXin LI # include "libssl_compat.h"
214e1ef62aSXin LI # ifdef HAVE_OPENSSL_CMAC_H
224e1ef62aSXin LI # include <openssl/cmac.h>
2309100258SXin LI # define CMAC_LENGTH 16
2409100258SXin LI # define CMAC "AES128CMAC"
254e1ef62aSXin LI # endif /*HAVE_OPENSSL_CMAC_H*/
262b15cb3dSCy Schubert
27*f5f40dd6SCy Schubert EVP_MD_CTX *digest_ctx;
28*f5f40dd6SCy Schubert
292b15cb3dSCy Schubert
30f0574f5cSXin LI static void
atexit_ssl_cleanup(void)312b15cb3dSCy Schubert atexit_ssl_cleanup(void)
322b15cb3dSCy Schubert {
33*f5f40dd6SCy Schubert if (NULL == digest_ctx) {
342b15cb3dSCy Schubert return;
3509100258SXin LI }
36*f5f40dd6SCy Schubert EVP_MD_CTX_free(digest_ctx);
37*f5f40dd6SCy Schubert digest_ctx = NULL;
38*f5f40dd6SCy Schubert #if OPENSSL_VERSION_NUMBER < 0x10100000L
392b15cb3dSCy Schubert EVP_cleanup();
402b15cb3dSCy Schubert ERR_free_strings();
41*f5f40dd6SCy Schubert #endif /* OpenSSL < 1.1 */
422b15cb3dSCy Schubert }
432b15cb3dSCy Schubert
44*f5f40dd6SCy Schubert
45f0574f5cSXin LI void
ssl_init(void)46f0574f5cSXin LI ssl_init(void)
47f0574f5cSXin LI {
48f0574f5cSXin LI init_lib();
49f0574f5cSXin LI
50*f5f40dd6SCy Schubert if (NULL == digest_ctx) {
51*f5f40dd6SCy Schubert #if OPENSSL_VERSION_NUMBER < 0x10100000L
52f0574f5cSXin LI ERR_load_crypto_strings();
53f0574f5cSXin LI OpenSSL_add_all_algorithms();
54*f5f40dd6SCy Schubert #endif /* OpenSSL < 1.1 */
55*f5f40dd6SCy Schubert digest_ctx = EVP_MD_CTX_new();
56*f5f40dd6SCy Schubert INSIST(digest_ctx != NULL);
57f0574f5cSXin LI atexit(&atexit_ssl_cleanup);
58f0574f5cSXin LI }
59f0574f5cSXin LI }
60f0574f5cSXin LI
612b15cb3dSCy Schubert
622b15cb3dSCy Schubert void
ssl_check_version(void)632b15cb3dSCy Schubert ssl_check_version(void)
642b15cb3dSCy Schubert {
65f0574f5cSXin LI u_long v;
66*f5f40dd6SCy Schubert char * buf;
67f0574f5cSXin LI
68f0574f5cSXin LI v = OpenSSL_version_num();
69f0574f5cSXin LI if ((v ^ OPENSSL_VERSION_NUMBER) & ~0xff0L) {
70*f5f40dd6SCy Schubert LIB_GETBUF(buf);
71*f5f40dd6SCy Schubert snprintf(buf, LIB_BUFLENGTH,
72*f5f40dd6SCy Schubert "OpenSSL version mismatch."
73*f5f40dd6SCy Schubert "Built against %lx, you have %lx\n",
74f0574f5cSXin LI (u_long)OPENSSL_VERSION_NUMBER, v);
75*f5f40dd6SCy Schubert msyslog(LOG_WARNING, "%s", buf);
76*f5f40dd6SCy Schubert fputs(buf, stderr);
772b15cb3dSCy Schubert }
782b15cb3dSCy Schubert INIT_SSL();
792b15cb3dSCy Schubert }
802b15cb3dSCy Schubert #endif /* OPENSSL */
812b15cb3dSCy Schubert
822b15cb3dSCy Schubert
832b15cb3dSCy Schubert /*
842b15cb3dSCy Schubert * keytype_from_text returns OpenSSL NID for digest by name, and
852b15cb3dSCy Schubert * optionally the associated digest length.
862b15cb3dSCy Schubert *
872b15cb3dSCy Schubert * Used by ntpd authreadkeys(), ntpq and ntpdc keytype()
882b15cb3dSCy Schubert */
892b15cb3dSCy Schubert int
keytype_from_text(const char * text,size_t * pdigest_len)902b15cb3dSCy Schubert keytype_from_text(
912b15cb3dSCy Schubert const char * text,
922b15cb3dSCy Schubert size_t * pdigest_len
932b15cb3dSCy Schubert )
942b15cb3dSCy Schubert {
952b15cb3dSCy Schubert int key_type;
962b15cb3dSCy Schubert u_int digest_len;
9709100258SXin LI #ifdef OPENSSL /* --*-- OpenSSL code --*-- */
98*f5f40dd6SCy Schubert const u_long max_digest_len = MAX_MDG_LEN;
992b15cb3dSCy Schubert char * upcased;
1002b15cb3dSCy Schubert char * pch;
10109100258SXin LI EVP_MD const * md;
1022b15cb3dSCy Schubert
1032b15cb3dSCy Schubert /*
1042b15cb3dSCy Schubert * OpenSSL digest short names are capitalized, so uppercase the
1052b15cb3dSCy Schubert * digest name before passing to OBJ_sn2nid(). If it is not
10609100258SXin LI * recognized but matches our CMAC string use NID_cmac, or if
10709100258SXin LI * it begins with 'M' or 'm' use NID_md5 to be consistent with
10809100258SXin LI * past behavior.
1092b15cb3dSCy Schubert */
1102b15cb3dSCy Schubert INIT_SSL();
11109100258SXin LI
11209100258SXin LI /* get name in uppercase */
1132b15cb3dSCy Schubert LIB_GETBUF(upcased);
1142b15cb3dSCy Schubert strlcpy(upcased, text, LIB_BUFLENGTH);
11509100258SXin LI
11609100258SXin LI for (pch = upcased; '\0' != *pch; pch++) {
1172b15cb3dSCy Schubert *pch = (char)toupper((unsigned char)*pch);
11809100258SXin LI }
11909100258SXin LI
1202b15cb3dSCy Schubert key_type = OBJ_sn2nid(upcased);
12109100258SXin LI
1224e1ef62aSXin LI # ifdef ENABLE_CMAC
12309100258SXin LI if (!key_type && !strncmp(CMAC, upcased, strlen(CMAC) + 1)) {
12409100258SXin LI key_type = NID_cmac;
12509100258SXin LI
12609100258SXin LI if (debug) {
12709100258SXin LI fprintf(stderr, "%s:%d:%s():%s:key\n",
12809100258SXin LI __FILE__, __LINE__, __func__, CMAC);
12909100258SXin LI }
13009100258SXin LI }
1314e1ef62aSXin LI # endif /*ENABLE_CMAC*/
1322b15cb3dSCy Schubert #else
13309100258SXin LI
1342b15cb3dSCy Schubert key_type = 0;
1352b15cb3dSCy Schubert #endif
1362b15cb3dSCy Schubert
13709100258SXin LI if (!key_type && 'm' == tolower((unsigned char)text[0])) {
1382b15cb3dSCy Schubert key_type = NID_md5;
13909100258SXin LI }
1402b15cb3dSCy Schubert
14109100258SXin LI if (!key_type) {
1422b15cb3dSCy Schubert return 0;
14309100258SXin LI }
1442b15cb3dSCy Schubert
1452b15cb3dSCy Schubert if (NULL != pdigest_len) {
1462b15cb3dSCy Schubert #ifdef OPENSSL
14709100258SXin LI md = EVP_get_digestbynid(key_type);
14809100258SXin LI digest_len = (md) ? EVP_MD_size(md) : 0;
149f391d6bcSXin LI
15009100258SXin LI if (!md || digest_len <= 0) {
1514e1ef62aSXin LI # ifdef ENABLE_CMAC
15209100258SXin LI if (key_type == NID_cmac) {
15309100258SXin LI digest_len = CMAC_LENGTH;
15409100258SXin LI
15509100258SXin LI if (debug) {
15609100258SXin LI fprintf(stderr, "%s:%d:%s():%s:len\n",
15709100258SXin LI __FILE__, __LINE__, __func__, CMAC);
15809100258SXin LI }
1594e1ef62aSXin LI } else
1604e1ef62aSXin LI # endif /*ENABLE_CMAC*/
1614e1ef62aSXin LI {
16209100258SXin LI fprintf(stderr,
16309100258SXin LI "key type %s is not supported by OpenSSL\n",
16409100258SXin LI keytype_name(key_type));
16509100258SXin LI msyslog(LOG_ERR,
16609100258SXin LI "key type %s is not supported by OpenSSL\n",
16709100258SXin LI keytype_name(key_type));
16809100258SXin LI return 0;
16909100258SXin LI }
17009100258SXin LI }
17109100258SXin LI
1722b15cb3dSCy Schubert if (digest_len > max_digest_len) {
1732b15cb3dSCy Schubert fprintf(stderr,
1742b15cb3dSCy Schubert "key type %s %u octet digests are too big, max %lu\n",
1752b15cb3dSCy Schubert keytype_name(key_type), digest_len,
1762b15cb3dSCy Schubert max_digest_len);
1772b15cb3dSCy Schubert msyslog(LOG_ERR,
1782b15cb3dSCy Schubert "key type %s %u octet digests are too big, max %lu",
1792b15cb3dSCy Schubert keytype_name(key_type), digest_len,
1802b15cb3dSCy Schubert max_digest_len);
1812b15cb3dSCy Schubert return 0;
1822b15cb3dSCy Schubert }
1832b15cb3dSCy Schubert #else
18409100258SXin LI digest_len = MD5_LENGTH;
1852b15cb3dSCy Schubert #endif
1862b15cb3dSCy Schubert *pdigest_len = digest_len;
1872b15cb3dSCy Schubert }
1882b15cb3dSCy Schubert
1892b15cb3dSCy Schubert return key_type;
1902b15cb3dSCy Schubert }
1912b15cb3dSCy Schubert
1922b15cb3dSCy Schubert
1932b15cb3dSCy Schubert /*
1942b15cb3dSCy Schubert * keytype_name returns OpenSSL short name for digest by NID.
1952b15cb3dSCy Schubert *
1962b15cb3dSCy Schubert * Used by ntpq and ntpdc keytype()
1972b15cb3dSCy Schubert */
1982b15cb3dSCy Schubert const char *
keytype_name(int type)1992b15cb3dSCy Schubert keytype_name(
200*f5f40dd6SCy Schubert int type
2012b15cb3dSCy Schubert )
2022b15cb3dSCy Schubert {
2032b15cb3dSCy Schubert static const char unknown_type[] = "(unknown key type)";
2042b15cb3dSCy Schubert const char *name;
2052b15cb3dSCy Schubert
2062b15cb3dSCy Schubert #ifdef OPENSSL
2072b15cb3dSCy Schubert INIT_SSL();
208*f5f40dd6SCy Schubert name = OBJ_nid2sn(type);
20909100258SXin LI
2104e1ef62aSXin LI # ifdef ENABLE_CMAC
211*f5f40dd6SCy Schubert if (NID_cmac == type) {
21209100258SXin LI name = CMAC;
21309100258SXin LI } else
2144e1ef62aSXin LI # endif /*ENABLE_CMAC*/
21509100258SXin LI if (NULL == name) {
2162b15cb3dSCy Schubert name = unknown_type;
21709100258SXin LI }
2182b15cb3dSCy Schubert #else /* !OPENSSL follows */
219*f5f40dd6SCy Schubert if (NID_md5 == type)
2202b15cb3dSCy Schubert name = "MD5";
2212b15cb3dSCy Schubert else
2222b15cb3dSCy Schubert name = unknown_type;
2232b15cb3dSCy Schubert #endif
2242b15cb3dSCy Schubert return name;
2252b15cb3dSCy Schubert }
2262b15cb3dSCy Schubert
2272b15cb3dSCy Schubert
2282b15cb3dSCy Schubert /*
2292b15cb3dSCy Schubert * Use getpassphrase() if configure.ac detected it, as Suns that
2302b15cb3dSCy Schubert * have it truncate the password in getpass() to 8 characters.
2312b15cb3dSCy Schubert */
2322b15cb3dSCy Schubert #ifdef HAVE_GETPASSPHRASE
2332b15cb3dSCy Schubert # define getpass(str) getpassphrase(str)
2342b15cb3dSCy Schubert #endif
2352b15cb3dSCy Schubert
2362b15cb3dSCy Schubert /*
2372b15cb3dSCy Schubert * getpass_keytype() -- shared between ntpq and ntpdc, only vaguely
2382b15cb3dSCy Schubert * related to the rest of ssl_init.c.
2392b15cb3dSCy Schubert */
2402b15cb3dSCy Schubert char *
getpass_keytype(int type)2412b15cb3dSCy Schubert getpass_keytype(
242*f5f40dd6SCy Schubert int type
2432b15cb3dSCy Schubert )
2442b15cb3dSCy Schubert {
2452b15cb3dSCy Schubert char pass_prompt[64 + 11 + 1]; /* 11 for " Password: " */
2462b15cb3dSCy Schubert
2472b15cb3dSCy Schubert snprintf(pass_prompt, sizeof(pass_prompt),
248*f5f40dd6SCy Schubert "%.64s Password: ", keytype_name(type));
2492b15cb3dSCy Schubert
2502b15cb3dSCy Schubert return getpass(pass_prompt);
2512b15cb3dSCy Schubert }
25209100258SXin LI
253