Merge "Keymaster digest/padding NONE no longer means ANY." into mnc-dev

This commit is contained in:
Shawn Willden
2015-07-29 03:58:39 +00:00
committed by Android (Google) Code Review
5 changed files with 65 additions and 55 deletions

View File

@@ -63,7 +63,6 @@ import java.security.spec.ECGenParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -215,7 +214,14 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
KeyProperties.PURPOSE_SIGN
| KeyProperties.PURPOSE_VERIFY);
// Authorized to be used with any digest (including no digest).
specBuilder.setDigests(KeyProperties.DIGEST_NONE);
// MD5 was never offered for Android Keystore for ECDSA.
specBuilder.setDigests(
KeyProperties.DIGEST_NONE,
KeyProperties.DIGEST_SHA1,
KeyProperties.DIGEST_SHA224,
KeyProperties.DIGEST_SHA256,
KeyProperties.DIGEST_SHA384,
KeyProperties.DIGEST_SHA512);
break;
case KeymasterDefs.KM_ALGORITHM_RSA:
specBuilder = new KeyGenParameterSpec.Builder(
@@ -225,11 +231,23 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
| KeyProperties.PURPOSE_SIGN
| KeyProperties.PURPOSE_VERIFY);
// Authorized to be used with any digest (including no digest).
specBuilder.setDigests(KeyProperties.DIGEST_NONE);
specBuilder.setDigests(
KeyProperties.DIGEST_NONE,
KeyProperties.DIGEST_MD5,
KeyProperties.DIGEST_SHA1,
KeyProperties.DIGEST_SHA224,
KeyProperties.DIGEST_SHA256,
KeyProperties.DIGEST_SHA384,
KeyProperties.DIGEST_SHA512);
// Authorized to be used with any encryption and signature padding
// scheme (including no padding).
// schemes (including no padding).
specBuilder.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_NONE);
KeyProperties.ENCRYPTION_PADDING_NONE,
KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
KeyProperties.ENCRYPTION_PADDING_RSA_OAEP);
specBuilder.setSignaturePaddings(
KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
KeyProperties.SIGNATURE_PADDING_RSA_PSS);
// Disable randomized encryption requirement to support encryption
// padding NONE above.
specBuilder.setRandomizedEncryptionRequired(false);
@@ -724,27 +742,11 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
// We use Bouncy Castle to generate self-signed RSA certificates. Bouncy Castle
// only supports RSA certificates signed using PKCS#1 padding scheme. The key needs
// to be authorized for PKCS#1 padding or padding NONE which means any padding.
boolean pkcs1SignaturePaddingSupported = false;
for (int keymasterPadding : KeyProperties.SignaturePadding.allToKeymaster(
spec.getSignaturePaddings())) {
if ((keymasterPadding == KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN)
|| (keymasterPadding == KeymasterDefs.KM_PAD_NONE)) {
pkcs1SignaturePaddingSupported = true;
break;
}
}
if (!pkcs1SignaturePaddingSupported) {
// Keymaster doesn't distinguish between encryption padding NONE and signature
// padding NONE. In the Android Keystore API only encryption padding NONE is
// exposed.
for (int keymasterPadding : KeyProperties.EncryptionPadding.allToKeymaster(
spec.getEncryptionPaddings())) {
if (keymasterPadding == KeymasterDefs.KM_PAD_NONE) {
pkcs1SignaturePaddingSupported = true;
break;
}
}
}
boolean pkcs1SignaturePaddingSupported =
com.android.internal.util.ArrayUtils.contains(
KeyProperties.SignaturePadding.allToKeymaster(
spec.getSignaturePaddings()),
KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN);
if (!pkcs1SignaturePaddingSupported) {
// Key not authorized for PKCS#1 signature padding -- can't sign
return null;
@@ -803,14 +805,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
: KeyProperties.Digest.allToKeymaster(supportedSignatureDigests)) {
supportedKeymasterSignatureDigests.add(keymasterDigest);
}
if (authorizedKeymasterKeyDigests.contains(KeymasterDefs.KM_DIGEST_NONE)) {
// Key is authorized to be used with any digest
return supportedKeymasterSignatureDigests;
} else {
// Key is authorized to be used only with specific digests.
Set<Integer> result = new HashSet<Integer>(supportedKeymasterSignatureDigests);
result.retainAll(authorizedKeymasterKeyDigests);
return result;
}
Set<Integer> result = new HashSet<Integer>(supportedKeymasterSignatureDigests);
result.retainAll(authorizedKeymasterKeyDigests);
return result;
}
}

View File

@@ -292,7 +292,14 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
new KeyProtection.Builder(
KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY);
// Authorized to be used with any digest (including no digest).
specBuilder.setDigests(KeyProperties.DIGEST_NONE);
// MD5 was never offered for Android Keystore for ECDSA.
specBuilder.setDigests(
KeyProperties.DIGEST_NONE,
KeyProperties.DIGEST_SHA1,
KeyProperties.DIGEST_SHA224,
KeyProperties.DIGEST_SHA256,
KeyProperties.DIGEST_SHA384,
KeyProperties.DIGEST_SHA512);
} else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
specBuilder =
new KeyProtection.Builder(
@@ -301,13 +308,25 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
| KeyProperties.PURPOSE_SIGN
| KeyProperties.PURPOSE_VERIFY);
// Authorized to be used with any digest (including no digest).
specBuilder.setDigests(KeyProperties.DIGEST_NONE);
// Authorized to be used with any encryption and signature padding scheme (including no
// padding).
specBuilder.setDigests(
KeyProperties.DIGEST_NONE,
KeyProperties.DIGEST_MD5,
KeyProperties.DIGEST_SHA1,
KeyProperties.DIGEST_SHA224,
KeyProperties.DIGEST_SHA256,
KeyProperties.DIGEST_SHA384,
KeyProperties.DIGEST_SHA512);
// Authorized to be used with any encryption and signature padding
// schemes (including no padding).
specBuilder.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_NONE);
// Disable randomized encryption requirement to support encryption padding NONE
// above.
KeyProperties.ENCRYPTION_PADDING_NONE,
KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
KeyProperties.ENCRYPTION_PADDING_RSA_OAEP);
specBuilder.setSignaturePaddings(
KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
KeyProperties.SIGNATURE_PADDING_RSA_PSS);
// Disable randomized encryption requirement to support encryption
// padding NONE above.
specBuilder.setRandomizedEncryptionRequired(false);
} else {
throw new KeyStoreException("Unsupported key algorithm: " + keyAlgorithm);

View File

@@ -65,17 +65,16 @@ import javax.security.auth.x500.X500Principal;
*
* <p>NOTE: If a private key is not authorized to sign the self-signed certificate, then the
* certificate will be created with an invalid signature which will not verify. Such a certificate
* is still useful because it provides access to the public key. To generate a valid
* signature for the certificate the key needs to be authorized for all of the following:
* is still useful because it provides access to the public key. To generate a valid signature for
* the certificate the key needs to be authorized for all of the following:
* <ul>
* <li>{@link KeyProperties#PURPOSE_SIGN},</li>
* <li>operation without requiring the user to be authenticated (see
* {@link Builder#setUserAuthenticationRequired(boolean)}),</li>
* <li>signing/origination at this moment in time (see {@link Builder#setKeyValidityStart(Date)}
* and {@link Builder#setKeyValidityForOriginationEnd(Date)}),</li>
* <li>suitable digest or {@link KeyProperties#DIGEST_NONE},</li>
* <li>(RSA keys only) padding scheme {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1} or
* {@link KeyProperties#ENCRYPTION_PADDING_NONE}.</li>
* <li>suitable digest,</li>
* <li>(RSA keys only) padding scheme {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1}.</li>
* </ul>
*
* <p>NOTE: The key material of the generated symmetric and private keys is not accessible. The key
@@ -668,7 +667,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
*
* <p>For RSA private keys used by TLS/SSL servers to authenticate themselves to clients it
* is usually necessary to authorize the use of no/any padding
* ({@link KeyProperties#ENCRYPTION_PADDING_NONE}). This is because RSA decryption is
* ({@link KeyProperties#ENCRYPTION_PADDING_NONE}) and/or PKCS#1 encryption padding
* ({@link KeyProperties#ENCRYPTION_PADDING_RSA_PKCS1}). This is because RSA decryption is
* required by some cipher suites, and some stacks request decryption using no padding
* whereas others request PKCS#1 padding.
*

View File

@@ -364,9 +364,6 @@ public abstract class KeyProperties {
/**
* No encryption padding.
*
* <p><b>NOTE</b>: If a key is authorized to be used with no padding, then it can be used with
* any padding scheme, both for encryption and signing.
*/
public static final String ENCRYPTION_PADDING_NONE = "NoPadding";
@@ -513,9 +510,6 @@ public abstract class KeyProperties {
/**
* No digest: sign/authenticate the raw message.
*
* <p><b>NOTE</b>: If a key is authorized to be used with no digest, then it can be used with
* any digest.
*/
public static final String DIGEST_NONE = "NONE";

View File

@@ -386,7 +386,8 @@ public final class KeyProtection implements ProtectionParameter {
*
* <p>For RSA private keys used by TLS/SSL servers to authenticate themselves to clients it
* is usually necessary to authorize the use of no/any padding
* ({@link KeyProperties#ENCRYPTION_PADDING_NONE}). This is because RSA decryption is
* ({@link KeyProperties#ENCRYPTION_PADDING_NONE}) and/or PKCS#1 encryption padding
* ({@link KeyProperties#ENCRYPTION_PADDING_RSA_PKCS1}). This is because RSA decryption is
* required by some cipher suites, and some stacks request decryption using no padding
* whereas others request PKCS#1 padding.
*