/* * Copyright (C) 2015 The Android Open Source Project * * 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 * * http://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 android.security; import android.content.Context; import android.text.TextUtils; import java.security.cert.Certificate; import java.security.spec.AlgorithmParameterSpec; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Set; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; /** * {@link AlgorithmParameterSpec} for initializing a {@code KeyGenerator} that works with * Android KeyStore facility. * *
The Android KeyStore facility is accessed through a {@link KeyGenerator} API * using the {@code AndroidKeyStore} provider. The {@code context} passed in may be used to pop up * some UI to ask the user to unlock or initialize the Android KeyStore facility. * *
After generation, the {@code keyStoreAlias} is used with the
* {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
* interface to retrieve the {@link SecretKey} and its associated {@link Certificate} chain.
*
* @hide
*/
public class KeyGeneratorSpec implements AlgorithmParameterSpec {
private final Context mContext;
private final String mKeystoreAlias;
private final int mFlags;
private final Integer mKeySize;
private final Date mKeyValidityStart;
private final Date mKeyValidityForOriginationEnd;
private final Date mKeyValidityForConsumptionEnd;
private final @KeyStoreKeyConstraints.PurposeEnum Integer mPurposes;
private final @KeyStoreKeyConstraints.PaddingEnum Integer mPadding;
private final @KeyStoreKeyConstraints.BlockModeEnum Integer mBlockMode;
private final Integer mMinSecondsBetweenOperations;
private final Integer mMaxUsesPerBoot;
private final Set The alias must be provided. There is no default.
*/
public Builder setAlias(String alias) {
if (alias == null) {
throw new NullPointerException("alias == null");
}
mKeystoreAlias = alias;
return this;
}
/**
* Sets the size (in bits) of the key to be generated.
*
* By default, the key size will be determines based on the key algorithm. For example,
* for {@code HmacSHA256}, the key size will default to {@code 256}.
*/
public Builder setKeySize(int keySize) {
mKeySize = keySize;
return this;
}
/**
* Indicates that this key must be encrypted at rest on storage. Note that enabling this
* will require that the user enable a strong lock screen (e.g., PIN, password) before
* creating or using the generated key is successful.
*/
public Builder setEncryptionRequired(boolean required) {
if (required) {
mFlags |= KeyStore.FLAG_ENCRYPTED;
} else {
mFlags &= ~KeyStore.FLAG_ENCRYPTED;
}
return this;
}
/**
* Sets the time instant before which the key is not yet valid.
*
* By default, the key is valid at any instant.
*
* @see #setKeyValidityEnd(Date)
*
* @hide
*/
public Builder setKeyValidityStart(Date startDate) {
mKeyValidityStart = startDate;
return this;
}
/**
* Sets the time instant after which the key is no longer valid.
*
* By default, the key is valid at any instant.
*
* @see #setKeyValidityStart(Date)
* @see #setKeyValidityForConsumptionEnd(Date)
* @see #setKeyValidityForOriginationEnd(Date)
*
* @hide
*/
public Builder setKeyValidityEnd(Date endDate) {
setKeyValidityForOriginationEnd(endDate);
setKeyValidityForConsumptionEnd(endDate);
return this;
}
/**
* Sets the time instant after which the key is no longer valid for encryption and signing.
*
* By default, the key is valid at any instant.
*
* @see #setKeyValidityForConsumptionEnd(Date)
*
* @hide
*/
public Builder setKeyValidityForOriginationEnd(Date endDate) {
mKeyValidityForOriginationEnd = endDate;
return this;
}
/**
* Sets the time instant after which the key is no longer valid for decryption and
* verification.
*
* By default, the key is valid at any instant.
*
* @see #setKeyValidityForOriginationEnd(Date)
*
* @hide
*/
public Builder setKeyValidityForConsumptionEnd(Date endDate) {
mKeyValidityForConsumptionEnd = endDate;
return this;
}
/**
* Restricts the purposes for which the key can be used to the provided set of purposes.
*
* By default, the key can be used for encryption, decryption, signing, and verification.
*
* @hide
*/
public Builder setPurposes(@KeyStoreKeyConstraints.PurposeEnum int purposes) {
mPurposes = purposes;
return this;
}
/**
* Restricts the key to being used only with the provided padding scheme. Attempts to use
* the key with any other padding will be rejected.
*
* This restriction must be specified for keys which are used for encryption/decryption.
*
* @hide
*/
public Builder setPadding(@KeyStoreKeyConstraints.PaddingEnum int padding) {
mPadding = padding;
return this;
}
/**
* Restricts the key to being used only with the provided block mode when encrypting or
* decrypting. Attempts to use the key with any other block modes will be rejected.
*
* This restriction must be specified for keys which are used for encryption/decryption.
*
* @hide
*/
public Builder setBlockMode(@KeyStoreKeyConstraints.BlockModeEnum int blockMode) {
mBlockMode = blockMode;
return this;
}
/**
* Sets the minimum number of seconds that must expire since the most recent use of the key
* before it can be used again.
*
* By default, there is no restriction on how frequently a key can be used.
*
* @hide
*/
public Builder setMinSecondsBetweenOperations(int seconds) {
mMinSecondsBetweenOperations = seconds;
return this;
}
/**
* Sets the maximum number of times a key can be used without rebooting the device.
*
* By default, the key can be used for an unlimited number of times.
*
* @hide
*/
public Builder setMaxUsesPerBoot(int count) {
mMaxUsesPerBoot = count;
return this;
}
/**
* Sets the user authenticators which protect access to this key. The key can only be used
* iff the user has authenticated to at least one of these user authenticators.
*
* By default, the key can be used without user authentication.
*
* @param userAuthenticators user authenticators or empty list if this key can be accessed
* without user authentication.
*
* @see #setUserAuthenticationValidityDurationSeconds(int)
*
* @hide
*/
public Builder setUserAuthenticators(Set By default, the user needs to authenticate for every use of the key.
*
* @param seconds duration in seconds or {@code 0} if the user needs to authenticate for
* every use of the key.
*
* @see #setUserAuthenticators(Set)
*
* @hide
*/
public Builder setUserAuthenticationValidityDurationSeconds(int seconds) {
mUserAuthenticationValidityDurationSeconds = seconds;
return this;
}
/**
* Sets whether this key must be invalidated (permanently) once a new fingerprint is
* enrolled. This only has effect if fingerprint reader is one of the user authenticators
* protecting access to the key.
*
* By default, enrolling a new fingerprint does not invalidate the key.
*
* @see #setUserAuthenticators(Set)
*
* @hide
*/
public Builder setInvalidatedOnNewFingerprintEnrolled(boolean invalidated) {
mInvalidatedOnNewFingerprintEnrolled = invalidated;
return this;
}
/**
* Builds a new instance instance of {@code KeyGeneratorSpec}.
*
* @throws IllegalArgumentException if a required field is missing or violates a constraint.
*/
public KeyGeneratorSpec build() {
return new KeyGeneratorSpec(mContext, mKeystoreAlias, mFlags, mKeySize,
mKeyValidityStart, mKeyValidityForOriginationEnd, mKeyValidityForConsumptionEnd,
mPurposes, mPadding, mBlockMode, mMinSecondsBetweenOperations, mMaxUsesPerBoot,
mUserAuthenticators, mUserAuthenticationValidityDurationSeconds,
mInvalidatedOnNewFingerprintEnrolled);
}
}
}