📄 ck_crp.c
字号:
int fb64_reply P((unsigned char *, int, struct des_fb *));static int fb64_session P((Session_Key *, int, struct des_fb *));void fb64_stream_key P((Block, struct des_stinfo *));int fb64_keyid P((int, unsigned char *, int *, struct des_fb *));#ifdef MIT_CURRENTstatic void#ifdef CK_ANSICecb_encrypt(struct des_stinfo *stp, Block in, Block out)#else /* CKANSIC */ecb_encrypt(stp, in, out) struct des_stinfo *stp; Block in; Block out;#endif /* CK_ANSIC */{ krb5_error_code code; krb5_data din; krb5_enc_data dout; din.length = 8; din.data = in; dout.ciphertext.length = 8; dout.ciphertext.data = out; dout.enctype = ENCTYPE_UNKNOWN;#ifdef CRYPT_DLL code = krb5_c_encrypt(*p_k5_context, &stp->str_key, 0, 0, &din, &dout);#else /* CRYPT_DLL */ code = krb5_c_encrypt(k5_context, &stp->str_key, 0, 0, &din, &dout);#endif /* CRYPT_DLL */ /* XXX I'm not sure what to do if this fails */ if (code) com_err("libtelnet", code, "encrypting stream data");}#endif /* MIT_CURRENT */voidcfb64_init(server) int server;{ fb64_init(&des_fb[CFB]); des_fb[CFB].fb_feed[4] = ENCTYPE_DES_CFB64; des_fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB); des_fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB);}voidofb64_init(server) int server;{ fb64_init(&des_fb[OFB]); des_fb[OFB].fb_feed[4] = ENCTYPE_DES_OFB64; des_fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB); des_fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB);}voidfb64_init(fbp) register struct des_fb *fbp;{ memset((void *)fbp, 0, sizeof(*fbp)); fbp->state[0] = fbp->state[1] = xFAILED; fbp->fb_feed[0] = IAC; fbp->fb_feed[1] = SB; fbp->fb_feed[2] = TELOPT_ENCRYPTION; fbp->fb_feed[3] = ENCRYPT_IS;}/* * Returns: * -1: some error. Negotiation is done, encryption not ready. * 0: Successful, initial negotiation all done. * 1: successful, negotiation not done yet. * 2: Not yet. Other things (like getting the key from * Kerberos) have to happen before we can continue. */intcfb64_start(dir, server) int dir; int server;{ return(fb64_start(&des_fb[CFB], dir, server));}intofb64_start(dir, server) int dir; int server;{ return(fb64_start(&des_fb[OFB], dir, server));}static intfb64_start(fbp, dir, server) struct des_fb *fbp; int dir; int server;{ int x; unsigned char *p; register int state; switch (dir) { case DIR_DECRYPT: /* * This is simply a request to have the other side * start output (our input). He will negotiate an * IV so we need not look for it. */ state = fbp->state[dir-1]; if (state == xFAILED) state = IN_PROGRESS; break; case DIR_ENCRYPT: state = fbp->state[dir-1]; if (state == xFAILED) state = IN_PROGRESS; else if ((state & NO_SEND_IV) == 0) break;#ifdef MIT_CURRENT if (!fbp->validkey) { fbp->need_start = 1; break; }#else /* MIT_CURRENT */ if (!VALIDKEY(fbp->krbdes_key)) { fbp->need_start = 1; break; }#endif /* MIT_CURRENT */ state &= ~NO_SEND_IV; state |= NO_RECV_IV; /* * Create a random feed and send it over. */#ifdef MIT_CURRENT { krb5_data d; krb5_error_code code; d.data = fbp->temp_feed; d.length = sizeof(fbp->temp_feed);#ifdef CRYPT_DLL if (code = krb5_c_random_make_octets(*p_k5_context,&d)) return(xFAILED);#else /* CRYPT_DLL */ if (code = krb5_c_random_make_octets(k5_context,&d)) return(xFAILED);#endif /* CRYPT_DLL */ }#else /* MIT_CURRENT */ des_new_random_key(fbp->temp_feed); des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed, fbp->krbdes_sched, 1);#endif /* MIT_CURRENT */ p = fbp->fb_feed + 3; *p++ = ENCRYPT_IS; p++; *p++ = FB64_IV; for (x = 0; x < sizeof(Block); ++x) { if (( *p++ = fbp->temp_feed[x]) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; if (deblog || tn_deb || debses) { int i; sprintf(tn_msg, "TELNET SENT SB %s IS %s FB64_IV ", TELOPT(fbp->fb_feed[2]), enctype_names[fbp->fb_feed[4]]); /* safe */ tn_hex(tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],(p-fbp->fb_feed)-2-6); ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN); debug(F100,tn_msg,"",0); if (tn_deb || debses) tn_debug(tn_msg); }#ifdef OS2 RequestTelnetMutex( SEM_INDEFINITE_WAIT );#endif ttol(fbp->fb_feed, p - fbp->fb_feed);#ifdef OS2 ReleaseTelnetMutex();#endif break; default: return(xFAILED); } return(fbp->state[dir-1] = state);}/* * Returns: * -1: some error. Negotiation is done, encryption not ready. * 0: Successful, initial negotiation all done. * 1: successful, negotiation not done yet. */intcfb64_is(data, cnt) unsigned char *data; int cnt;{ return(fb64_is(data, cnt, &des_fb[CFB]));}intofb64_is(data, cnt) unsigned char *data; int cnt;{ return(fb64_is(data, cnt, &des_fb[OFB]));}intfb64_is(data, cnt, fbp) unsigned char *data; int cnt; struct des_fb *fbp;{ unsigned char *p; register int state = fbp->state[DIR_DECRYPT-1]; if (cnt-- < 1) goto failure;#ifdef CK_SSL if (!TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)#endif /* CK_SSL */ switch (*data++) { case FB64_IV: if (cnt != sizeof(Block)) {#ifdef DEBUG if (encrypt_debug_mode) printf("CFB64: initial vector failed on size\r\n");#endif state = xFAILED; goto failure; }#ifdef DEBUG if (encrypt_debug_mode) { printf("CFB64: initial vector received\r\n"); printf("Initializing Decrypt stream\r\n"); }#endif fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]); p = fbp->fb_feed + 3; *p++ = ENCRYPT_REPLY; p++; *p++ = FB64_IV_OK; *p++ = IAC; *p++ = SE; if (deblog || tn_deb || debses) { int i; sprintf(tn_msg, "TELNET SENT SB %s REPLY %s FB64_IV_OK ", TELOPT(fbp->fb_feed[2]), enctype_names[fbp->fb_feed[4]]); /* safe */ tn_hex(tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],(p-fbp->fb_feed)-2-6); ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN); debug(F100,tn_msg,"",0); if (tn_deb || debses) tn_debug(tn_msg); }#ifdef OS2 RequestTelnetMutex( SEM_INDEFINITE_WAIT );#endif ttol(fbp->fb_feed, p - fbp->fb_feed);#ifdef OS2 ReleaseTelnetMutex();#endif state = IN_PROGRESS; break; default:#if 0 if (encrypt_debug_mode) { printf("Unknown option type: %d\r\n", *(data-1)); printf("\r\n"); }#endif /* FALL THROUGH */ failure: /* * We failed. Send an FB64_IV_BAD option * to the other side so it will know that * things failed. */ p = fbp->fb_feed + 3; *p++ = ENCRYPT_REPLY; p++; *p++ = FB64_IV_BAD; *p++ = IAC; *p++ = SE; if (deblog || tn_deb || debses) { int i; sprintf(tn_msg, "TELNET SENT SB %s REPLY %s FB64_IV_BAD ", TELOPT(fbp->fb_feed[2]), enctype_names[fbp->fb_feed[4]]); /* safe */ tn_hex(tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],(p-fbp->fb_feed)-2-6); ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN); debug(F100,tn_msg,"",0); if (tn_deb || debses) tn_debug(tn_msg); }#ifdef OS2 RequestTelnetMutex( SEM_INDEFINITE_WAIT );#endif ttol(fbp->fb_feed, p - fbp->fb_feed);#ifdef OS2 ReleaseTelnetMutex();#endif break; } return(fbp->state[DIR_DECRYPT-1] = state);}/* * Returns: * -1: some error. Negotiation is done, encryption not ready. * 0: Successful, initial negotiation all done. * 1: successful, negotiation not done yet. */intcfb64_reply(data, cnt) unsigned char *data; int cnt;{ return(fb64_reply(data, cnt, &des_fb[CFB]));}intofb64_reply(data, cnt) unsigned char *data; int cnt;{ return(fb64_reply(data, cnt, &des_fb[OFB]));}intfb64_reply(data, cnt, fbp) unsigned char *data; int cnt; struct des_fb *fbp;{ register int state = fbp->state[DIR_ENCRYPT-1]; if (cnt-- < 1) goto failure; switch (*data++) { case FB64_IV_OK: fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]); if (state == xFAILED) state = IN_PROGRESS; state &= ~NO_RECV_IV; encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1); break; case FB64_IV_BAD: memset(fbp->temp_feed, 0, sizeof(Block)); fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]); state = xFAILED; break; default:#if 0 if (encrypt_debug_mode) { printf("Unknown option type: %d\r\n", data[-1]); printf("\r\n"); }#endif /* FALL THROUGH */ failure: state = xFAILED; break; } return(fbp->state[DIR_ENCRYPT-1] = state);}intcfb64_session(key, server) Session_Key *key; int server;{ return(fb64_session(key, server, &des_fb[CFB]));}intofb64_session(key, server) Session_Key *key; int server;{ return(fb64_session(key, server, &des_fb[OFB]));}static intfb64_session(key, server, fbp) Session_Key *key; int server; struct des_fb *fbp;{ int rc=0; int use2keys; struct des_stinfo * s_stream; struct des_stinfo * c_stream; if(server) { s_stream = &fbp->streams[DIR_ENCRYPT-1]; c_stream = &fbp->streams[DIR_DECRYPT-1]; } else { s_stream = &fbp->streams[DIR_DECRYPT-1]; c_stream = &fbp->streams[DIR_ENCRYPT-1]; } if (!key || key->length < sizeof(Block)) { CHAR buf[80]; sprintf(buf,"Can't set DES session key (%d < %d)", key ? key->length : 0, sizeof(Block)); /* safe */#ifdef DEBUG if (encrypt_debug_mode) printf("%s\r\n",buf);#endif debug(F110,"fb64_session",buf,0); return(-1); } use2keys = (key->type == SK_DES || key->length < 2 * sizeof(Block)) ? 0 : 1;#ifdef MIT_CURRENT if(use2keys) { memcpy((void *) fbp->keybytes, (void *) (key->data + sizeof(Block)), sizeof(Block)); des_fixup_key_parity(fbp->); fb64_stream_key(fbp->krbdes_key, s_stream); } memcpy((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block)); if (key->type != SK_DES) des_fixup_key_parity(fbp->krbdes_key); if(!use2keys) fb64_stream_key(fbp->krbdes_key, s_stream); fb64_stream_key(fbp->krbdes_key, c_stream); fbp->validkey = 1; fb64_stream_key(key->data, &fbp->streams[DIR_ENCRYPT-1]); fb64_stream_key(key->data, &fbp->streams[DIR_DECRYPT-1]);#else /* MIT_CURRENT */ if(use2keys) { memcpy((void *) fbp->krbdes_key, (void *) (key->data + sizeof(Block)), sizeof(Block)); des_fixup_key_parity(fbp->krbdes_key); fb64_stream_key(fbp->krbdes_key, s_stream); } memcpy((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block)); if (key->type != SK_DES) des_fixup_key_parity(fbp->krbdes_key); if(!use2keys) fb64_stream_key(fbp->krbdes_key, s_stream); fb64_stream_key(fbp->krbdes_key, c_stream); if (fbp->once == 0) { des_set_random_generator_seed(fbp->krbdes_key); fbp->once = 1; } memset(fbp->krbdes_sched,0,sizeof(Schedule)); hexdump("fb64_session_key",fbp->krbdes_key,8); rc = des_key_sched(fbp->krbdes_key, fbp->krbdes_sched); if ( rc == -1 ) { printf("?Invalid DES key specified for encryption\n"); debug(F110,"fb64_session_key", "invalid DES Key specified for encryption",0); } else if ( rc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -