summaryrefslogtreecommitdiff
path: root/src/main/javatest/com/google/security/cryptauth/lib/securegcm/KeyEncodingTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/javatest/com/google/security/cryptauth/lib/securegcm/KeyEncodingTest.java')
-rw-r--r--src/main/javatest/com/google/security/cryptauth/lib/securegcm/KeyEncodingTest.java189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/main/javatest/com/google/security/cryptauth/lib/securegcm/KeyEncodingTest.java b/src/main/javatest/com/google/security/cryptauth/lib/securegcm/KeyEncodingTest.java
new file mode 100644
index 0000000..7012eae
--- /dev/null
+++ b/src/main/javatest/com/google/security/cryptauth/lib/securegcm/KeyEncodingTest.java
@@ -0,0 +1,189 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.security.cryptauth.lib.securegcm;
+
+import com.google.security.cryptauth.lib.securemessage.PublicKeyProtoUtil;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.interfaces.DHPublicKey;
+import junit.framework.TestCase;
+
+/**
+ * Android compatible tests for the {@link KeyEncoding} class.
+ */
+public class KeyEncodingTest extends TestCase {
+ private static final byte[] RAW_KEY_BYTES = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2};
+
+ private Boolean isLegacy;
+ private KeyPair userKeyPair;
+
+ @Override
+ protected void setUp() throws Exception {
+ installSunEcSecurityProviderIfNecessary();
+ isLegacy = PublicKeyProtoUtil.isLegacyCryptoRequired();
+ setUserKeyPair();
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ KeyEncoding.setSimulateLegacyCrypto(false);
+ isLegacy = PublicKeyProtoUtil.isLegacyCryptoRequired();
+ super.tearDown();
+ }
+
+ private void setUserKeyPair() {
+ userKeyPair = isLegacy ? PublicKeyProtoUtil.generateRSA2048KeyPair()
+ : PublicKeyProtoUtil.generateEcP256KeyPair();
+ }
+
+ public void testSimulateLegacyCrypto() {
+ if (isLegacy) {
+ return; // Nothing to test if we are already stuck in a legacy platform
+ }
+ assertFalse(KeyEncoding.isLegacyCryptoRequired());
+ KeyEncoding.setSimulateLegacyCrypto(true);
+ assertTrue(KeyEncoding.isLegacyCryptoRequired());
+ }
+
+ public void testMasterKeyEncoding() {
+ // Require that master keys are encoded/decoded as raw byte arrays
+ assertTrue(Arrays.equals(
+ RAW_KEY_BYTES,
+ KeyEncoding.encodeMasterKey(KeyEncoding.parseMasterKey(RAW_KEY_BYTES))));
+ }
+
+ public void testUserPublicKeyEncoding() throws InvalidKeySpecException {
+ PublicKey pk = userKeyPair.getPublic();
+ byte[] encodedPk = KeyEncoding.encodeUserPublicKey(pk);
+ PublicKey decodedPk = KeyEncoding.parseUserPublicKey(encodedPk);
+ assertKeysEqual(pk, decodedPk);
+ }
+
+ public void testUserPrivateKeyEncoding() throws InvalidKeySpecException {
+ PrivateKey sk = userKeyPair.getPrivate();
+ byte[] encodedSk = KeyEncoding.encodeUserPrivateKey(sk);
+ PrivateKey decodedSk = KeyEncoding.parseUserPrivateKey(encodedSk, isLegacy);
+ assertKeysEqual(sk, decodedSk);
+ }
+
+ public void testKeyAgreementPublicKeyEncoding() throws InvalidKeySpecException {
+ KeyPair clientKeyPair = EnrollmentCryptoOps.generateEnrollmentKeyAgreementKeyPair(isLegacy);
+ PublicKey pk = clientKeyPair.getPublic();
+ byte[] encodedPk = KeyEncoding.encodeKeyAgreementPublicKey(pk);
+ PublicKey decodedPk = KeyEncoding.parseKeyAgreementPublicKey(encodedPk);
+ assertKeysEqual(pk, decodedPk);
+ }
+
+ public void testKeyAgreementPrivateKeyEncoding() throws InvalidKeySpecException {
+ KeyPair clientKeyPair = EnrollmentCryptoOps.generateEnrollmentKeyAgreementKeyPair(isLegacy);
+ PrivateKey sk = clientKeyPair.getPrivate();
+ byte[] encodedSk = KeyEncoding.encodeKeyAgreementPrivateKey(sk);
+ PrivateKey decodedSk = KeyEncoding.parseKeyAgreementPrivateKey(encodedSk, isLegacy);
+ assertKeysEqual(sk, decodedSk);
+ }
+
+ public void testEncodingsWithForcedLegacy() throws InvalidKeySpecException {
+ if (PublicKeyProtoUtil.isLegacyCryptoRequired()) {
+ // We already test with legacy in this case
+ return;
+ }
+ KeyEncoding.setSimulateLegacyCrypto(true);
+ isLegacy = true;
+ setUserKeyPair();
+ testUserPublicKeyEncoding();
+ testUserPrivateKeyEncoding();
+ testKeyAgreementPublicKeyEncoding();
+ testKeyAgreementPrivateKeyEncoding();
+ }
+
+ public void testSigningPublicKeyEncoding() throws InvalidKeySpecException {
+ KeyPair keyPair = PublicKeyProtoUtil.generateEcP256KeyPair();
+ PublicKey pk = keyPair.getPublic();
+ byte[] encodedPk = KeyEncoding.encodeSigningPublicKey(pk);
+ PublicKey decodedPk = KeyEncoding.parseSigningPublicKey(encodedPk);
+ assertKeysEqual(pk, decodedPk);
+ }
+
+ public void testSigningPrivateKeyEncoding() throws InvalidKeySpecException {
+ KeyPair keyPair = PublicKeyProtoUtil.generateEcP256KeyPair();
+ PrivateKey sk = keyPair.getPrivate();
+ byte[] encodedSk = KeyEncoding.encodeSigningPrivateKey(sk);
+ PrivateKey decodedSk = KeyEncoding.parseSigningPrivateKey(encodedSk);
+ assertKeysEqual(sk, decodedSk);
+ }
+
+ public void testDeviceSyncPublicKeyEncoding() throws InvalidKeySpecException {
+ KeyPair keyPair = PublicKeyProtoUtil.generateEcP256KeyPair();
+ PublicKey pk = keyPair.getPublic();
+ byte[] encodedPk = KeyEncoding.encodeDeviceSyncGroupPublicKey(pk);
+ PublicKey decodedPk = KeyEncoding.parseDeviceSyncGroupPublicKey(encodedPk);
+ assertKeysEqual(pk, decodedPk);
+ }
+
+ void assertKeysEqual(Key a, Key b) {
+ if ((a instanceof ECPublicKey)
+ || (a instanceof ECPrivateKey)
+ || (a instanceof RSAPublicKey)
+ || (a instanceof RSAPrivateKey)) {
+ assertNotNull(a.getEncoded());
+ assertTrue(Arrays.equals(a.getEncoded(), b.getEncoded()));
+ }
+ if (a instanceof DHPublicKey) {
+ DHPublicKey ya = (DHPublicKey) a;
+ DHPublicKey yb = (DHPublicKey) b;
+ assertEquals(ya.getY(), yb.getY());
+ assertEquals(ya.getParams().getG(), yb.getParams().getG());
+ assertEquals(ya.getParams().getP(), yb.getParams().getP());
+ }
+ if (a instanceof DHPrivateKey) {
+ DHPrivateKey xa = (DHPrivateKey) a;
+ DHPrivateKey xb = (DHPrivateKey) b;
+ assertEquals(xa.getX(), xb.getX());
+ assertEquals(xa.getParams().getG(), xb.getParams().getG());
+ assertEquals(xa.getParams().getP(), xb.getParams().getP());
+ }
+ }
+
+ /**
+ * Registers the SunEC security provider if no EC security providers are currently registered.
+ */
+ // TODO(shabsi): Remove this method when b/7891565 is fixed
+ static void installSunEcSecurityProviderIfNecessary() {
+ if (Security.getProviders("KeyPairGenerator.EC") == null) {
+ try {
+ Class<?> providerClass = Class.forName("sun.security.ec.SunEC");
+ Security.addProvider((Provider) providerClass.newInstance());
+ } catch (Exception e) {
+ // SunEC is not available, nothing we can do
+ }
+ }
+ }
+}