Example usage for org.bouncycastle.util Arrays copyOfRange

List of usage examples for org.bouncycastle.util Arrays copyOfRange

Introduction

In this page you can find the example usage for org.bouncycastle.util Arrays copyOfRange.

Prototype

public static BigInteger[] copyOfRange(BigInteger[] original, int from, int to) 

Source Link

Usage

From source file:org.hyperledger.fabric.sdk.MemberServicesImpl.java

License:Open Source License

/**
 * Process a batch of tcerts after having retrieved them from the TCA.
 *///from   ww w . j a v  a  2  s .  c om
private List<TCert> processTCertBatch(GetTCertBatchRequest req, TCertCreateSetResp resp)
        throws NoSuchPaddingException, InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException,
        BadPaddingException, InvalidAlgorithmParameterException, CryptoException, IOException {
    String enrollKey = req.getEnrollment().getKey();
    byte[] tCertOwnerKDFKey = resp.getCerts().getKey().toByteArray();
    List<Ca.TCert> tCerts = resp.getCerts().getCertsList();

    byte[] byte1 = new byte[] { 1 };
    byte[] byte2 = new byte[] { 2 };

    byte[] tCertOwnerEncryptKey = Arrays.copyOfRange(cryptoPrimitives.calculateMac(tCertOwnerKDFKey, byte1), 0,
            32);
    byte[] expansionKey = cryptoPrimitives.calculateMac(tCertOwnerKDFKey, byte2);

    List<TCert> tCertBatch = new ArrayList<>(tCerts.size());

    // Loop through certs and extract private keys
    for (Ca.TCert tCert : tCerts) {
        X509Certificate x509Certificate;
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            x509Certificate = (X509Certificate) cf.generateCertificate(tCert.getCert().newInput());
        } catch (Exception ex) {
            logger.debug("Warning: problem parsing certificate bytes; retrying ... ", ex);
            continue;
        }

        // extract the encrypted bytes from extension attribute
        byte[] tCertIndexCT = fromDer(x509Certificate.getExtensionValue(TCERT_ENC_TCERT_INDEX));
        byte[] tCertIndex = cryptoPrimitives.aesCBCPKCS7Decrypt(tCertOwnerEncryptKey, tCertIndexCT);

        byte[] expansionValue = cryptoPrimitives.calculateMac(expansionKey, tCertIndex);

        // compute the private key
        BigInteger k = new BigInteger(1, expansionValue);
        BigInteger n = ((ECPrivateKey) cryptoPrimitives.ecdsaKeyFromPrivate(Hex.decode(enrollKey)))
                .getParameters().getN().subtract(BigInteger.ONE);
        k = k.mod(n).add(BigInteger.ONE);

        BigInteger D = ((ECPrivateKey) cryptoPrimitives.ecdsaKeyFromPrivate(Hex.decode(enrollKey))).getD()
                .add(k);
        D = D.mod(((ECPrivateKey) cryptoPrimitives.ecdsaKeyFromPrivate(Hex.decode(enrollKey))).getParameters()
                .getN());

        // Put private and public key in returned tcert
        TCert tcert = new TCert(tCert.getCert().toByteArray(), cryptoPrimitives.ecdsaKeyFromBigInt(D));

        tCertBatch.add(tcert);
    }

    if (tCertBatch.size() == 0) {
        throw new RuntimeException("Failed fetching TCertBatch. No valid TCert received.");
    }

    return tCertBatch;
}

From source file:org.hyperledger.fabric.sdk.security.CryptoPrimitives.java

License:Open Source License

public byte[] eciesDecrypt(KeyPair keyPair, byte[] data) throws CryptoException {
    try {/* www . j av  a 2s . c  o  m*/
        int ek_len = (int) (Math.floor((this.securityLevel + 7) / 8) * 2 + 1);
        int mk_len = this.securityLevel >> 3;
        int em_len = data.length - ek_len - mk_len;

        byte[] ephemeralPublicKeyBytes = Arrays.copyOfRange(data, 0, ek_len);
        byte[] encryptedMessage = Arrays.copyOfRange(data, ek_len, ek_len + em_len);
        byte[] tag = Arrays.copyOfRange(data, ek_len + em_len, data.length);

        // Parsing public key.
        ECParameterSpec asymmetricKeyParams = generateECParameterSpec();
        KeyFactory asymmetricKeyFactory = KeyFactory.getInstance(ASYMMETRIC_KEY_TYPE, SECURITY_PROVIDER);

        PublicKey ephemeralPublicKey = asymmetricKeyFactory.generatePublic(new ECPublicKeySpec(
                asymmetricKeyParams.getCurve().decodePoint(ephemeralPublicKeyBytes), asymmetricKeyParams));

        // Deriving shared secret.
        KeyAgreement keyAgreement = KeyAgreement.getInstance(KEY_AGREEMENT_ALGORITHM, SECURITY_PROVIDER);
        keyAgreement.init(keyPair.getPrivate());
        keyAgreement.doPhase(ephemeralPublicKey, true);
        byte[] sharedSecret = keyAgreement.generateSecret();

        // Deriving encryption and mac keys.
        HKDFBytesGenerator hkdfBytesGenerator = new HKDFBytesGenerator(getHashDigest());

        hkdfBytesGenerator.init(new HKDFParameters(sharedSecret, null, null));
        byte[] encryptionKey = new byte[SYMMETRIC_KEY_BYTE_COUNT];
        hkdfBytesGenerator.generateBytes(encryptionKey, 0, SYMMETRIC_KEY_BYTE_COUNT);

        byte[] macKey = new byte[MAC_KEY_BYTE_COUNT];
        hkdfBytesGenerator.generateBytes(macKey, 0, MAC_KEY_BYTE_COUNT);

        // Verifying Message Authentication Code (aka mac/tag)
        byte[] expectedTag = calculateMac(macKey, encryptedMessage);
        if (!Arrays.areEqual(tag, expectedTag)) {
            throw new RuntimeException("Bad Message Authentication Code!");
        }

        // Decrypting the message.
        byte[] iv = Arrays.copyOfRange(encryptedMessage, 0, 16);
        byte[] encrypted = Arrays.copyOfRange(encryptedMessage, 16, encryptedMessage.length);
        byte[] output = aesDecrypt(encryptionKey, iv, encrypted);

        return output;

    } catch (Exception e) {
        throw new CryptoException("Could not decrypt the message", e);
    }

}

From source file:org.osgp.pa.dlms.device.Hls5ConnectorLite.java

License:Open Source License

private DecryptedKeys decryptedKeys(final DlmsDevice dlmsDevice) throws TechnicalException, EncrypterException {
    // Decode the key from Hexstring to bytes
    byte[] authenticationKey = null;
    byte[] encryptionKey = null;
    try {//from   w  w w  .j  a  v  a  2  s  .  c  o m
        final String validAuthenticationKey = this.dlmsDevice.getAuthKey();
        final String validEncryptionKey = this.dlmsDevice.getEncKey();
        authenticationKey = Hex.decodeHex(validAuthenticationKey.toCharArray());
        encryptionKey = Hex.decodeHex(validEncryptionKey.toCharArray());
    } catch (final DecoderException e) {
        throw new EncrypterException(e);
    }

    // Decrypt the key, discard ivBytes
    byte[] decryptedAuthentication = ENCRYPTION_SRV.decrypt(authenticationKey);
    byte[] decryptedEncryption = ENCRYPTION_SRV.decrypt(encryptionKey);
    decryptedAuthentication = Arrays.copyOfRange(decryptedAuthentication, 16, decryptedAuthentication.length);
    decryptedEncryption = Arrays.copyOfRange(decryptedEncryption, 16, decryptedEncryption.length);

    return new DecryptedKeys(decryptedAuthentication, decryptedEncryption);
}

From source file:org.pieShare.pieShareClient.services.InputTask.java

private synchronized void newPacketReceived() {
    byte[] bytes = new byte[1024];
    bytes = Arrays.copyOfRange(bytes, 0, packet.getLength());
    PieLogger.info(this.getClass(), String.format("Input Message: %s", new String(bytes)));
    JsonObject input = processInput(bytes);

    if (input.getString("type").equals("connection")) {
        JsonObject newClient = input.getJsonObject("client");
        callback.Handle(newClient);//from   ww w .  ja  v  a  2  s  .c  o  m
    }
    if (input.getString("type").equals("msg")) {
        System.out.println("Message Arrived: " + input.getString("msg"));
    }
    if (input.getString("type").equals("punch")) {
        sendTask.send(ackMsg.getBytes(), packet.getAddress().getHostAddress(), packet.getPort());
    }
    if (input.getString("type").equals("ACK")) {
        sendTask.setACK(true);
    }
}

From source file:org.pieShare.pieShareServer.tasks.LoopHoleListenerTask.java

@Override
public void run() {
    PieLogger.info(this.getClass(), "Listener Started!");
    while (run) {

        byte[] bytes = new byte[1024];
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length);

        try {//from w  w w  .j a  v a 2  s  . c  om
            socket.receive(packet);
            bytes = Arrays.copyOfRange(packet.getData(), 0, packet.getLength());
            IUdpMessage msg = (IUdpMessage) serializerService.deserialize(bytes);
            InetSocketAddress address = new InetSocketAddress(packet.getAddress(), packet.getPort());
            msg.setSenderAddress(address);
            excuterService.handlePieEvent(msg);
        } catch (IOException ex) {
            PieLogger.error(this.getClass(), "Error receiving message.", ex);
        } catch (PieExecutorTaskFactoryException ex) {
            PieLogger.error(this.getClass(), "Error receiving message.", ex);
        } catch (SerializerServiceException ex) {
            PieLogger.error(this.getClass(), "Error receiving message.", ex);
        }
    }
}

From source file:org.pieShare.pieTools.piePlate.task.LoopHoleListenerTask.java

@Override
public void run() {
    while (run) {

        byte[] bytes = new byte[1024];
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length);

        try {//ww  w.  j a va 2s.co  m
            socket.receive(packet);
            bytes = Arrays.copyOfRange(packet.getData(), 0, packet.getLength());
            PieLogger.info(this.getClass(), String.format("Message Arrived: %s", new String(bytes)));

            IUdpMessage msg = (IUdpMessage) serializerService.deserialize(bytes);
            InetSocketAddress address = new InetSocketAddress(packet.getAddress(), packet.getPort());
            msg.setSenderAddress(address);
            excuterService.handlePieEvent(msg);
        } catch (IOException ex) {
            PieLogger.error(this.getClass(), "Error receiving message.", ex);
        } catch (PieExecutorTaskFactoryException ex) {
            PieLogger.error(this.getClass(), "Error receiving message.", ex);
        } catch (SerializerServiceException ex) {
            PieLogger.error(this.getClass(), "Error receiving message.", ex);
        }
    }
}

From source file:org.red5.server.net.rtmp.codec.RTMPMinaProtocolDecoder.java

License:Open Source License

/** {@inheritDoc} */
public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws ProtocolCodecException {
    // get the connection from the session
    String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID);
    log.trace("Session id: {}", sessionId);
    // connection verification routine
    @SuppressWarnings("unchecked")
    IConnectionManager<RTMPConnection> connManager = (IConnectionManager<RTMPConnection>) ((WeakReference<?>) session
            .getAttribute(RTMPConnection.RTMP_CONN_MANAGER)).get();
    RTMPConnection conn = (RTMPConnection) connManager.getConnectionBySessionId(sessionId);
    RTMPConnection connLocal = (RTMPConnection) Red5.getConnectionLocal();
    if (connLocal == null || !conn.getSessionId().equals(connLocal.getSessionId())) {
        if (log.isDebugEnabled() && connLocal != null) {
            log.debug("Connection local didn't match session");
        }/*from  w ww .j a  v a  2 s .c  om*/
    }
    if (conn != null) {
        // set the connection to local if its referred to by this session
        Red5.setConnectionLocal(conn);
        // create a buffer and store it on the session
        IoBuffer buf = (IoBuffer) session.getAttribute("buffer");
        if (buf == null) {
            buf = IoBuffer.allocate(in.limit());
            buf.setAutoExpand(true);
            session.setAttribute("buffer", buf);
        }
        // copy incoming into buffer
        buf.put(in);
        buf.flip();
        if (log.isTraceEnabled()) {
            log.trace("Buffer before: {}",
                    Hex.encodeHexString(Arrays.copyOfRange(buf.array(), buf.position(), buf.limit())));
            log.trace("Buffers info before: buf.position {}, buf.limit {}, buf.remaining {}",
                    new Object[] { buf.position(), buf.limit(), buf.remaining() });
        }
        // get the connections decoder lock
        final Semaphore lock = conn.getDecoderLock();
        try {
            // acquire the decoder lock
            //log.trace("Decoder lock acquiring.. {}", sessionId);
            lock.acquire();
            log.trace("Decoder lock acquired {}", sessionId);
            // construct any objects from the decoded bugger
            List<?> objects = decoder.decodeBuffer(conn, buf);
            log.trace("Decoded: {}", objects);
            if (objects != null) {
                int writeCount = 0;
                for (Object object : objects) {
                    out.write(object);
                    writeCount++;
                }
                log.trace("Wrote {} objects", writeCount);
            }
        } catch (Exception e) {
            log.error("Error during decode", e);
        } finally {
            log.trace("Decoder lock releasing.. {}", sessionId);
            lock.release();
            // clear local
            Red5.setConnectionLocal(null);
        }
        if (log.isTraceEnabled()) {
            log.trace("Buffer after: {}",
                    Hex.encodeHexString(Arrays.copyOfRange(buf.array(), buf.position(), buf.limit())));
            log.trace("Buffers info after: buf.position {}, buf.limit {}, buf.remaining {}",
                    new Object[] { buf.position(), buf.limit(), buf.remaining() });
        }
    } else {
        log.debug("Closing and skipping decode for unregistered connection: {}", sessionId);
        session.closeNow();
        log.debug("Session closing: {} reading: {} writing: {}", session.isClosing(), session.isReadSuspended(),
                session.isWriteSuspended());
    }
}

From source file:org.sufficientlysecure.keychain.experimental.WordConfirm.java

License:Open Source License

public static String getWords(Context context, byte[] fingerprintBlob) {
    ArrayList<String> words = new ArrayList<>();

    BufferedReader reader = null;
    try {//ww w.jav  a  2  s .c  o  m
        reader = new BufferedReader(
                new InputStreamReader(context.getResources().openRawResource(R.raw.fp_word_list), "UTF-8"));

        String line = reader.readLine();
        while (line != null) {
            words.add(line);

            line = reader.readLine();
        }
    } catch (IOException e) {
        throw new RuntimeException("IOException", e);
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException ignored) {
            }
        }
    }

    String fingerprint = "";

    // NOTE: 160 bit SHA-1 truncated to 156 bit
    byte[] fingerprintBlobTruncated = Arrays.copyOfRange(fingerprintBlob, 0, 156 / 8);

    // TODO: implement key stretching to minimize fp length?

    // BitSet bits = BitSet.valueOf(fingerprintBlob);  // min API 19 and little endian!
    BitSet bits = bitSetToByteArray(fingerprintBlobTruncated);
    Log.d(Constants.TAG, "bits: " + bits.toString());

    final int CHUNK_SIZE = 13;
    final int LAST_CHUNK_INDEX = fingerprintBlobTruncated.length * 8 / CHUNK_SIZE; // 12
    Log.d(Constants.TAG, "LAST_CHUNK_INDEX: " + LAST_CHUNK_INDEX);

    int from = 0;
    int to = CHUNK_SIZE;
    for (int i = 0; i < (LAST_CHUNK_INDEX + 1); i++) {
        Log.d(Constants.TAG, "from: " + from + " to: " + to);

        BitSet setIndex = bits.get(from, to);
        int wordIndex = (int) bitSetToLong(setIndex);
        // int wordIndex = (int) setIndex.toLongArray()[0]; // min API 19

        fingerprint += words.get(wordIndex);

        if (i != LAST_CHUNK_INDEX) {
            // line break every 3 words
            if (to % (CHUNK_SIZE * 3) == 0) {
                fingerprint += "\n";
            } else {
                fingerprint += " ";
            }
        }

        from = to;
        to += CHUNK_SIZE;
    }

    return fingerprint;
}

From source file:org.sufficientlysecure.keychain.securitytoken.SCP11bSecureMessaging.java

License:Open Source License

public static void establish(final SecurityTokenHelper t, final Context ctx)
        throws SecureMessagingException, IOException {

    final int keySize = t.getOpenPgpCapabilities().getSMAESKeySize();

    t.clearSecureMessaging();/*from  www  .j  av a 2s. c o  m*/

    if ((keySize != 16) && (keySize != 32)) {
        throw new SecureMessagingException("invalid key size");
    }

    CommandAPDU cmd;
    ResponseAPDU resp;
    Iso7816TLV[] tlvs;

    // retrieving key algorithm
    cmd = new CommandAPDU(0, (byte) 0xCA, (byte) 0x00, OPENPGP_SECURE_MESSAGING_KEY_ATTRIBUTES_TAG,
            SecurityTokenHelper.MAX_APDU_NE_EXT);
    resp = t.communicate(cmd);
    if (resp.getSW() != SecurityTokenHelper.APDU_SW_SUCCESS) {
        throw new SecureMessagingException("failed to retrieve secure messaging key attributes");
    }
    tlvs = Iso7816TLV.readList(resp.getData(), true);
    if ((tlvs == null) || (tlvs.length != 1)
            || ((byte) tlvs[0].mT != OPENPGP_SECURE_MESSAGING_KEY_ATTRIBUTES_TAG)) {
        throw new SecureMessagingException("invalid format of secure messaging key attributes");
    }

    final KeyFormat kf = KeyFormat.fromBytes(tlvs[0].mV);

    if (kf.keyFormatType() != KeyFormat.KeyFormatType.ECKeyFormatType) {
        throw new SecureMessagingException("invalid format of secure messaging key");
    }

    final ECKeyFormat eckf = (ECKeyFormat) kf;

    if (eckf.getCurveOID() == null) {
        throw new SecureMessagingException("unsupported curve");
    }

    try {
        ECPublicKey pkcard = null;

        final Preferences prefs = Preferences.getPreferences(ctx);

        if (prefs != null && prefs.getExperimentalSmartPGPAuthoritiesEnable()) {
            // retrieving certificate
            cmd = new CommandAPDU(0, (byte) 0xA5, (byte) 0x03, (byte) 0x04, new byte[] { (byte) 0x60,
                    (byte) 0x04, (byte) 0x5C, (byte) 0x02, (byte) 0x7F, (byte) 0x21 });
            resp = t.communicate(cmd);
            if (resp.getSW() != SecurityTokenHelper.APDU_SW_SUCCESS) {
                throw new SecureMessagingException("failed to select secure messaging certificate");
            }
            cmd = new CommandAPDU(0, (byte) 0xCA, (byte) 0x7F, (byte) 0x21,
                    SecurityTokenHelper.MAX_APDU_NE_EXT);
            resp = t.communicate(cmd);
            if (resp.getSW() != SecurityTokenHelper.APDU_SW_SUCCESS) {
                throw new SecureMessagingException("failed to retrieve secure messaging certificate");
            }

            pkcard = verifyCertificate(ctx, eckf, resp.getData());

        } else {
            // retrieving public key
            cmd = new CommandAPDU(0, (byte) 0x47, (byte) 0x81, (byte) 0x00, OPENPGP_SECURE_MESSAGING_KEY_CRT,
                    SecurityTokenHelper.MAX_APDU_NE_EXT);
            resp = t.communicate(cmd);
            if (resp.getSW() != SecurityTokenHelper.APDU_SW_SUCCESS) {
                throw new SecureMessagingException("failed to retrieve secure messaging public key");
            }
            tlvs = Iso7816TLV.readList(resp.getData(), true);
            if ((tlvs == null) || (tlvs.length != 1) || ((short) tlvs[0].mT != (short) 0x7f49)) {
                throw new SecureMessagingException("invalid format of secure messaging key");
            }
            tlvs = Iso7816TLV.readList(tlvs[0].mV, true);
            if ((tlvs == null) || (tlvs.length != 1) || ((byte) tlvs[0].mT != (byte) 0x86)) {
                throw new SecureMessagingException("invalid format of secure messaging key");
            }

            pkcard = newECDHPublicKey(eckf, tlvs[0].mV);
        }

        if (pkcard == null) {
            throw new SecureMessagingException("No key in token for secure messaging");
        }

        final KeyPair ekoce = generateECDHKeyPair(eckf);
        final ECPublicKey epkoce = (ECPublicKey) ekoce.getPublic();
        final ECPrivateKey eskoce = (ECPrivateKey) ekoce.getPrivate();

        final byte[] crt_template = new byte[] { (byte) 0xA6, (byte) 0x0D, (byte) 0x90, (byte) 0x02,
                (byte) 0x11, (byte) 0x00, (byte) 0x95, (byte) 0x01, (byte) 0x3C, (byte) 0x80, (byte) 0x01,
                (byte) 0x88, (byte) 0x81, (byte) 0x01, (byte) keySize, (byte) 0x5F, (byte) 0x49 };

        int csize = (int) Math.ceil(epkoce.getParams().getCurve().getField().getFieldSize() / 8.0);

        ByteArrayOutputStream pkout = new ByteArrayOutputStream(), bout = new ByteArrayOutputStream();

        pkout.write((byte) 0x04);
        SecurityTokenUtils.writeBits(pkout, epkoce.getW().getAffineX(), csize);
        SecurityTokenUtils.writeBits(pkout, epkoce.getW().getAffineY(), csize);

        bout.write(crt_template);
        bout.write(SecurityTokenUtils.encodeLength(pkout.size()));
        pkout.writeTo(bout);
        pkout = bout;

        // internal authenticate
        cmd = new CommandAPDU(0, (byte) 0x88, (byte) 0x01, (byte) 0x0, pkout.toByteArray(),
                SecurityTokenHelper.MAX_APDU_NE_EXT);
        resp = t.communicate(cmd);
        if (resp.getSW() != SecurityTokenHelper.APDU_SW_SUCCESS) {
            throw new SecureMessagingException("failed to initiate internal authenticate");
        }

        tlvs = Iso7816TLV.readList(resp.getData(), true);
        if ((tlvs == null) || (tlvs.length != 2) || (tlvs[0].mT == tlvs[1].mT)) {
            throw new SecureMessagingException("invalid internal authenticate response");
        }

        byte[] receipt = null;
        ECPublicKey epkcard = null;

        for (int i = 0; i < tlvs.length; ++i) {
            switch (tlvs[i].mT) {
            case 0x86:
                if (tlvs[i].mL != AES_BLOCK_SIZE) {
                    throw new SecureMessagingException("invalid size for receipt");
                }
                receipt = tlvs[i].mV;
                break;

            case 0x5F49:
                epkcard = newECDHPublicKey(eckf, tlvs[i].mV);
                break;

            default:
                throw new SecureMessagingException("unexpected data in internal authenticate response");
            }
        }

        final KeyAgreement ecdhKa = KeyAgreement.getInstance(SCP11B_KEY_AGREEMENT_ALGO, PROVIDER);
        bout = new ByteArrayOutputStream();

        //compute ShSe
        ecdhKa.init(eskoce);
        ecdhKa.doPhase(epkcard, true);
        bout.write(ecdhKa.generateSecret());

        //compute ShSs
        ecdhKa.init(eskoce);
        ecdhKa.doPhase(pkcard, true);
        bout.write(ecdhKa.generateSecret());

        csize = bout.size() + 3;

        bout.write(new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 0, crt_template[8], crt_template[11],
                (byte) keySize });

        byte[] shs = bout.toByteArray();

        //key derivation
        final MessageDigest h = MessageDigest.getInstance(SCP11B_KEY_DERIVATION_ALGO, PROVIDER);

        bout = new ByteArrayOutputStream();
        while (bout.size() < 4 * keySize) {
            ++shs[csize];
            bout.write(h.digest(shs));
        }

        shs = bout.toByteArray();

        final byte[] rkey = Arrays.copyOfRange(shs, 0, keySize);
        final byte[] sEnc = Arrays.copyOfRange(shs, keySize, 2 * keySize);
        final byte[] sMac = Arrays.copyOfRange(shs, 2 * keySize, 3 * keySize);
        final byte[] sRmac = Arrays.copyOfRange(shs, 3 * keySize, 4 * keySize);

        //receipt computation
        final Mac mac = Mac.getInstance(SCP11_MAC_ALGO, PROVIDER);

        mac.init(new SecretKeySpec(rkey, SCP11_SYMMETRIC_ALGO));

        shs = resp.getData();
        mac.update(pkout.toByteArray());
        mac.update(shs, 0, shs.length - 2 - AES_BLOCK_SIZE);
        shs = mac.doFinal();

        for (int i = 0; i < AES_BLOCK_SIZE; ++i) {
            if (shs[i] != receipt[i]) {
                throw new SecureMessagingException("corrupted receipt!");
            }
        }

        final SCP11bSecureMessaging sm = new SCP11bSecureMessaging();
        sm.setKeys(sEnc, sMac, sRmac, receipt);

        t.setSecureMessaging(sm);

    } catch (InvalidKeySpecException e) {
        throw new SecureMessagingException("invalid key specification : " + e.getMessage());
    } catch (NoSuchAlgorithmException e) {
        throw new SecureMessagingException("unknown EC key algorithm : " + e.getMessage());
    } catch (InvalidParameterSpecException e) {
        throw new SecureMessagingException("invalid ECDH parameters : " + e.getMessage());
    } catch (NoSuchProviderException e) {
        throw new SecureMessagingException("unknown provider " + PROVIDER);
    } catch (InvalidAlgorithmParameterException e) {
        throw new SecureMessagingException("invalid algorithm parameters : " + e.getMessage());
    } catch (InvalidKeyException e) {
        throw new SecureMessagingException("invalid key : " + e.getMessage());
    } catch (IllegalArgumentException e) {
        throw new SecureMessagingException("illegal argument (" + e.getMessage() + ")");
    }
}

From source file:org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection.java

License:Open Source License

/**
 * Call DECIPHER command/*  w  w  w  .jav a2s .c o  m*/
 *
 * @param encryptedSessionKey the encoded session key
 * @param publicKey
 * @return the decoded session key
 */
public byte[] decryptSessionKey(@NonNull byte[] encryptedSessionKey, CanonicalizedPublicKey publicKey)
        throws IOException {
    final KeyFormat kf = mOpenPgpCapabilities.getFormatForKeyType(KeyType.ENCRYPT);

    if (!mPw1ValidatedForDecrypt) {
        verifyPinForOther();
    }

    byte[] data;
    byte[] dataLen;
    int pLen = 0;

    X9ECParameters x9Params;

    switch (kf.keyFormatType()) {
    case RSAKeyFormatType:
        data = Arrays.copyOfRange(encryptedSessionKey, 2, encryptedSessionKey.length);
        if (data[0] != 0) {
            data = Arrays.prepend(data, (byte) 0x00);
        }
        break;

    case ECKeyFormatType:
        pLen = ((((encryptedSessionKey[0] & 0xff) << 8) + (encryptedSessionKey[1] & 0xff)) + 7) / 8;
        data = new byte[pLen];

        System.arraycopy(encryptedSessionKey, 2, data, 0, pLen);

        final ECKeyFormat eckf = (ECKeyFormat) kf;
        x9Params = NISTNamedCurves.getByOID(eckf.getCurveOID());

        final ECPoint p = x9Params.getCurve().decodePoint(data);
        if (!p.isValid()) {
            throw new CardException("Invalid EC point!");
        }

        data = p.getEncoded(false);

        if (data.length < 128) {
            dataLen = new byte[] { (byte) data.length };
        } else {
            dataLen = new byte[] { (byte) 0x81, (byte) data.length };
        }
        data = Arrays.concatenate(Hex.decode("86"), dataLen, data);

        if (data.length < 128) {
            dataLen = new byte[] { (byte) data.length };
        } else {
            dataLen = new byte[] { (byte) 0x81, (byte) data.length };
        }
        data = Arrays.concatenate(Hex.decode("7F49"), dataLen, data);

        if (data.length < 128) {
            dataLen = new byte[] { (byte) data.length };
        } else {
            dataLen = new byte[] { (byte) 0x81, (byte) data.length };
        }
        data = Arrays.concatenate(Hex.decode("A6"), dataLen, data);
        break;

    default:
        throw new CardException("Unknown encryption key type!");
    }

    CommandApdu command = commandFactory.createDecipherCommand(data);
    ResponseApdu response = communicate(command);

    if (!response.isSuccess()) {
        throw new CardException("Deciphering with Security token failed on receive", response.getSw());
    }

    switch (mOpenPgpCapabilities.getFormatForKeyType(KeyType.ENCRYPT).keyFormatType()) {
    case RSAKeyFormatType:
        return response.getData();

    /* From 3.x OpenPGP card specification :
       In case of ECDH the card supports a partial decrypt only.
       With its own private key and the given public key the card calculates a shared secret
       in compliance with the Elliptic Curve Key Agreement Scheme from Diffie-Hellman.
       The shared secret is returned in the response, all other calculation for deciphering
       are done outside of the card.
            
       The shared secret obtained is a KEK (Key Encryption Key) that is used to wrap the
       session key.
            
       From rfc6637#section-13 :
       This document explicitly discourages the use of algorithms other than AES as a KEK algorithm.
       */
    case ECKeyFormatType:
        data = response.getData();

        final byte[] keyEnc = new byte[encryptedSessionKey[pLen + 2]];

        System.arraycopy(encryptedSessionKey, 2 + pLen + 1, keyEnc, 0, keyEnc.length);

        try {
            final MessageDigest kdf = MessageDigest
                    .getInstance(MessageDigestUtils.getDigestName(publicKey.getSecurityTokenHashAlgorithm()));

            kdf.update(new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 1 });
            kdf.update(data);
            kdf.update(publicKey.createUserKeyingMaterial(fingerprintCalculator));

            final byte[] kek = kdf.digest();
            final Cipher c = Cipher.getInstance("AESWrap");

            c.init(Cipher.UNWRAP_MODE,
                    new SecretKeySpec(kek, 0, publicKey.getSecurityTokenSymmetricKeySize() / 8, "AES"));

            final Key paddedSessionKey = c.unwrap(keyEnc, "Session", Cipher.SECRET_KEY);

            Arrays.fill(kek, (byte) 0);

            return PGPPad.unpadSessionData(paddedSessionKey.getEncoded());
        } catch (NoSuchAlgorithmException e) {
            throw new CardException("Unknown digest/encryption algorithm!");
        } catch (NoSuchPaddingException e) {
            throw new CardException("Unknown padding algorithm!");
        } catch (PGPException e) {
            throw new CardException(e.getMessage());
        } catch (InvalidKeyException e) {
            throw new CardException("Invalid KEK!");
        }

    default:
        throw new CardException("Unknown encryption key type!");
    }
}