Annotation of embedaddon/ntp/sntp/crypto.c, revision 1.1
1.1 ! misho 1: #include <config.h>
! 2: #include "crypto.h"
! 3: #include <ctype.h>
! 4:
! 5: struct key *key_ptr;
! 6: int key_cnt = 0;
! 7:
! 8: int
! 9: make_mac(
! 10: char *pkt_data,
! 11: int pkt_size,
! 12: int mac_size,
! 13: struct key *cmp_key,
! 14: char * digest
! 15: )
! 16: {
! 17: u_int len = mac_size;
! 18: int key_type;
! 19: EVP_MD_CTX ctx;
! 20:
! 21: if (cmp_key->key_len > 64)
! 22: return 0;
! 23: if (pkt_size % 4 != 0)
! 24: return 0;
! 25:
! 26: INIT_SSL();
! 27: key_type = keytype_from_text(cmp_key->type, NULL);
! 28: EVP_DigestInit(&ctx, EVP_get_digestbynid(key_type));
! 29: EVP_DigestUpdate(&ctx, (u_char *)cmp_key->key_seq, (u_int)cmp_key->key_len);
! 30: EVP_DigestUpdate(&ctx, (u_char *)pkt_data, (u_int)pkt_size);
! 31: EVP_DigestFinal(&ctx, (u_char *)digest, &len);
! 32:
! 33: return (int)len;
! 34: }
! 35:
! 36:
! 37: /* Generates a md5 digest of the key specified in keyid concatinated with the
! 38: * ntp packet (exluding the MAC) and compares this digest to the digest in
! 39: * the packet's MAC. If they're equal this function returns 1 (packet is
! 40: * authentic) or else 0 (not authentic).
! 41: */
! 42: int
! 43: auth_md5(
! 44: char *pkt_data,
! 45: int pkt_size,
! 46: int mac_size,
! 47: struct key *cmp_key
! 48: )
! 49: {
! 50: int hash_len;
! 51: int authentic;
! 52: char digest[20];
! 53:
! 54: if (mac_size > sizeof(digest))
! 55: return 0;
! 56: hash_len = make_mac(pkt_data, pkt_size, sizeof(digest), cmp_key,
! 57: digest);
! 58: if (!hash_len)
! 59: authentic = FALSE;
! 60: else
! 61: authentic = !memcmp(digest, pkt_data + pkt_size + 4,
! 62: hash_len);
! 63: return authentic;
! 64: }
! 65:
! 66: static int
! 67: hex_val(
! 68: unsigned char x
! 69: )
! 70: {
! 71: int val;
! 72:
! 73: if ('0' <= x && x <= '9')
! 74: val = x - '0';
! 75: else if ('a' <= x && x <= 'f')
! 76: val = x - 'a' + 0xa;
! 77: else if ('A' <= x && x <= 'F')
! 78: val = x - 'A' + 0xA;
! 79: else
! 80: val = -1;
! 81:
! 82: return val;
! 83: }
! 84:
! 85: /* Load keys from the specified keyfile into the key structures.
! 86: * Returns -1 if the reading failed, otherwise it returns the
! 87: * number of keys it read
! 88: */
! 89: int
! 90: auth_init(
! 91: const char *keyfile,
! 92: struct key **keys
! 93: )
! 94: {
! 95: FILE *keyf = fopen(keyfile, "r");
! 96: struct key *prev = NULL;
! 97: int scan_cnt, line_cnt = 0;
! 98: char kbuf[200];
! 99: char keystring[129];
! 100:
! 101: if (keyf == NULL) {
! 102: if (ENABLED_OPT(NORMALVERBOSE))
! 103: printf("sntp auth_init: Couldn't open key file %s for reading!\n", keyfile);
! 104: return -1;
! 105: }
! 106: if (feof(keyf)) {
! 107: if (ENABLED_OPT(NORMALVERBOSE))
! 108: printf("sntp auth_init: Key file %s is empty!\n", keyfile);
! 109: fclose(keyf);
! 110: return -1;
! 111: }
! 112: key_cnt = 0;
! 113: while (!feof(keyf)) {
! 114: char * octothorpe;
! 115: struct key *act = emalloc(sizeof(struct key));
! 116: int goodline = 0;
! 117:
! 118: if (NULL == fgets(kbuf, sizeof(kbuf), keyf))
! 119: continue;
! 120:
! 121: kbuf[sizeof(kbuf) - 1] = '\0';
! 122: octothorpe = strchr(kbuf, '#');
! 123: if (octothorpe)
! 124: *octothorpe = '\0';
! 125: scan_cnt = sscanf(kbuf, "%d %9s %128s", &act->key_id, act->type, keystring);
! 126: if (scan_cnt == 3) {
! 127: int len = strlen(keystring);
! 128: if (len <= 20) {
! 129: act->key_len = len;
! 130: memcpy(act->key_seq, keystring, len + 1);
! 131: goodline = 1;
! 132: } else if ((len & 1) != 0) {
! 133: goodline = 0; /* it's bad */
! 134: } else {
! 135: int j;
! 136: goodline = 1;
! 137: act->key_len = len >> 1;
! 138: for (j = 0; j < len; j+=2) {
! 139: int val;
! 140: val = (hex_val(keystring[j]) << 4) |
! 141: hex_val(keystring[j+1]);
! 142: if (val < 0) {
! 143: goodline = 0; /* it's bad */
! 144: break;
! 145: }
! 146: act->key_seq[j>>1] = (char)val;
! 147: }
! 148: }
! 149: }
! 150: if (goodline) {
! 151: act->next = NULL;
! 152: if (NULL == prev)
! 153: *keys = act;
! 154: else
! 155: prev->next = act;
! 156: prev = act;
! 157: key_cnt++;
! 158: } else {
! 159: msyslog(LOG_DEBUG, "auth_init: scanf %d items, skipping line %d.",
! 160: scan_cnt, line_cnt);
! 161: free(act);
! 162: }
! 163: line_cnt++;
! 164: }
! 165: fclose(keyf);
! 166:
! 167: key_ptr = *keys;
! 168: return key_cnt;
! 169: }
! 170:
! 171: /* Looks for the key with keyid key_id and sets the d_key pointer to the
! 172: * address of the key. If no matching key is found the pointer is not touched.
! 173: */
! 174: void
! 175: get_key(
! 176: int key_id,
! 177: struct key **d_key
! 178: )
! 179: {
! 180: struct key *itr_key;
! 181:
! 182: if (key_cnt == 0)
! 183: return;
! 184: for (itr_key = key_ptr; itr_key; itr_key = itr_key->next) {
! 185: if (itr_key->key_id == key_id) {
! 186: *d_key = itr_key;
! 187: break;
! 188: }
! 189: }
! 190: return;
! 191: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>