/** Creates and sends Finished message */
 @DSGenerator(
     tool_name = "Doppelganger",
     tool_version = "2.0",
     generated_on = "2013-12-30 13:01:10.428 -0500",
     hash_original_method = "8B073BF3F8F00875CF9B653567C3900A",
     hash_generated_method = "782E43CE43B7326AF0F4F50C66FB2FDB")
 @Override
 protected void makeFinished() {
   byte[] verify_data;
   if (serverHello.server_version[1] == 1) {
     verify_data = new byte[12];
     computerVerifyDataTLS("client finished", verify_data);
   } else {
     verify_data = new byte[36];
     computerVerifyDataSSLv3(SSLv3Constants.client, verify_data);
   }
   clientFinished = new Finished(verify_data);
   send(clientFinished);
   if (isResuming) {
     session.lastAccessedTime = System.currentTimeMillis();
     status = FINISHED;
   } else {
     if (serverHello.server_version[1] == 1) {
       computerReferenceVerifyDataTLS("server finished");
     } else {
       computerReferenceVerifyDataSSLv3(SSLv3Constants.server);
     }
     status = NEED_UNWRAP;
   }
 }
  @DSComment("Private Method")
  @DSBan(DSCat.PRIVATE_METHOD)
  @DSGenerator(
      tool_name = "Doppelganger",
      tool_version = "2.0",
      generated_on = "2013-12-30 13:00:13.241 -0500",
      hash_original_method = "03E7802E2319FF252715B6886182CABF",
      hash_generated_method = "792D08AC6A43E9804EEE0BCE0AF8FF5D")
  private Vector generateOcts() {
    Vector vec = new Vector();
    for (int i = 0; i < string.length; i += MAX_LENGTH) {
      int end;

      if (i + MAX_LENGTH > string.length) {
        end = string.length;
      } else {
        end = i + MAX_LENGTH;
      }

      byte[] nStr = new byte[end - i];

      System.arraycopy(string, i, nStr, 0, nStr.length);

      vec.addElement(new DEROctetString(nStr));
    }

    return vec;
  }
Example #3
0
  /**
   * Build adn hex byte array based on record size The format of byte array is defined in 51.011
   * 10.5.1
   *
   * @param recordSize is the size X of EF record
   * @return hex byte[recordSize] to be written to EF record return null for wrong format of dialing
   *     number or tag
   */
  @DSSource({DSSourceKind.NETWORK})
  @DSGenerator(
      tool_name = "Doppelganger",
      tool_version = "2.0",
      generated_on = "2013-12-30 12:59:17.039 -0500",
      hash_original_method = "43E5A3A3017D389C996FCD504E7A9103",
      hash_generated_method = "E3F599972D04B8E5D7F86AB1411559E9")
  public byte[] buildAdnString(int recordSize) {
    byte[] bcdNumber;
    byte[] byteTag;
    byte[] adnString;
    int footerOffset = recordSize - FOOTER_SIZE_BYTES;

    // create an empty record
    adnString = new byte[recordSize];
    for (int i = 0; i < recordSize; i++) {
      adnString[i] = (byte) 0xFF;
    }

    if (TextUtils.isEmpty(number)) {
      Log.w(LOG_TAG, "[buildAdnString] Empty dialing number");
      return adnString; // return the empty record (for delete)
    } else if (number.length() > (ADN_DIALING_NUMBER_END - ADN_DIALING_NUMBER_START + 1) * 2) {
      Log.w(LOG_TAG, "[buildAdnString] Max length of dialing number is 20");
      return null;
    } else if (alphaTag != null && alphaTag.length() > footerOffset) {
      Log.w(LOG_TAG, "[buildAdnString] Max length of tag is " + footerOffset);
      return null;
    } else {
      bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(number);

      System.arraycopy(bcdNumber, 0, adnString, footerOffset + ADN_TON_AND_NPI, bcdNumber.length);

      adnString[footerOffset + ADN_BCD_NUMBER_LENGTH] = (byte) (bcdNumber.length);
      adnString[footerOffset + ADN_CAPABILITY_ID] = (byte) 0xFF; // Capability Id
      adnString[footerOffset + ADN_EXTENSION_ID] = (byte) 0xFF; // Extension Record Id

      if (!TextUtils.isEmpty(alphaTag)) {
        byteTag = GsmAlphabet.stringToGsm8BitPacked(alphaTag);
        System.arraycopy(byteTag, 0, adnString, 0, byteTag.length);
      }

      return adnString;
    }
  }
 @DSGenerator(
     tool_name = "Doppelganger",
     tool_version = "2.0",
     generated_on = "2013-12-30 12:34:11.148 -0500",
     hash_original_method = "CF45914111E05D752375948053626E9D",
     hash_generated_method = "DB8631F608D962E1CC5946A6A27F962A")
 @Override
 public void growArray(int oldSize, int newSize) {
   super.growArray(oldSize, newSize);
   final int[][] newStateSets = new int[newSize][];
   System.arraycopy(mStateSets, 0, newStateSets, 0, oldSize);
   mStateSets = newStateSets;
 }
 /** Add a field with the specified value. */
 @DSGenerator(
     tool_name = "Doppelganger",
     tool_version = "2.0",
     generated_on = "2013-12-30 13:02:32.316 -0500",
     hash_original_method = "438CB3F0D3B01507EC959AE5277C1434",
     hash_generated_method = "D618B8A0B8645A63526CEA5B342F57A5")
 public void add(String fieldName, String value) {
   if (fieldName == null) {
     throw new IllegalArgumentException("fieldName == null");
   }
   if (value == null) {
     /*
      * Given null values, the RI sends a malformed field line like
      * "Accept\r\n". For platform compatibility and HTTP compliance, we
      * print a warning and ignore null values.
      */
     System.logW("Ignoring HTTP header field '" + fieldName + "' because its value is null");
     return;
   }
   namesAndValues.add(fieldName);
   namesAndValues.add(value.trim());
 }
  /**
   * Processes ServerHelloDone: makes verification of the server messages; sends client messages,
   * computers masterSecret, sends ChangeCipherSpec
   */
  @DSComment("Package priviledge")
  @DSBan(DSCat.DEFAULT_MODIFIER)
  @DSGenerator(
      tool_name = "Doppelganger",
      tool_version = "2.0",
      generated_on = "2013-12-30 13:01:10.434 -0500",
      hash_original_method = "2DDF37E22088D1FE8BC73EB3CA83F3A0",
      hash_generated_method = "D2F899ECF0C8F0AF7307958FBF03F0A2")
  void processServerHelloDone() {
    PrivateKey clientKey = null;

    if (serverCert != null) {
      if (session.cipherSuite.isAnonymous()) {
        unexpectedMessage();
        return;
      }
      verifyServerCert();
    } else {
      if (!session.cipherSuite.isAnonymous()) {
        unexpectedMessage();
        return;
      }
    }

    // Client certificate
    if (certificateRequest != null) {
      X509Certificate[] certs = null;
      // obtain certificates from key manager
      String alias = null;
      String[] certTypes = certificateRequest.getTypesAsString();
      X500Principal[] issuers = certificateRequest.certificate_authorities;
      X509KeyManager km = parameters.getKeyManager();
      if (km instanceof X509ExtendedKeyManager) {
        X509ExtendedKeyManager ekm = (X509ExtendedKeyManager) km;
        if (this.socketOwner != null) {
          alias = ekm.chooseClientAlias(certTypes, issuers, this.socketOwner);
        } else {
          alias = ekm.chooseEngineClientAlias(certTypes, issuers, this.engineOwner);
        }
        if (alias != null) {
          certs = ekm.getCertificateChain(alias);
        }
      } else {
        alias = km.chooseClientAlias(certTypes, issuers, this.socketOwner);
        if (alias != null) {
          certs = km.getCertificateChain(alias);
        }
      }

      session.localCertificates = certs;
      clientCert = new CertificateMessage(certs);
      clientKey = km.getPrivateKey(alias);
      send(clientCert);
    }
    // Client key exchange
    if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA
        || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
      // RSA encrypted premaster secret message
      Cipher c;
      try {
        c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        if (serverKeyExchange != null) {
          c.init(Cipher.ENCRYPT_MODE, serverKeyExchange.getRSAPublicKey());
        } else {
          c.init(Cipher.ENCRYPT_MODE, serverCert.certs[0]);
        }
      } catch (Exception e) {
        fatalAlert(AlertProtocol.INTERNAL_ERROR, "Unexpected exception", e);
        return;
      }
      preMasterSecret = new byte[48];
      parameters.getSecureRandom().nextBytes(preMasterSecret);
      System.arraycopy(clientHello.client_version, 0, preMasterSecret, 0, 2);
      try {
        clientKeyExchange =
            new ClientKeyExchange(c.doFinal(preMasterSecret), serverHello.server_version[1] == 1);
      } catch (Exception e) {
        fatalAlert(AlertProtocol.INTERNAL_ERROR, "Unexpected exception", e);
        return;
      }
    } else {
      try {
        KeyFactory kf = KeyFactory.getInstance("DH");
        KeyAgreement agreement = KeyAgreement.getInstance("DH");
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
        PublicKey serverPublic;
        DHParameterSpec spec;
        if (serverKeyExchange != null) {
          serverPublic =
              kf.generatePublic(
                  new DHPublicKeySpec(
                      serverKeyExchange.par3, serverKeyExchange.par1, serverKeyExchange.par2));
          spec = new DHParameterSpec(serverKeyExchange.par1, serverKeyExchange.par2);
        } else {
          serverPublic = serverCert.certs[0].getPublicKey();
          spec = ((DHPublicKey) serverPublic).getParams();
        }
        kpg.initialize(spec);

        KeyPair kp = kpg.generateKeyPair();
        Key key = kp.getPublic();
        if (clientCert != null
            && serverCert != null
            && (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA
                || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS)) {
          PublicKey client_pk = clientCert.certs[0].getPublicKey();
          PublicKey server_pk = serverCert.certs[0].getPublicKey();
          if (client_pk instanceof DHKey && server_pk instanceof DHKey) {
            if (((DHKey) client_pk)
                    .getParams()
                    .getG()
                    .equals(((DHKey) server_pk).getParams().getG())
                && ((DHKey) client_pk)
                    .getParams()
                    .getP()
                    .equals(((DHKey) server_pk).getParams().getG())) {
              // client cert message DH public key parameters
              // matched those specified by the
              //   server in its certificate,
              clientKeyExchange = new ClientKeyExchange(); // empty
            }
          }
        } else {
          clientKeyExchange = new ClientKeyExchange(((DHPublicKey) key).getY());
        }
        key = kp.getPrivate();
        agreement.init(key);
        agreement.doPhase(serverPublic, true);
        preMasterSecret = agreement.generateSecret();
      } catch (Exception e) {
        fatalAlert(AlertProtocol.INTERNAL_ERROR, "Unexpected exception", e);
        return;
      }
    }
    if (clientKeyExchange != null) {
      send(clientKeyExchange);
    }

    computerMasterSecret();

    // send certificate verify for all certificates except those containing
    // fixed DH parameters
    if (clientCert != null && !clientKeyExchange.isEmpty()) {
      // Certificate verify
      String authType = clientKey.getAlgorithm();
      DigitalSignature ds = new DigitalSignature(authType);
      ds.init(clientKey);

      if ("RSA".equals(authType)) {
        ds.setMD5(io_stream.getDigestMD5());
        ds.setSHA(io_stream.getDigestSHA());
      } else if ("DSA".equals(authType)) {
        ds.setSHA(io_stream.getDigestSHA());
        // The Signature should be empty in case of anonymous signature algorithm:
        // } else if ("DH".equals(authType)) {
      }
      certificateVerify = new CertificateVerify(ds.sign());
      send(certificateVerify);
    }

    sendChangeCipherSpec();
  }
  /**
   * Processes inbound handshake messages
   *
   * @param bytes
   */
  @DSGenerator(
      tool_name = "Doppelganger",
      tool_version = "2.0",
      generated_on = "2013-12-30 13:01:10.423 -0500",
      hash_original_method = "A389390FF4680222C458E1D6E9083717",
      hash_generated_method = "4F35B217867E297BC43CAC891648AAE5")
  @Override
  public void unwrap(byte[] bytes) {
    if (this.delegatedTaskErr != null) {
      Exception e = this.delegatedTaskErr;
      this.delegatedTaskErr = null;
      this.fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Error in delegated task", e);
    }
    int handshakeType;
    io_stream.append(bytes);
    while (io_stream.available() > 0) {
      io_stream.mark();
      int length;
      try {
        handshakeType = io_stream.read();
        length = io_stream.readUint24();
        if (io_stream.available() < length) {
          io_stream.reset();
          return;
        }
        switch (handshakeType) {
          case 0: // HELLO_REQUEST
            // we don't need to take this message into account
            // during FINISH message verification, so remove it
            io_stream.removeFromMarkedPosition();
            if (clientHello != null && (clientFinished == null || serverFinished == null)) {
              // currently negotiating - ignore
              break;
            }
            // renegotiate
            if (session.isValid()) {
              session = (SSLSessionImpl) session.clone();
              isResuming = true;
              startSession();
            } else {
              // if SSLSession is invalidated (e.g. timeout limit is
              // exceeded) connection can't resume the session.
              renegotiateNewSession();
            }
            break;
          case 2: // SERVER_HELLO
            if (clientHello == null || serverHello != null) {
              unexpectedMessage();
              return;
            }
            serverHello = new ServerHello(io_stream, length);

            // check protocol version
            ProtocolVersion servProt = ProtocolVersion.getByVersion(serverHello.server_version);
            String[] enabled = parameters.getEnabledProtocols();
            find:
            {
              for (int i = 0; i < enabled.length; i++) {
                if (servProt.equals(ProtocolVersion.getByName(enabled[i]))) {
                  break find;
                }
              }
              fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Bad server hello protocol version");
            }

            // check compression method
            if (serverHello.compression_method != 0) {
              fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Bad server hello compression method");
            }

            // check cipher_suite
            CipherSuite[] enabledSuites = parameters.getEnabledCipherSuitesMember();
            find:
            {
              for (int i = 0; i < enabledSuites.length; i++) {
                if (serverHello.cipher_suite.equals(enabledSuites[i])) {
                  break find;
                }
              }
              fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Bad server hello cipher suite");
            }

            if (isResuming) {
              if (serverHello.session_id.length == 0) {
                // server is not willing to establish the new connection
                // using specified session
                isResuming = false;
              } else if (!Arrays.equals(serverHello.session_id, clientHello.session_id)) {
                isResuming = false;
              } else if (!session.protocol.equals(servProt)) {
                fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Bad server hello protocol version");
              } else if (!session.cipherSuite.equals(serverHello.cipher_suite)) {
                fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Bad server hello cipher suite");
              }
              if (serverHello.server_version[1] == 1) {
                computerReferenceVerifyDataTLS("server finished");
              } else {
                computerReferenceVerifyDataSSLv3(SSLv3Constants.server);
              }
            }
            session.protocol = servProt;
            recordProtocol.setVersion(session.protocol.version);
            session.cipherSuite = serverHello.cipher_suite;
            session.id = serverHello.session_id.clone();
            session.serverRandom = serverHello.random;
            break;
          case 11: // CERTIFICATE
            if (serverHello == null
                || serverKeyExchange != null
                || serverCert != null
                || isResuming) {
              unexpectedMessage();
              return;
            }
            serverCert = new CertificateMessage(io_stream, length);
            break;
          case 12: // SERVER_KEY_EXCHANGE
            if (serverHello == null || serverKeyExchange != null || isResuming) {
              unexpectedMessage();
              return;
            }
            serverKeyExchange =
                new ServerKeyExchange(io_stream, length, session.cipherSuite.keyExchange);
            break;
          case 13: // CERTIFICATE_REQUEST
            if (serverCert == null
                || certificateRequest != null
                || session.cipherSuite.isAnonymous()
                || isResuming) {
              unexpectedMessage();
              return;
            }
            certificateRequest = new CertificateRequest(io_stream, length);
            break;
          case 14: // SERVER_HELLO_DONE
            if (serverHello == null || serverHelloDone != null || isResuming) {
              unexpectedMessage();
              return;
            }
            serverHelloDone = new ServerHelloDone(io_stream, length);
            if (this.nonBlocking) {
              delegatedTasks.add(
                  new DelegatedTask(
                      new Runnable() {
                        @DSSafe(DSCat.SAFE_LIST)
                        public void run() {
                          processServerHelloDone();
                        }
                      },
                      this));
              return;
            }
            processServerHelloDone();
            break;
          case 20: // FINISHED
            if (!changeCipherSpecReceived) {
              unexpectedMessage();
              return;
            }
            serverFinished = new Finished(io_stream, length);
            verifyFinished(serverFinished.getData());
            session.lastAccessedTime = System.currentTimeMillis();
            session.context = parameters.getClientSessionContext();
            parameters.getClientSessionContext().putSession(session);
            if (isResuming) {
              sendChangeCipherSpec();
            } else {
              session.lastAccessedTime = System.currentTimeMillis();
              status = FINISHED;
            }
            // XXX there is no cleanup work
            break;
          default:
            unexpectedMessage();
            return;
        }
      } catch (IOException e) {
        // io stream dosn't contain complete handshake message
        io_stream.reset();
        return;
      }
    }
  }