Annotation of embedaddon/ntp/sntp/crypto.c, revision 1.1.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>