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