📄 auth.c
字号:
DEBUG(DEBUG_FLAG, "auth_check_gen: unknown algorithm %i\n", alg); return 0; } mac = (unsigned char *) malloc(mac_len); if (mac == NULL) { DEBUG(DEBUG_FLAG, "auth_check_gen: malloc(%i) failed\n", mac_len); return 0; } if (ntohs(auth->length) != mac_len + SPI_LEN) { DEBUG(DEBUG_FLAG, "auth_check_gen: len=%i != %i\n", ntohs(auth->length), mac_len + SPI_LEN); return 0; } len = ((unsigned char *)auth) - data + sizeof(struct generalized_auth_ext); mac_func(key, keylen, data, len, mac);#ifdef AUTH_EXTRA_DEBUG DEBUG(DEBUG_FLAG, "auth_check_gen: len=%i, recvMAC=", len); show_hex(MSG_GEN_AUTH_DATA(auth), mac_len); DEBUG(DEBUG_FLAG, ", expMAC="); show_hex(mac, mac_len); DEBUG(DEBUG_FLAG, "\n");#endif ret = memcmp(mac, MSG_GEN_AUTH_DATA(auth), mac_len) == 0; free(mac); return ret;}/* Encrypts the session key with given algorithm and shared secret */int auth_encrypt(int alg, unsigned char *ssec, unsigned int sseclen, unsigned char *key, struct msg_key *keyrep, struct reg_rep *data, __u8 keytype, __u32 spi){ unsigned char *t; int i; int mac_len; MACfunc mac_func; mac_func = auth_get_mac_data(alg, &mac_len); if (mac_func == NULL) { DEBUG(DEBUG_FLAG, "auth_encrypt: unknown algorithm %i\n", alg); return SPI_LEN; } init_key_extension(keyrep, keytype, spi, mac_len); t = MSG_KEY_DATA(keyrep); mac_func(ssec, sseclen, (unsigned char *) data, sizeof(struct reg_rep), t); for (i = 0; i < mac_len; i++) t[i] ^= key[i]; return GET_KEY_EXT_LEN(keyrep);}/* Decrypts keyrep extension with given algorithm and shared secret * Returns: * Pointer to the decrypted session (caller must release the memory) on * success or NULL on failure. * sk_len is set to the length of the session key or on failure to an * error code: * -1: could not allocate enough memory * -2: invalid length of keyrep * -3: unknown decryption algorithm */unsigned char* auth_decrypt(int alg, unsigned char *ssec, unsigned int sseclen, struct msg_key *keyrep, struct reg_rep *data, int *sk_len){ unsigned char *skey; int i; int mac_len; MACfunc mac_func; mac_func = auth_get_mac_data(alg, &mac_len); if (mac_func == NULL) { DEBUG(DEBUG_FLAG, "auth_decrypt: unknown algorithm %i\n", alg); *sk_len = -3; return NULL; } *sk_len = mac_len; if (GET_KEY_LEN(keyrep) != *sk_len) { DEBUG(DEBUG_FLAG, "auth_decrypt: keyrep has wrong length %i " "!= %i\n", GET_KEY_LEN(keyrep), *sk_len); *sk_len = -2; return NULL; } skey = malloc(*sk_len); if (skey == NULL) { DEBUG(DEBUG_FLAG, "auth_decrypt: not enough memory\n"); *sk_len = -1; return NULL; } mac_func(ssec, sseclen, (unsigned char *) data, sizeof(struct reg_rep), skey); for (i = 0; i < *sk_len; i++) skey[i] ^= *(MSG_KEY_DATA(keyrep) + i); return skey;}/* NOTE! * /dev/random waits until it gets enough "randomness" available * i.e. it can take a long time to generate the needed 128 bits! * the use of /dev/urandom eliminates this blocking, but it is not as * secure * * The "randomness" is coming from mouse movements, keyboard clicks, * interrupts and block device requests. If the system is very idle, there * might be some DoS problems with this.. Because of this, the system uses * /dev/urandom. This should be changed if a reliable non-blocking * source of random numbers was available. * * /dev/urandom gives as good random numbers as /dev/random _if_ there is * enough random data available, but it will not block in case such data * is not available (it gives some less random data in that case). The * session key is generated with MD5 and a secret key generation key, so the * process should be very difficult to break even if some of the random bits * were not so random. */int generate_session_key(int alg, unsigned char *key, unsigned int key_len, unsigned char *session_key){ FILE *in; unsigned char data[MAX_SK_LEN]; int len; int mac_len; MACfunc mac_func; mac_func = auth_get_mac_data(alg, &mac_len); if (mac_func == NULL) { DEBUG(DEBUG_FLAG, "generate_session_key: unknown algorithm %i\n", alg); return -1; } len = mac_len; if (key == NULL) return -1; in = fopen("/dev/urandom", "rb"); if (in == NULL) return -1; if (fread(data, 1, len, in) != len) { fclose(in); return -1; } fclose(in); mac_func(key, key_len, data, len, session_key); assert(len <= MAX_SK_LEN); return len;}/** * auth_is_protected: * @ext: pointer to extension whose protection is checked * @auth: pointer to authentication extension * * Checks whether @auth protects @ext, i.e., whether @auth comes after @ext. * * Returns: * 1 if @ext is %NULL or protected by @auth; or 0 if not */int auth_is_protected(void *ext, void *auth){ if (ext == NULL) return 1; if (ext > auth) return 0; return 1;}/** * auth_aaa_key_alg_id_to_dynamics: * @alg_id: algorithm id as specified in draft-ietf-mobileip-aaa-key-07.txt * * Convert algorithm id in aaa-key to authentication algorithm used in * Dynamics. * * Returns: 0 if auth. alg. is not recognized or corresponding Dynamics * authentication algorithm id. */int auth_aaa_key_alg_id_to_dynamics(int alg_id){ switch (alg_id) { case AAA_KEY_ALG_MD5: return AUTH_ALG_MD5; case AAA_KEY_ALG_HMAC_MD5: return AUTH_ALG_HMAC_MD5; case AAA_KEY_ALG_SHA1: return AUTH_ALG_SHA1; } return 0;}/** * auth_aaa_key_replay_to_dynamics: * @replay: replay method as specified in draft-ietf-mobileip-aaa-key-07.txt * * Convert replay method in aaa-key to method identifier used in Dynamics. * * Returns: -1 if auth. alg. is not recognized or corresponding Dynamics * replay method id. */int auth_aaa_key_replay_to_dynamics(int replay){ switch (replay) { case AAA_KEY_REPLAY_NONE: return REPLAY_PROTECTION_NONE; case AAA_KEY_REPLAY_TIMESTAMPS: return REPLAY_PROTECTION_TIMESTAMP; case AAA_KEY_REPLAY_NONCES: return REPLAY_PROTECTION_NONCE; } return 0;}/** * auth_generate_key: * @alg: AAA algorithm used for key generation * @key: AAA shared secret * @keylen: length of @key * @genkey: memory area for generated key * @genkeylen: pointer to @genkey len; initially maximum size and after * function call, length of the generated key * * Generate shared secret for dynamic security association as specified in * draft-ietf-mobile-aaa-key-07.txt. * * Returns: 0 on success or -1 on failure */int auth_generate_key(int alg, unsigned char *key, unsigned int keylen, const unsigned char *keymaterial, unsigned int keymateriallen, const unsigned char *nodeaddr, unsigned int nodeaddrlen, unsigned char *genkey, unsigned int *genkeylen){ unsigned char *data; int mac_len; MACfunc mac_func; mac_func = auth_get_mac_data(alg, &mac_len); if (mac_func == NULL) { DEBUG(DEBUG_FLAG, "auth_generate_key: unsupported algorithm " "%i\n", alg); return -1; } if (*genkeylen < mac_len) { DEBUG(DEBUG_FLAG, "auth_generate_key: not enough space" " for generated key\n"); return -1; } data = (unsigned char *) malloc(keymateriallen + nodeaddrlen); if (data == NULL) { DEBUG(DEBUG_FLAG, "auth_generate_key: could not allocate " "memory\n"); return -1; } memcpy(data, keymaterial, keymateriallen); memcpy(data + keymateriallen, nodeaddr, nodeaddrlen); mac_func(key, keylen, data, keymateriallen + nodeaddrlen, genkey); *genkeylen = mac_len; free(data); return 0;}/** * auth_supported_auth_alg: * @alg: algorithm id * * Check whether given algorithm is supported for authentication. * * Returns: 1 if supported, or 0 if not */int auth_supported_auth_alg(int alg){ if (alg == AUTH_ALG_MD5 || alg == AUTH_ALG_MD5_RFC2002 || /* AUTH_ALG_RADIUS not supported for all functions */ alg == AUTH_ALG_MD5_PREFIX_SUFFIX || alg == AUTH_ALG_HMAC_MD5 || alg == AUTH_ALG_SHA1 || alg == AUTH_ALG_HMAC_SHA1) return 1; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -