Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DHE client implementation example #79

Open
Ayms opened this issue Oct 8, 2013 · 0 comments
Open

DHE client implementation example #79

Ayms opened this issue Oct 8, 2013 · 0 comments

Comments

@Ayms
Copy link

Ayms commented Oct 8, 2013

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;
            };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
1 participant