-
Notifications
You must be signed in to change notification settings - Fork 831
Open
Description
Before I move to something else, please see below, add to forge DHE_TLS_RSA_WITH_AES_128/256_CBC_SHA, in case someone is interested one day, sorry for the code, it's messy (modified on minified code + mixing my buffers and forge's one), but it's quite easy to understand I believe, without the comments only a few lines were modified/added, the TODO (check signature + server side) should not be very difficult.
var DHE_handleServerKeyExchange=function(c, record, length) {
// this implementation only supports RSA, no Diffie-Hellman support
// so any length > 0 is invalid
if(length > 0) {
/*
select (KeyExchangeAlgorithm) {
case dh_anon:
ServerDHParams params;
case dhe_dss:
case dhe_rsa:
ServerDHParams params;
digitally-signed struct {
opaque client_random[32];
opaque server_random[32];
ServerDHParams params;
} signed_params;
case rsa:
case dh_dss:
case dh_rsa:
struct {} ;
message is omitted for rsa, dh_dss, and dh_rsa
may be extended, e.g., for ECDH -- see [TLSECC]
} ServerKeyExchange;
struct { Lenght 2 bytes + data
opaque dh_p<1..2^16-1>;
opaque dh_g<1..2^16-1>;
opaque dh_Ys<1..2^16-1>;
} ServerDHParams;
dh_p
The prime modulus used for the Diffie-Hellman operation.
dh_g
The generator used for the Diffie-Hellman operation.
dh_Ys
The server's Diffie-Hellman public value (g^X mod p).
*/
var b=record.fragment;
var dhe=c.session.sp.DHE={};
dhe.prime=b.getBytes(b.getInt(16));
//alert((new Buffer(prime,'binary')).toString('hex'));
dhe.g=b.getBytes(b.getInt(16));
dhe.server_public_key=b.getBytes(b.getInt(16));
dhe.signature=b.getBytes(b.getInt(16));
//TODO check signature
}
//else {
// expect an optional CertificateRequest message next
c.expect = L;
// continue
c.process();
//}
};
var DHE_createClientKeyExchange = function(ac) {
/*
createSecurityParameters modified
switch(ac.session.cipherSuite) {
case g.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA:
keyLength = 16;
break;
case g.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA:
keyLength = 32;
break;
}
struct {
select (KeyExchangeAlgorithm) {
case rsa:
EncryptedPreMasterSecret;
case dhe_dss:
case dhe_rsa:
case dh_dss:
case dh_rsa:
case dh_anon:
ClientDiffieHellmanPublic;
} exchange_keys;
} ClientKeyExchange;
struct {
select (PublicValueEncoding) {
case implicit: struct { };
case explicit: opaque dh_Yc<1..2^16-1>;
} dh_public;
} ClientDiffieHellmanPublic;
dh_Yc
The client's Diffie-Hellman public value (Yc).
*/
// create buffer to encrypt
var aa = ac.session.sp;
var X;
if (!aa.DHE) {
// add highest client-supported protocol to help server avoid version
// rollback attacks
X = N.util.createBuffer();
X.putByte(g.Version.major);
X.putByte(g.Version.minor);
// generate and add 46 random bytes
X.putBytes(N.random.getBytes(46));
// save pre-master secret
aa.pre_master_secret = X.getBytes();
// RSA-encrypt the pre-master secret
var Y = ac.session.serverCertificate.publicKey;
X = Y.encrypt(aa.pre_master_secret);
/* Note: The encrypted pre-master secret will be stored in a
public-key-encrypted opaque vector that has the length prefixed using
2 bytes, so include those 2 bytes in the handshake message length. This
is done as a minor optimization instead of calling writeVector(). */
} else {
var dhe=aa.DHE;
var client_key=new BigInteger(Rand(128).toString('hex'),16);
var prime=new BigInteger(new Buffer(dhe.prime,'binary').toString('hex'),16);
var gdh=new BigInteger(new Buffer(dhe.g,'binary').toString('hex'),16);
var server_key=new BigInteger(new Buffer(dhe.server_public_key,'binary').toString('hex'),16);
var sec=new Buffer(server_key.modPow(client_key,prime).toString(16),'hex');
aa.pre_master_secret=sec.toString('binary');
//console.log('Pre Master: '+sec.toString('hex'));
X=new Buffer(gdh.modPow(client_key,prime).toString(16),'hex');
//console.log('Client public key: '+X.toString('hex'));
};
// determine length of the handshake message
var Z = X.length + 2;
// build record fragment
var ab = N.util.createBuffer();
ab.putByte(g.HandshakeType.client_key_exchange);
ab.putInt24(Z);
// add vector length bytes
ab.putInt16(X.length);
ab.putBytes(X);
return ab;
};Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels