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