Container Key Renewal
The operation (Container.renew) can be used to renew the container keys without having to perform activation again or interrupting an existing service in the case of expiration. All keys are renewed during this operation.
Key Renewal Trigger
The decision to trigger the keys renewal can be taken by the application based on the following information:
Container.isRenewable() will return a boolean that states if the container can be renewed. A container can be renewed if the:
- HID authentication platform supports this operation
- “Transport Key for Mobile Service communications” key (CT_SMK4 credential type) is still valid
- Container.getRenewalDate() will return the date by which the keys must be renewed for container to be fully functional (support might be limited or not working after this date)
This date corresponds to the shortest key from this container
- The limit date for key renewal is the expiration date of the “Transport Key for Mobile Service communications” key (CT_SMK4 credential type)
After this date, key renewal is no longer possible
It is recommended that the Key Renewal operation happens before the RenewalDate.Announcement.
For further details, see:
ActivID AS Credential Type Parameters
ActivID Appliance Credential Type Parameters
HID Authentication Service Credential Parameters
Key Renewal Processing and Result
- As with container provisioning, key renewal is a time-consuming operation.
- After key renewal, the container remains the same, but all previous keys have been deleted, and new keys have been created for this container just as if this was a brand-new container (created using the current HID authentication platform configuration).
-
A container key renewal operation can be used to apply an update to the protection policy configuration used for the initial container creation (for example, enabling biometrics or updating password complexity requirements). However, these changes will not be enforced for a user's current password and will only be applied after an explicit call to change password. An integrator can choose to wait until password expiration or to trigger the change password immediately after the key renewal operation depending on the desired workflow.
-
The original creation date of the container can be retrieved using Container.getOriginalCreationDate()
-
For security (non-repudiation), a password-protected container is required to provide the password to trigger the renewal operation:
-
This can be done by populating the ContainerRenewal structure or provided via the EventListener callback
-
For biometric-enabled containers, the end user will be prompted by the system for a standard biometric authentication
-
For device-protected policies, the password is not required
-
if (currentContainer.isRenewable(null)) {
val containerRenewal = ContainerRenewal()
containerRenewal.pushId = pushId
// To renew the container, we need the password which protects it.
// You can either bypass the password prompt by filling the password through the containerRenewal setPassword,
// Or by using the PasswordPromptEvent ( similar to createContainer )
// Biometric-enabled containers will automatically prompt
if (containerPassword != null) {
containerRenewal.password = containerPassword.toCharArray()
}
// The listener works the same way than the createContainer.
val myEventListener =
EventListener { event ->
if (event is PasswordPromptEvent) {
val prompt = PasswordPromptResult(EventResult.Code.Continue)
prompt.password = containerPassword.toCharArray()
return@EventListener prompt
}
null
}
// We can proceed to the renew :
try {
currentContainer.renew(containerRenewal, null, myEventListener)
println("container has been renewed")
} catch (ex: Exception) {
when(ex) {
is AuthenticationException -> { // Password is incorrect
ex.printStackTrace()
}
is PasswordExpiredException, is UnsupportedDeviceException, is InternalException, is AuthenticationException,
is RemoteException, is UnsafeDeviceException, is ServerProtocolException , is FingerprintAuthenticationRequiredException,
is FingerprintNotEnrolledException, is LostCredentialsException, is PasswordRequiredException , is CredentialsExpiredException,
is ServerUnsupportedOperationException, is GooglePlayServicesObsoleteException, is PasswordCancelledException , is ServerOperationFailedException,
is InvalidParameterException -> {
ex.printStackTrace()
}
else -> throw ex
}
}
finally {
// Good practice, the reset operation will nullify sensitive datas.
containerRenewal.reset()
}
}
if (currentContainer.isRenewable(null)) {
ContainerRenewal containerRenewal = new ContainerRenewal();
containerRenewal.pushId = pushId;
// To renew the container, we need the password which protects it.
// you can either bypass the password prompt by filling the password through the containerRenewal, or by using the PasswordPromptEvent
// Biometric-enabled containers will automatically prompt
if (containerPassword != null) {
Log.d(LOG_TAG, "Start renewal");
containerRenewal.password = containerPassword.toCharArray();
}
// The listener works the same way than the createContainer.
EventListener myEventListener = new EventListener() {
@Override
public EventResult onEventReceived(Event event) {
if (event instanceof PasswordPromptEvent) {
PasswordPromptResult prompt = new PasswordPromptResult(EventResult.Code.Continue);
prompt.setPassword(containerPassword.toCharArray());
return prompt;
}
return null;
}
};
// We can proceed to the renew :
try {
currentContainer.renew(containerRenewal, null, myEventListener);
Log.d(LOG_TAG,"container has been renewed")
} catch ( PasswordExpiredException | UnsupportedDeviceException | InternalException | AuthenticationException | RemoteException |
UnsafeDeviceException | ServerProtocolException | FingerprintAuthenticationRequiredException | FingerprintNotEnrolledException |
LostCredentialsException | PasswordRequiredException | CredentialsExpiredException | ServerUnsupportedOperationException |
GooglePlayServicesObsoleteException | PasswordCancelledException | ServerOperationFailedException | InvalidParameterException e) {
e.printStackTrace();
}
finally {
// Good practice, the reset operation will nullify sensitive datas.
containerRenewal.reset();
}
}