mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 722430 - Propagate NoSuchAlgorithmException and InvalidKeyException; wrap in CryptoException higher up the call stack. r=rnewman
This commit is contained in:
parent
0cca0b16db
commit
91bb310434
@ -1,102 +1,66 @@
|
|||||||
/* ***** BEGIN LICENSE BLOCK *****
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
*
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
* The contents of this file are subject to the Mozilla Public License Version
|
|
||||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
* http://www.mozilla.org/MPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
||||||
* for the specific language governing rights and limitations under the
|
|
||||||
* License.
|
|
||||||
*
|
|
||||||
* The Original Code is Android Sync Client.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is
|
|
||||||
* the Mozilla Foundation.
|
|
||||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
|
||||||
* the Initial Developer. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
* Jason Voll
|
|
||||||
*
|
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
||||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
||||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
||||||
* of those above. If you wish to allow use of your version of this file only
|
|
||||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
||||||
* use your version of this file under the terms of the MPL, indicate your
|
|
||||||
* decision by deleting the provisions above and replace them with the notice
|
|
||||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
||||||
* the provisions above, a recipient may use your version of this file under
|
|
||||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
||||||
*
|
|
||||||
* ***** END LICENSE BLOCK ***** */
|
|
||||||
|
|
||||||
package org.mozilla.gecko.sync.crypto;
|
package org.mozilla.gecko.sync.crypto;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All info in these objects should be decoded (i.e. not BaseXX encoded).
|
* All info in these objects should be decoded (i.e. not BaseXX encoded).
|
||||||
*/
|
*/
|
||||||
public class CryptoInfo {
|
public class CryptoInfo {
|
||||||
|
|
||||||
private byte[] message;
|
private byte[] message;
|
||||||
private byte[] iv;
|
private byte[] iv;
|
||||||
private byte[] hmac;
|
private byte[] hmac;
|
||||||
private KeyBundle keys;
|
private KeyBundle keys;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructor typically used when encrypting
|
* Constructor typically used when encrypting.
|
||||||
*/
|
*/
|
||||||
public CryptoInfo(byte[] message, KeyBundle keys) {
|
public CryptoInfo(byte[] message, KeyBundle keys) {
|
||||||
this.setMessage(message);
|
this.setMessage(message);
|
||||||
this.setKeys(keys);
|
this.setKeys(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructor typically used when decrypting
|
* Constructor typically used when decrypting.
|
||||||
*/
|
*/
|
||||||
public CryptoInfo(byte[] message, byte[] iv, byte[] hmac, KeyBundle keys) {
|
public CryptoInfo(byte[] message, byte[] iv, byte[] hmac, KeyBundle keys) {
|
||||||
this.setMessage(message);
|
this.setMessage(message);
|
||||||
this.setIV(iv);
|
this.setIV(iv);
|
||||||
this.setHMAC(hmac);
|
this.setHMAC(hmac);
|
||||||
this.setKeys(keys);
|
this.setKeys(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getMessage() {
|
public byte[] getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(byte[] message) {
|
public void setMessage(byte[] message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getIV() {
|
public byte[] getIV() {
|
||||||
return iv;
|
return iv;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIV(byte[] iv) {
|
public void setIV(byte[] iv) {
|
||||||
this.iv = iv;
|
this.iv = iv;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getHMAC() {
|
public byte[] getHMAC() {
|
||||||
return hmac;
|
return hmac;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHMAC(byte[] hmac) {
|
public void setHMAC(byte[] hmac) {
|
||||||
this.hmac = hmac;
|
this.hmac = hmac;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyBundle getKeys() {
|
public KeyBundle getKeys() {
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKeys(KeyBundle keys) {
|
|
||||||
this.keys = keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public void setKeys(KeyBundle keys) {
|
||||||
|
this.keys = keys;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ import javax.crypto.spec.SecretKeySpec;
|
|||||||
import org.mozilla.apache.commons.codec.binary.Base32;
|
import org.mozilla.apache.commons.codec.binary.Base32;
|
||||||
import org.mozilla.apache.commons.codec.binary.Base64;
|
import org.mozilla.apache.commons.codec.binary.Base64;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Implements the basic required cryptography options.
|
* Implements the basic required cryptography options.
|
||||||
@ -82,7 +83,6 @@ public class Cryptographer {
|
|||||||
cipher.init(Cipher.ENCRYPT_MODE, spec, new IvParameterSpec(info.getIV()));
|
cipher.init(Cipher.ENCRYPT_MODE, spec, new IvParameterSpec(info.getIV()));
|
||||||
}
|
}
|
||||||
} catch (GeneralSecurityException ex) {
|
} catch (GeneralSecurityException ex) {
|
||||||
ex.printStackTrace();
|
|
||||||
throw new CryptoException(ex);
|
throw new CryptoException(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +94,13 @@ public class Cryptographer {
|
|||||||
info.setIV(cipher.getIV());
|
info.setIV(cipher.getIV());
|
||||||
|
|
||||||
// Generate HMAC.
|
// Generate HMAC.
|
||||||
info.setHMAC(generateHMAC(info));
|
try {
|
||||||
|
info.setHMAC(generateHMAC(info));
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new CryptoException(e);
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
throw new CryptoException(e);
|
||||||
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
|
|
||||||
@ -112,8 +118,14 @@ public class Cryptographer {
|
|||||||
public static byte[] decrypt(CryptoInfo info) throws CryptoException {
|
public static byte[] decrypt(CryptoInfo info) throws CryptoException {
|
||||||
|
|
||||||
// Check HMAC.
|
// Check HMAC.
|
||||||
if (!verifyHMAC(info)) {
|
try {
|
||||||
throw new HMACVerificationException();
|
if (!verifyHMAC(info)) {
|
||||||
|
throw new HMACVerificationException();
|
||||||
|
}
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new CryptoException(e);
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
throw new CryptoException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cipher cipher = getCipher();
|
Cipher cipher = getCipher();
|
||||||
@ -190,7 +202,7 @@ public class Cryptographer {
|
|||||||
/*
|
/*
|
||||||
* Helper to verify HMAC Input: CryptoInfo Output: true if HMAC is correct
|
* Helper to verify HMAC Input: CryptoInfo Output: true if HMAC is correct
|
||||||
*/
|
*/
|
||||||
private static boolean verifyHMAC(CryptoInfo bundle) {
|
private static boolean verifyHMAC(CryptoInfo bundle) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||||
byte[] generatedHMAC = generateHMAC(bundle);
|
byte[] generatedHMAC = generateHMAC(bundle);
|
||||||
byte[] expectedHMAC = bundle.getHMAC();
|
byte[] expectedHMAC = bundle.getHMAC();
|
||||||
boolean eq = Arrays.equals(generatedHMAC, expectedHMAC);
|
boolean eq = Arrays.equals(generatedHMAC, expectedHMAC);
|
||||||
@ -206,7 +218,7 @@ public class Cryptographer {
|
|||||||
* Helper to generate HMAC Input: CryptoInfo Output: a generated HMAC for
|
* Helper to generate HMAC Input: CryptoInfo Output: a generated HMAC for
|
||||||
* given cipher text
|
* given cipher text
|
||||||
*/
|
*/
|
||||||
private static byte[] generateHMAC(CryptoInfo bundle) {
|
private static byte[] generateHMAC(CryptoInfo bundle) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||||
Mac hmacHasher = HKDF.makeHMACHasher(bundle.getKeys().getHMACKey());
|
Mac hmacHasher = HKDF.makeHMACHasher(bundle.getKeys().getHMACKey());
|
||||||
return hmacHasher.doFinal(Base64.encodeBase64(bundle.getMessage()));
|
return hmacHasher.doFinal(Base64.encodeBase64(bundle.getMessage()));
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,6 @@
|
|||||||
/* ***** BEGIN LICENSE BLOCK *****
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
*
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
* The contents of this file are subject to the Mozilla Public License Version
|
|
||||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
* http://www.mozilla.org/MPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
||||||
* for the specific language governing rights and limitations under the
|
|
||||||
* License.
|
|
||||||
*
|
|
||||||
* The Original Code is Android Sync Client.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is
|
|
||||||
* the Mozilla Foundation.
|
|
||||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
|
||||||
* the Initial Developer. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
* Jason Voll
|
|
||||||
*
|
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
||||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
||||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
||||||
* of those above. If you wish to allow use of your version of this file only
|
|
||||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
||||||
* use your version of this file under the terms of the MPL, indicate your
|
|
||||||
* decision by deleting the provisions above and replace them with the notice
|
|
||||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
||||||
* the provisions above, a recipient may use your version of this file under
|
|
||||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
||||||
*
|
|
||||||
* ***** END LICENSE BLOCK ***** */
|
|
||||||
|
|
||||||
package org.mozilla.gecko.sync.crypto;
|
package org.mozilla.gecko.sync.crypto;
|
||||||
|
|
||||||
@ -46,105 +13,99 @@ import javax.crypto.spec.SecretKeySpec;
|
|||||||
|
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A standards-compliant implementation of RFC 5869
|
* A standards-compliant implementation of RFC 5869
|
||||||
* for HMAC-based Key Derivation Function.
|
* for HMAC-based Key Derivation Function.
|
||||||
* HMAC uses HMAC SHA256 standard.
|
* HMAC uses HMAC SHA256 standard.
|
||||||
*/
|
*/
|
||||||
public class HKDF {
|
public class HKDF {
|
||||||
|
public static String HMAC_ALGORITHM = "hmacSHA256";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for conversion in cases in which you *know* the encoding exists.
|
* Used for conversion in cases in which you *know* the encoding exists.
|
||||||
*/
|
*/
|
||||||
public static final byte[] bytes(String in) {
|
public static final byte[] bytes(String in) {
|
||||||
try {
|
try {
|
||||||
return in.getBytes("UTF-8");
|
return in.getBytes("UTF-8");
|
||||||
} catch (java.io.UnsupportedEncodingException e) {
|
} catch (java.io.UnsupportedEncodingException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int BLOCKSIZE = 256 / 8;
|
||||||
|
public static final byte[] HMAC_INPUT = bytes("Sync-AES_256_CBC-HMAC256");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Step 1 of RFC 5869
|
||||||
|
* Get sha256HMAC Bytes
|
||||||
|
* Input: salt (message), IKM (input keyring material)
|
||||||
|
* Output: PRK (pseudorandom key)
|
||||||
|
*/
|
||||||
|
public static byte[] hkdfExtract(byte[] salt, byte[] IKM) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||||
|
return digestBytes(IKM, makeHMACHasher(salt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Step 2 of RFC 5869.
|
||||||
|
* Input: PRK from step 1, info, length.
|
||||||
|
* Output: OKM (output keyring material).
|
||||||
|
*/
|
||||||
|
public static byte[] hkdfExpand(byte[] prk, byte[] info, int len) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||||
|
Mac hmacHasher = makeHMACHasher(prk);
|
||||||
|
|
||||||
|
byte[] T = {};
|
||||||
|
byte[] Tn = {};
|
||||||
|
|
||||||
|
int iterations = (int) Math.ceil(((double)len) / ((double)BLOCKSIZE));
|
||||||
|
for (int i = 0; i < iterations; i++) {
|
||||||
|
Tn = digestBytes(Utils.concatAll(Tn, info, Utils.hex2Byte(Integer.toHexString(i + 1))),
|
||||||
|
hmacHasher);
|
||||||
|
T = Utils.concatAll(T, Tn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int BLOCKSIZE = 256 / 8;
|
byte[] result = new byte[len];
|
||||||
public static final byte[] HMAC_INPUT = bytes("Sync-AES_256_CBC-HMAC256");
|
System.arraycopy(T, 0, result, 0, len);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Step 1 of RFC 5869
|
* Make HMAC key
|
||||||
* Get sha256HMAC Bytes
|
* Input: key (salt)
|
||||||
* Input: salt (message), IKM (input keyring material)
|
* Output: Key HMAC-Key
|
||||||
* Output: PRK (pseudorandom key)
|
*/
|
||||||
*/
|
public static Key makeHMACKey(byte[] key) {
|
||||||
public static byte[] hkdfExtract(byte[] salt, byte[] IKM) {
|
if (key.length == 0) {
|
||||||
return digestBytes(IKM, makeHMACHasher(salt));
|
key = new byte[BLOCKSIZE];
|
||||||
}
|
}
|
||||||
|
return new SecretKeySpec(key, HMAC_ALGORITHM);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Step 2 of RFC 5869.
|
* Make an HMAC hasher
|
||||||
* Input: PRK from step 1, info, length.
|
* Input: Key hmacKey
|
||||||
* Output: OKM (output keyring material).
|
* Ouput: An HMAC Hasher
|
||||||
*/
|
*/
|
||||||
public static byte[] hkdfExpand(byte[] prk, byte[] info, int len) {
|
public static Mac makeHMACHasher(byte[] key) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||||
|
Mac hmacHasher = null;
|
||||||
|
hmacHasher = Mac.getInstance(HMAC_ALGORITHM);
|
||||||
|
|
||||||
Mac hmacHasher = makeHMACHasher(prk);
|
// If Mac.getInstance doesn't throw NoSuchAlgorithmException, hmacHasher is
|
||||||
|
// non-null.
|
||||||
|
assert(hmacHasher != null);
|
||||||
|
|
||||||
byte[] T = {};
|
hmacHasher.init(makeHMACKey(key));
|
||||||
byte[] Tn = {};
|
return hmacHasher;
|
||||||
|
}
|
||||||
|
|
||||||
int iterations = (int) Math.ceil(((double)len) / ((double)BLOCKSIZE));
|
/*
|
||||||
for (int i = 0; i < iterations; i++) {
|
* Hash bytes with given hasher
|
||||||
Tn = digestBytes(Utils.concatAll
|
* Input: message to hash, HMAC hasher
|
||||||
(Tn, info, Utils.hex2Byte(Integer.toHexString(i + 1))), hmacHasher);
|
* Output: hashed byte[].
|
||||||
T = Utils.concatAll(T, Tn);
|
*/
|
||||||
}
|
public static byte[] digestBytes(byte[] message, Mac hasher) {
|
||||||
|
hasher.update(message);
|
||||||
byte[] result = new byte[len];
|
byte[] ret = hasher.doFinal();
|
||||||
System.arraycopy(T, 0, result, 0, len);
|
hasher.reset();
|
||||||
return result;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Make HMAC key
|
|
||||||
* Input: key (salt)
|
|
||||||
* Output: Key HMAC-Key
|
|
||||||
*/
|
|
||||||
public static Key makeHMACKey(byte[] key) {
|
|
||||||
if (key.length == 0) {
|
|
||||||
key = new byte[BLOCKSIZE];
|
|
||||||
}
|
|
||||||
return new SecretKeySpec(key, "HmacSHA256");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make an HMAC hasher
|
|
||||||
* Input: Key hmacKey
|
|
||||||
* Ouput: An HMAC Hasher
|
|
||||||
*/
|
|
||||||
public static Mac makeHMACHasher(byte[] key) {
|
|
||||||
Mac hmacHasher = null;
|
|
||||||
try {
|
|
||||||
hmacHasher = Mac.getInstance("hmacSHA256");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
hmacHasher.init(makeHMACKey(key));
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return hmacHasher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Hash bytes with given hasher
|
|
||||||
* Input: message to hash, HMAC hasher
|
|
||||||
* Output: hashed byte[].
|
|
||||||
*/
|
|
||||||
public static byte[] digestBytes(byte[] message, Mac hasher) {
|
|
||||||
hasher.update(message);
|
|
||||||
byte[] ret = hasher.doFinal();
|
|
||||||
hasher.reset();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,8 @@ import javax.crypto.Mac;
|
|||||||
|
|
||||||
import org.mozilla.apache.commons.codec.binary.Base64;
|
import org.mozilla.apache.commons.codec.binary.Base64;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import org.mozilla.gecko.sync.crypto.CryptoException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
|
||||||
public class KeyBundle {
|
public class KeyBundle {
|
||||||
|
|
||||||
@ -86,7 +88,7 @@ public class KeyBundle {
|
|||||||
* encryption key and the second iteration the HMAC key.
|
* encryption key and the second iteration the HMAC key.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public KeyBundle(String username, String base32SyncKey) {
|
public KeyBundle(String username, String base32SyncKey) throws CryptoException {
|
||||||
if (base32SyncKey == null) {
|
if (base32SyncKey == null) {
|
||||||
throw new IllegalArgumentException("No sync key provided.");
|
throw new IllegalArgumentException("No sync key provided.");
|
||||||
}
|
}
|
||||||
@ -105,7 +107,15 @@ public class KeyBundle {
|
|||||||
byte[] syncKey = Utils.decodeFriendlyBase32(base32SyncKey);
|
byte[] syncKey = Utils.decodeFriendlyBase32(base32SyncKey);
|
||||||
byte[] user = username.getBytes();
|
byte[] user = username.getBytes();
|
||||||
|
|
||||||
Mac hmacHasher = HKDF.makeHMACHasher(syncKey);
|
Mac hmacHasher;
|
||||||
|
try {
|
||||||
|
hmacHasher = HKDF.makeHMACHasher(syncKey);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new CryptoException(e);
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
throw new CryptoException(e);
|
||||||
|
}
|
||||||
|
assert(hmacHasher != null); // If makeHMACHasher doesn't throw, then hmacHasher is non-null.
|
||||||
|
|
||||||
byte[] encrBytes = Utils.concatAll(EMPTY_BYTES, HKDF.HMAC_INPUT, user, ENCR_INPUT_BYTES);
|
byte[] encrBytes = Utils.concatAll(EMPTY_BYTES, HKDF.HMAC_INPUT, user, ENCR_INPUT_BYTES);
|
||||||
byte[] encrKey = HKDF.digestBytes(encrBytes, hmacHasher);
|
byte[] encrKey = HKDF.digestBytes(encrBytes, hmacHasher);
|
||||||
|
@ -344,7 +344,7 @@ public class SyncCryptographer {
|
|||||||
/*
|
/*
|
||||||
* Get the keys needed to encrypt the crypto/keys bundle.
|
* Get the keys needed to encrypt the crypto/keys bundle.
|
||||||
*/
|
*/
|
||||||
public KeyBundle getCryptoKeysBundleKeys() {
|
public KeyBundle getCryptoKeysBundleKeys() throws CryptoException {
|
||||||
return new KeyBundle(username, syncKey);
|
return new KeyBundle(username, syncKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,8 @@ import ch.boye.httpclientandroidlib.client.methods.HttpRequestBase;
|
|||||||
import ch.boye.httpclientandroidlib.entity.StringEntity;
|
import ch.boye.httpclientandroidlib.entity.StringEntity;
|
||||||
import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
|
import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
|
||||||
import ch.boye.httpclientandroidlib.message.BasicHeader;
|
import ch.boye.httpclientandroidlib.message.BasicHeader;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
|
||||||
public class JPakeClient implements JPakeRequestDelegate {
|
public class JPakeClient implements JPakeRequestDelegate {
|
||||||
private static String LOG_TAG = "JPakeClient";
|
private static String LOG_TAG = "JPakeClient";
|
||||||
@ -474,6 +476,14 @@ public class JPakeClient implements JPakeRequestDelegate {
|
|||||||
Log.e(LOG_TAG, "ZKP mismatch");
|
Log.e(LOG_TAG, "ZKP mismatch");
|
||||||
abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
|
abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
Log.e(LOG_TAG, "NoSuchAlgorithmException", e);
|
||||||
|
abort(Constants.JPAKE_ERROR_INTERNAL);
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
Log.e(LOG_TAG, "InvalidKeyException", e);
|
||||||
|
abort(Constants.JPAKE_ERROR_INTERNAL);
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pairWithPin) { // Wait for other device to send verification of keys.
|
if (pairWithPin) { // Wait for other device to send verification of keys.
|
||||||
|
@ -51,6 +51,7 @@ import org.mozilla.gecko.sync.crypto.HKDF;
|
|||||||
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
|
||||||
public class JPakeCrypto {
|
public class JPakeCrypto {
|
||||||
private static final String LOG_TAG = "JPakeCrypto";
|
private static final String LOG_TAG = "JPakeCrypto";
|
||||||
@ -174,7 +175,7 @@ public class JPakeCrypto {
|
|||||||
* @throws IncorrectZkpException
|
* @throws IncorrectZkpException
|
||||||
*/
|
*/
|
||||||
public static KeyBundle finalRound(String secret, JPakeParty jp)
|
public static KeyBundle finalRound(String secret, JPakeParty jp)
|
||||||
throws IncorrectZkpException {
|
throws IncorrectZkpException, NoSuchAlgorithmException, InvalidKeyException {
|
||||||
Log.d(LOG_TAG, "Final round started.");
|
Log.d(LOG_TAG, "Final round started.");
|
||||||
BigInteger gb = jp.gx1.multiply(jp.gx2).mod(P).multiply(jp.gx3)
|
BigInteger gb = jp.gx1.multiply(jp.gx2).mod(P).multiply(jp.gx3)
|
||||||
.mod(P);
|
.mod(P);
|
||||||
@ -321,12 +322,12 @@ public class JPakeCrypto {
|
|||||||
/*
|
/*
|
||||||
* Helper function to generate encryption key and HMAC from a byte array.
|
* Helper function to generate encryption key and HMAC from a byte array.
|
||||||
*/
|
*/
|
||||||
public static void generateKeyAndHmac(BigInteger k, byte[] encOut, byte[] hmacOut) {
|
public static void generateKeyAndHmac(BigInteger k, byte[] encOut, byte[] hmacOut) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||||
// Generate HMAC and Encryption keys from synckey.
|
// Generate HMAC and Encryption keys from synckey.
|
||||||
byte[] zerokey = new byte[32];
|
byte[] zerokey = new byte[32];
|
||||||
byte[] prk = HMACSHA256(BigIntegerHelper.BigIntegerToByteArrayWithoutSign(k), zerokey);
|
byte[] prk = HMACSHA256(BigIntegerHelper.BigIntegerToByteArrayWithoutSign(k), zerokey);
|
||||||
|
|
||||||
byte[] okm = HKDF.hkdfExpand(prk, HKDF.HMAC_INPUT, 32 * 2);
|
byte[] okm = HKDF.hkdfExpand(prk, HKDF.HMAC_INPUT, 32 * 2);
|
||||||
System.arraycopy(okm, 0, encOut, 0, 32);
|
System.arraycopy(okm, 0, encOut, 0, 32);
|
||||||
System.arraycopy(okm, 32, hmacOut, 0, 32);
|
System.arraycopy(okm, 32, hmacOut, 0, 32);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ public class BaseResource implements Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BaseResource(String uri, boolean rewrite) throws URISyntaxException {
|
public BaseResource(String uri, boolean rewrite) throws URISyntaxException {
|
||||||
this(new URI(uri), rewrite);
|
this(new URI(uri), rewrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseResource(URI uri, boolean rewrite) {
|
public BaseResource(URI uri, boolean rewrite) {
|
||||||
|
Loading…
Reference in New Issue
Block a user