int AsymmCipher::encrypt(PrnGen &rng, const byte* plain, int plainlen, byte* buf, int buflen) { if ((int)key[PUB_PQ].ByteCount() + 2 > buflen) { return 0; } if (buf != plain) { memcpy(buf, plain, plainlen); } // add random padding rng.genblock(buf + plainlen, key[PUB_PQ].ByteCount() - plainlen - 2); Integer t(buf, key[PUB_PQ].ByteCount() - 2); rsaencrypt(key, &t); int i = t.BitCount(); byte* ptr = buf; *ptr++ = (byte)(i >> 8); *ptr++ = (byte)i; i = t.ByteCount(); while (i--) { *ptr++ = t.GetByte(i); } return int(ptr - buf); }
int AsymmCipher::encrypt(const byte* plain, int plainlen, byte* buf, int buflen) { if ((int)key[0].ByteCount()+2 > buflen) return 0; if (buf != plain) memcpy(buf,plain,plainlen); // add random padding PrnGen::genblock(buf+plainlen,key[0].ByteCount()-plainlen-2); Integer t(buf,key[0].ByteCount()-2); rsaencrypt(key,&t); int i = t.BitCount(); byte* ptr = buf; *ptr++ = (byte)(i >> 8); *ptr++ = (byte)i; i = t.ByteCount(); while (i--) *ptr++ = t.GetByte(i); return ptr-buf; }
int rsaverify(RSApub *key, DigestAlg *hash, uchar *digest, uint dlen, uchar *sig, uint siglen) { uchar asn1[512], *buf; int n, len, pad; mpint *m, *mm, *s; /* * Create ASN.1 */ n = mkasn1(asn1, hash, digest, dlen); /* * Create number to sign. */ len = (mpsignif(key->n)+7)/8 - 1; if(len < n+2) { werrstr("rsa key too short"); return -1; } pad = len - (n+2); if(siglen < len) { werrstr("signature buffer too short"); return -1; } buf = malloc(len); if(buf == nil) return -1; buf[0] = 0x01; memset(buf+1, 0xFF, pad); buf[1+pad] = 0x00; memmove(buf+1+pad+1, asn1, n); m = betomp(buf, len, nil); free(buf); if(m == nil) return -1; /* * Extract plaintext of signature. */ s = betomp(sig, siglen, nil); if(s == nil) return -1; mm = rsaencrypt(key, s, nil); mpfree(s); if(mm == nil) return -1; if(mpcmp(m, mm) != 0) { werrstr("signature did not verify"); mpfree(mm); mpfree(m); return -1; } mpfree(mm); mpfree(m); return 0; }
static int rsa_verify(mpint* m, void *sig, void *key) { mpint *t; int r; t = rsaencrypt((RSApub*)key, (mpint*)sig, nil); r = mpcmp(t, m) == 0; mpfree(t); return r; }
unsigned AsymmCipher::rawencrypt(const byte* plain, int plainlen, byte* buf, int buflen) { Integer t(plain,plainlen); rsaencrypt(key,&t); int i = t.ByteCount(); if (i > buflen) return 0; while (i--) *buf++ = t.GetByte(i); return t.ByteCount(); }
static void ssh_protocol(unsigned char *in, int inlen, int ispkt) { int i, j, len; unsigned char session_id[16]; unsigned char *rsabuf, *keystr1, *keystr2; unsigned char cookie[8]; struct RSAKey servkey, hostkey; struct MD5Context md5c; unsigned long supported_ciphers_mask; int cipher_type; extern struct ssh_cipher ssh_3des; extern struct ssh_cipher ssh_blowfish; crBegin; random_init(); while (!ispkt) crReturnV; if (pktin.type != 2) fatalbox("Public key packet not received"); memcpy(cookie, pktin.body, 8); MD5Init(&md5c); i = makekey(pktin.body+8, &servkey, &keystr1); j = makekey(pktin.body+8+i, &hostkey, &keystr2); supported_ciphers_mask = (pktin.body[12+i+j] << 24) | (pktin.body[13+i+j] << 16) | (pktin.body[14+i+j] << 8) | (pktin.body[15+i+j]); MD5Update(&md5c, keystr2, hostkey.bytes); MD5Update(&md5c, keystr1, servkey.bytes); MD5Update(&md5c, pktin.body, 8); MD5Final(session_id, &md5c); for (i=0; i<32; i++) session_key[i] = random_byte(); len = (hostkey.bytes > servkey.bytes ? hostkey.bytes : servkey.bytes); rsabuf = malloc(len); if (!rsabuf) fatalbox("Out of memory"); verify_ssh_host_key(savedhost, &hostkey); for (i=0; i<32; i++) { rsabuf[i] = session_key[i]; if (i < 16) rsabuf[i] ^= session_id[i]; } if (hostkey.bytes > servkey.bytes) { rsaencrypt(rsabuf, 32, &servkey); rsaencrypt(rsabuf, servkey.bytes, &hostkey); } else { rsaencrypt(rsabuf, 32, &hostkey); rsaencrypt(rsabuf, hostkey.bytes, &servkey); } cipher_type = cfg.cipher == CIPHER_BLOWFISH ? SSH_CIPHER_BLOWFISH : SSH_CIPHER_3DES; if ((supported_ciphers_mask & (1 << cipher_type)) == 0) { c_write("Selected cipher not supported, falling back to 3DES\r\n", 53); cipher_type = SSH_CIPHER_3DES; } s_wrpkt_start(3, len+15); pktout.body[0] = cipher_type; memcpy(pktout.body+1, cookie, 8); pktout.body[9] = (len*8) >> 8; pktout.body[10] = (len*8) & 0xFF; memcpy(pktout.body+11, rsabuf, len); pktout.body[len+11] = pktout.body[len+12] = 0; /* protocol flags */ pktout.body[len+13] = pktout.body[len+14] = 0; s_wrpkt(); free(rsabuf); cipher = cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish : &ssh_3des; cipher->sesskey(session_key); do { crReturnV; } while (!ispkt); if (pktin.type != 14) fatalbox("Encryption not successfully enabled"); fflush(stdout); { static char username[100]; static int pos = 0; static char c; if (!*cfg.username) { c_write("login as: ", 10); while (pos >= 0) { do { crReturnV; } while (ispkt); while (inlen--) switch (c = *in++) { case 10: case 13: username[pos] = 0; pos = -1; break; case 8: case 127: if (pos > 0) { c_write("\b \b", 3); pos--; } break; case 21: case 27: while (pos > 0) { c_write("\b \b", 3); pos--; } break; case 3: case 4: random_save_seed(); exit(0); break; default: if (c >= ' ' && c <= '~' && pos < 40) { username[pos++] = c; c_write(&c, 1); } break; } } c_write("\r\n", 2); username[strcspn(username, "\n\r")] = '\0'; } else { char stuff[200]; strncpy(username, cfg.username, 99); username[99] = '\0'; sprintf(stuff, "Sent username \"%s\".\r\n", username); c_write(stuff, strlen(stuff)); } s_wrpkt_start(4, 4+strlen(username)); pktout.body[0] = pktout.body[1] = pktout.body[2] = 0; pktout.body[3] = strlen(username); memcpy(pktout.body+4, username, strlen(username)); s_wrpkt(); } do { crReturnV; } while (!ispkt); while (pktin.type == 15) { static char password[100]; static int pos; static char c; c_write("password: "******"\r\n", 2); s_wrpkt_start(9, 4+strlen(password)); pktout.body[0] = pktout.body[1] = pktout.body[2] = 0; pktout.body[3] = strlen(password); memcpy(pktout.body+4, password, strlen(password)); s_wrpkt(); memset(password, 0, strlen(password)); do { crReturnV; } while (!ispkt); if (pktin.type == 15) { c_write("Access denied\r\n", 15); } else if (pktin.type != 14) { fatalbox("Strange packet received, type %d", pktin.type); } } if (!cfg.nopty) { i = strlen(cfg.termtype); s_wrpkt_start(10, i+5*4+1); pktout.body[0] = (i >> 24) & 0xFF; pktout.body[1] = (i >> 16) & 0xFF; pktout.body[2] = (i >> 8) & 0xFF; pktout.body[3] = i & 0xFF; memcpy(pktout.body+4, cfg.termtype, i); i += 4; pktout.body[i++] = (rows >> 24) & 0xFF; pktout.body[i++] = (rows >> 16) & 0xFF; pktout.body[i++] = (rows >> 8) & 0xFF; pktout.body[i++] = rows & 0xFF; pktout.body[i++] = (cols >> 24) & 0xFF; pktout.body[i++] = (cols >> 16) & 0xFF; pktout.body[i++] = (cols >> 8) & 0xFF; pktout.body[i++] = cols & 0xFF; memset(pktout.body+i, 0, 9); /* 0 pixwidth, 0 pixheight, 0.b endofopt */ s_wrpkt(); ssh_state = SSH_STATE_INTERMED; do { crReturnV; } while (!ispkt); if (pktin.type != 14 && pktin.type != 15) { fatalbox("Protocol confusion"); } else if (pktin.type == 15) { c_write("Server refused to allocate pty\r\n", 32); } }