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>