public abstract class

WritableIdentityCredential

extends java.lang.Object

 java.lang.Object

↳androidx.security.identity.WritableIdentityCredential

Gradle dependencies

compile group: 'androidx.security', name: 'security-identity-credential', version: '1.0.0-alpha03'

  • groupId: androidx.security
  • artifactId: security-identity-credential
  • version: 1.0.0-alpha03

Artifact androidx.security:security-identity-credential:1.0.0-alpha03 it located at Google repository (https://maven.google.com/)

Overview

Class used to personalize a new identity credential.

Credentials cannot be updated or modified after creation; any changes require deletion and re-creation. Use IdentityCredentialStore.createCredential(String, String) to create a new credential.

Summary

Constructors
protectedWritableIdentityCredential()

Methods
public abstract java.util.Collection<java.security.cert.X509Certificate>getCredentialKeyCertificateChain(byte[] challenge[])

Generates and returns an X.509 certificate chain for the CredentialKey which identifies this credential to the issuing authority.

public abstract byte[]personalize(PersonalizationData personalizationData)

Stores all of the data in the credential, with the specified access control profiles.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

protected WritableIdentityCredential()

Methods

public abstract java.util.Collection<java.security.cert.X509Certificate> getCredentialKeyCertificateChain(byte[] challenge[])

Generates and returns an X.509 certificate chain for the CredentialKey which identifies this credential to the issuing authority. The certificate contains an Android Keystore attestation extension which describes the key and the security hardware in which it lives.

The issuer MUST carefully examine this certificate chain including (but not limited to) checking that the root certificate is well-known, whether the tag Tag::IDENTITY_CREDENTIAL_KEY is present, the passed in challenge is present, the tag Tag::ATTESTATION_APPLICATION_ID is set to the expected Android application, the device has verified boot enabled, each certificate in the chain is signed by its successor, none of the certificates have been revoked, and so on.

If WritableIdentityCredential is not hardware-backed the credential is implemented using Android Keystore and the attestation extension will not contain the tag Tag::IDENTITY_CREDENTIAL_KEY. Otherwise if this tag is present it signals that WritableIdentityCredential is hardware-backed and CredentialKey and corresponding authentication keys can only sign/MAC very specific messages. This is in contrast to Android Keystore key which can be used to sign/MAC anything.

It is not strictly necessary to use this method to provision a credential if the issuing authority doesn't care about the nature of the security hardware. If called, however, this method must be called before WritableIdentityCredential.personalize(PersonalizationData).

Parameters:

challenge: is a non-empty byte array whose contents should be unique, fresh and provided by the issuing authority. The value provided is embedded in the attestation extension and enables the issuing authority to verify that the attestation certificate is fresh.

Returns:

the X.509 certificate for this credential's CredentialKey.

public abstract byte[] personalize(PersonalizationData personalizationData)

Stores all of the data in the credential, with the specified access control profiles.

This method returns a COSE_Sign1 data structure signed by the CredentialKey with payload set to ProofOfProvisioning as defined below.

     ProofOfProvisioning = [
          "ProofOfProvisioning",        ; tstr
          tstr,                         ; DocType
          [ * AccessControlProfile ],
          ProvisionedData,
          bool                          ; true if this is a test credential, should
                                        ; always be false.
      ]

      AccessControlProfile = {
          "id": uint,
          ? "readerCertificate" : bstr,
          ? (
               "userAuthenticationRequired" : bool,
               "timeoutMillis" : uint,
          )
      }

      ProvisionedData = {
          * Namespace => [ + Entry ]
      },

      Namespace = tstr

      Entry = {
          "name" : tstr,
          "value" : any,
          "accessControlProfiles" : [ * uint ],
      }
 

This data structure provides a guarantee to the issuer about the data which may be returned in the CBOR returned by ResultData.getAuthenticatedData() during a credential presentation.

Parameters:

personalizationData: The data to provision, including access control profiles and data elements and their values, grouped into namespaces.

Returns:

A COSE_Sign1 data structure, see above.

Source

/*
 * Copyright 2019 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 androidx.security.identity;

import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;

import java.security.cert.X509Certificate;
import java.util.Collection;

/**
 * Class used to personalize a new identity credential.
 *
 * <p>Credentials cannot be updated or modified after creation; any changes require deletion and
 * re-creation.
 *
 * Use {@link IdentityCredentialStore#createCredential(String, String)} to create a new credential.
 */
public abstract class WritableIdentityCredential {
    /**
     * @hide
     */
    @RestrictTo(RestrictTo.Scope.SUBCLASSES)
    protected WritableIdentityCredential() {}

    /**
     * Generates and returns an X.509 certificate chain for the CredentialKey which identifies this
     * credential to the issuing authority. The certificate contains an
     * <a href="https://source.android.com/security/keystore/attestation">Android Keystore</a>
     * attestation extension which describes the key and the security hardware in which it lives.
     *
     * <p>The issuer <b>MUST</b> carefully examine this certificate chain including (but not
     * limited to) checking that the root certificate is well-known, whether the tag
     * Tag::IDENTITY_CREDENTIAL_KEY is present, the passed in challenge is present, the tag
     * Tag::ATTESTATION_APPLICATION_ID is set to the expected Android application, the device
     * has verified boot enabled, each certificate in the chain is signed by its successor,
     * none of the certificates have been revoked, and so on.
     *
     * <p>If {@link WritableIdentityCredential} is not hardware-backed the credential is
     * implemented using Android Keystore and the attestation extension will
     * not contain the tag Tag::IDENTITY_CREDENTIAL_KEY. Otherwise if this tag is present
     * it signals that {@link WritableIdentityCredential} is hardware-backed and CredentialKey
     * and corresponding authentication keys can only sign/MAC very specific
     * messages. This is in contrast to Android Keystore key which can be used to
     * sign/MAC anything.
     *
     * <p>It is not strictly necessary to use this method to provision a credential if the issuing
     * authority doesn't care about the nature of the security hardware. If called, however, this
     * method must be called before {@link #personalize(PersonalizationData)}.
     *
     * @param challenge is a non-empty byte array whose contents should be unique, fresh and
     *                  provided by the issuing authority. The value provided is embedded in the
     *                  attestation extension and enables the issuing authority to verify that the
     *                  attestation certificate is fresh.
     * @return the X.509 certificate for this credential's CredentialKey.
     */
    public abstract @NonNull Collection<X509Certificate> getCredentialKeyCertificateChain(
            @NonNull byte[] challenge);

    /**
     * Stores all of the data in the credential, with the specified access control profiles.
     *
     * <p>This method returns a COSE_Sign1 data structure signed by the CredentialKey with payload
     * set to {@code ProofOfProvisioning} as defined below.
     *
     * <pre>
     *     ProofOfProvisioning = [
     *          "ProofOfProvisioning",        ; tstr
     *          tstr,                         ; DocType
     *          [ * AccessControlProfile ],
     *          ProvisionedData,
     *          bool                          ; true if this is a test credential, should
     *                                        ; always be false.
     *      ]
     *
     *      AccessControlProfile = {
     *          "id": uint,
     *          ? "readerCertificate" : bstr,
     *          ? (
     *               "userAuthenticationRequired" : bool,
     *               "timeoutMillis" : uint,
     *          )
     *      }
     *
     *      ProvisionedData = {
     *          * Namespace =&gt; [ + Entry ]
     *      },
     *
     *      Namespace = tstr
     *
     *      Entry = {
     *          "name" : tstr,
     *          "value" : any,
     *          "accessControlProfiles" : [ * uint ],
     *      }
     * </pre>
     *
     * <p>This data structure provides a guarantee to the issuer about the data which may be
     * returned in the CBOR returned by
     * {@link ResultData#getAuthenticatedData()} during a credential
     * presentation.
     *
     * @param personalizationData   The data to provision, including access control profiles
     *                              and data elements and their values, grouped into namespaces.
     * @return A COSE_Sign1 data structure, see above.
     */
    public abstract @NonNull byte[] personalize(
            @NonNull PersonalizationData personalizationData);
}