// see JCE spec
 protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random)
     throws InvalidKeyException, InvalidAlgorithmParameterException {
   byte[] ivValue;
   if (params != null) {
     if (params instanceof IvParameterSpec == false) {
       throw new InvalidAlgorithmParameterException("Only IvParameterSpec supported");
     }
     IvParameterSpec ivSpec = (IvParameterSpec) params;
     ivValue = ivSpec.getIV();
   } else {
     ivValue = null;
   }
   implInit(opmode, key, ivValue, random);
 }
 // see JCE spec
 protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
     throws InvalidKeyException, InvalidAlgorithmParameterException {
   byte[] ivValue;
   if (params != null) {
     try {
       IvParameterSpec ivSpec = (IvParameterSpec) params.getParameterSpec(IvParameterSpec.class);
       ivValue = ivSpec.getIV();
     } catch (InvalidParameterSpecException e) {
       throw new InvalidAlgorithmParameterException("Could not decode IV", e);
     }
   } else {
     ivValue = null;
   }
   implInit(opmode, key, ivValue, random);
 }
Beispiel #3
-1
  /*
   * Calculate the keys needed for this connection, once the session's
   * master secret has been calculated.  Uses the master key and nonces;
   * the amount of keying material generated is a function of the cipher
   * suite that's been negotiated.
   *
   * This gets called both on the "full handshake" (where we exchanged
   * a premaster secret and started a new session) as well as on the
   * "fast handshake" (where we just resumed a pre-existing session).
   */
  void calculateConnectionKeys(SecretKey masterKey) {
    /*
     * For both the read and write sides of the protocol, we use the
     * master to generate MAC secrets and cipher keying material.  Block
     * ciphers need initialization vectors, which we also generate.
     *
     * First we figure out how much keying material is needed.
     */
    int hashSize = cipherSuite.macAlg.size;
    boolean is_exportable = cipherSuite.exportable;
    BulkCipher cipher = cipherSuite.cipher;
    int expandedKeySize = is_exportable ? cipher.expandedKeySize : 0;

    // Which algs/params do we need to use?
    String keyMaterialAlg;
    PRF prf;

    if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
      keyMaterialAlg = "SunTls12KeyMaterial";
      prf = cipherSuite.prfAlg;
    } else {
      keyMaterialAlg = "SunTlsKeyMaterial";
      prf = P_NONE;
    }

    String prfHashAlg = prf.getPRFHashAlg();
    int prfHashLength = prf.getPRFHashLength();
    int prfBlockSize = prf.getPRFBlockSize();

    TlsKeyMaterialParameterSpec spec =
        new TlsKeyMaterialParameterSpec(
            masterKey,
            protocolVersion.major,
            protocolVersion.minor,
            clnt_random.random_bytes,
            svr_random.random_bytes,
            cipher.algorithm,
            cipher.keySize,
            expandedKeySize,
            cipher.ivSize,
            hashSize,
            prfHashAlg,
            prfHashLength,
            prfBlockSize);

    try {
      KeyGenerator kg = JsseJce.getKeyGenerator(keyMaterialAlg);
      kg.init(spec);
      TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec) kg.generateKey();

      clntWriteKey = keySpec.getClientCipherKey();
      svrWriteKey = keySpec.getServerCipherKey();

      // Return null if IVs are not supposed to be generated.
      // e.g. TLS 1.1+.
      clntWriteIV = keySpec.getClientIv();
      svrWriteIV = keySpec.getServerIv();

      clntMacSecret = keySpec.getClientMacKey();
      svrMacSecret = keySpec.getServerMacKey();
    } catch (GeneralSecurityException e) {
      throw new ProviderException(e);
    }

    //
    // Dump the connection keys as they're generated.
    //
    if (debug != null && Debug.isOn("keygen")) {
      synchronized (System.out) {
        HexDumpEncoder dump = new HexDumpEncoder();

        System.out.println("CONNECTION KEYGEN:");

        // Inputs:
        System.out.println("Client Nonce:");
        printHex(dump, clnt_random.random_bytes);
        System.out.println("Server Nonce:");
        printHex(dump, svr_random.random_bytes);
        System.out.println("Master Secret:");
        printHex(dump, masterKey.getEncoded());

        // Outputs:
        System.out.println("Client MAC write Secret:");
        printHex(dump, clntMacSecret.getEncoded());
        System.out.println("Server MAC write Secret:");
        printHex(dump, svrMacSecret.getEncoded());

        if (clntWriteKey != null) {
          System.out.println("Client write key:");
          printHex(dump, clntWriteKey.getEncoded());
          System.out.println("Server write key:");
          printHex(dump, svrWriteKey.getEncoded());
        } else {
          System.out.println("... no encryption keys used");
        }

        if (clntWriteIV != null) {
          System.out.println("Client write IV:");
          printHex(dump, clntWriteIV.getIV());
          System.out.println("Server write IV:");
          printHex(dump, svrWriteIV.getIV());
        } else {
          if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
            System.out.println("... no IV derived for this protocol");
          } else {
            System.out.println("... no IV used for this cipher");
          }
        }
        System.out.flush();
      }
    }
  }