Merge "Keymaster digest/padding NONE no longer means ANY." into mnc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a7b4d6dc10
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user