xref: /netbsd/external/bsd/ntp/dist/libntp/ssl_init.c (revision 6550d01e)
1 /*	$NetBSD: ssl_init.c,v 1.2 2010/12/04 23:08:34 christos Exp $	*/
2 
3 /*
4  * ssl_init.c	Common OpenSSL initialization code for the various
5  *		programs which use it.
6  *
7  * Moved from ntpd/ntp_crypto.c crypto_setup()
8  */
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12 #include <ctype.h>
13 #include <ntp.h>
14 #include <ntp_debug.h>
15 #include <lib_strbuf.h>
16 
17 #ifdef OPENSSL
18 #include "openssl/err.h"
19 #include "openssl/rand.h"
20 
21 
22 int ssl_init_done;
23 
24 void
25 ssl_init(void)
26 {
27 	if (ssl_init_done)
28 		return;
29 
30 	ERR_load_crypto_strings();
31 	OpenSSL_add_all_algorithms();
32 
33 	ssl_init_done = 1;
34 }
35 
36 
37 void
38 ssl_check_version(void)
39 {
40 	if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L) {
41 		msyslog(LOG_WARNING,
42 		    "OpenSSL version mismatch. Built against %lx, you have %lx",
43 		    OPENSSL_VERSION_NUMBER, SSLeay());
44 		fprintf(stderr,
45 		    "OpenSSL version mismatch. Built against %lx, you have %lx\n",
46 		    OPENSSL_VERSION_NUMBER, SSLeay());
47 	}
48 
49 	INIT_SSL();
50 }
51 #endif	/* OPENSSL */
52 
53 
54 /*
55  * keytype_from_text	returns OpenSSL NID for digest by name, and
56  *			optionally the associated digest length.
57  *
58  * Used by ntpd authreadkeys(), ntpq and ntpdc keytype()
59  */
60 int
61 keytype_from_text(
62 	const char *text,
63 	size_t *pdigest_len
64 	)
65 {
66 	int		key_type;
67 	u_int		digest_len;
68 #ifdef OPENSSL
69 	u_char		digest[EVP_MAX_MD_SIZE];
70 	char *		upcased;
71 	char *		pch;
72 	EVP_MD_CTX	ctx;
73 
74 	/*
75 	 * OpenSSL digest short names are capitalized, so uppercase the
76 	 * digest name before passing to OBJ_sn2nid().  If it is not
77 	 * recognized but begins with 'M' use NID_md5 to be consistent
78 	 * with past behavior.
79 	 */
80 	INIT_SSL();
81 	LIB_GETBUF(upcased);
82 	strncpy(upcased, text, LIB_BUFLENGTH);
83 	for (pch = upcased; '\0' != *pch; pch++)
84 		*pch = (char)toupper((unsigned char)*pch);
85 	key_type = OBJ_sn2nid(upcased);
86 #else
87 	key_type = 0;
88 #endif
89 
90 	if (!key_type && 'm' == tolower((unsigned char)text[0]))
91 		key_type = NID_md5;
92 
93 	if (!key_type)
94 		return 0;
95 
96 	if (NULL != pdigest_len) {
97 #ifdef OPENSSL
98 		EVP_DigestInit(&ctx, EVP_get_digestbynid(key_type));
99 		EVP_DigestFinal(&ctx, digest, &digest_len);
100 		if (digest_len + sizeof(keyid_t) > MAX_MAC_LEN) {
101 			fprintf(stderr,
102 				"key type %s %u octet digests are too big, max %u\n",
103 				keytype_name(key_type), digest_len,
104 				(unsigned)(MAX_MAC_LEN - sizeof(keyid_t)));
105 			msyslog(LOG_ERR,
106 				"key type %s %u octet digests are too big, max %u",
107 				keytype_name(key_type), digest_len,
108 				(unsigned)(MAX_MAC_LEN - sizeof(keyid_t)));
109 			return 0;
110 		}
111 #else
112 		digest_len = 16;
113 #endif
114 		*pdigest_len = digest_len;
115 	}
116 
117 	return key_type;
118 }
119 
120 
121 /*
122  * keytype_name		returns OpenSSL short name for digest by NID.
123  *
124  * Used by ntpq and ntpdc keytype()
125  */
126 const char *
127 keytype_name(
128 	int nid
129 	)
130 {
131 	static const char unknown_type[] = "(unknown key type)";
132 	const char *name;
133 
134 #ifdef OPENSSL
135 	INIT_SSL();
136 	name = OBJ_nid2sn(nid);
137 	if (NULL == name)
138 		name = unknown_type;
139 #else	/* !OPENSSL follows */
140 	if (NID_md5 == nid)
141 		name = "MD5";
142 	else
143 		name = unknown_type;
144 #endif
145 	return name;
146 }
147 
148