/** 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; }
/** * 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; } } }