1 /* 2 * Copyright 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.security.identity; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 22 import java.security.InvalidKeyException; 23 import java.security.KeyPair; 24 import java.security.PublicKey; 25 26 /** 27 * Class for presenting multiple documents to a remote verifier. 28 * 29 * <p>This should be used for all interactions with a remote verifier instead of the now deprecated 30 * {@link IdentityCredential#getEntries(byte[], Map, byte[], byte[])} method. 31 * 32 * Use {@link IdentityCredentialStore#createPresentationSession(int)} to create a {@link 33 * PresentationSession} instance. 34 */ 35 public abstract class PresentationSession { 36 /** 37 * @hide 38 */ PresentationSession()39 protected PresentationSession() {} 40 41 /** 42 * Gets the ephemeral key pair to use to establish a secure channel with the verifier. 43 * 44 * <p>Applications should use this key-pair for the communications channel with the verifier 45 * using a protocol / cipher-suite appropriate for the application. One example of such a 46 * protocol is the one used for Mobile Driving Licenses, see ISO 18013-5. 47 * 48 * <p>The ephemeral key pair is tied to the {@link PresentationSession} instance so subsequent 49 * calls to this method will return the same key-pair. 50 * 51 * @return ephemeral key pair to use to establish a secure channel with a reader. 52 */ getEphemeralKeyPair()53 public @NonNull abstract KeyPair getEphemeralKeyPair(); 54 55 /** 56 * Set the ephemeral public key provided by the verifier. 57 * 58 * <p>If called, this must be called before any calls to 59 * {@link #getCredentialData(String, CredentialDataRequest)}. 60 * 61 * <p>This method can only be called once per {@link PresentationSession} instance. 62 * 63 * @param readerEphemeralPublicKey The ephemeral public key provided by the reader to 64 * establish a secure session. 65 * @throws InvalidKeyException if the given key is invalid. 66 */ setReaderEphemeralPublicKey(@onNull PublicKey readerEphemeralPublicKey)67 public abstract void setReaderEphemeralPublicKey(@NonNull PublicKey readerEphemeralPublicKey) 68 throws InvalidKeyException; 69 70 /** 71 * Set the session transcript. 72 * 73 * <p>If called, this must be called before any calls to 74 * {@link #getCredentialData(String, CredentialDataRequest)}. 75 * 76 * <p>The X and Y coordinates of the public part of the key-pair returned by {@link 77 * #getEphemeralKeyPair()} must appear somewhere in the bytes of the passed in CBOR. Each of 78 * these coordinates must appear encoded with the most significant bits first and use the exact 79 * amount of bits indicated by the key size of the ephemeral keys. For example, if the 80 * ephemeral key is using the P-256 curve then the 32 bytes for the X coordinate encoded with 81 * the most significant bits first must appear somewhere and ditto for the 32 bytes for the Y 82 * coordinate. 83 * 84 * <p>This method can only be called once per {@link PresentationSession} instance. 85 * 86 * @param sessionTranscript the session transcript. 87 */ setSessionTranscript(@onNull byte[] sessionTranscript)88 public abstract void setSessionTranscript(@NonNull byte[] sessionTranscript); 89 90 /** 91 * Retrieves data from a named credential in the current presentation session. 92 * 93 * <p>If an access control check fails for one of the requested entries or if the entry 94 * doesn't exist, the entry is simply not returned. The application can detect this 95 * by using the {@link CredentialDataResult.Entries#getStatus(String, String)} method on 96 * each of the requested entries. 97 * 98 * <p>The application should not make any assumptions on whether user authentication is needed. 99 * Instead, the application should request the data elements values first and then examine 100 * the returned {@link CredentialDataResult.Entries}. If 101 * {@link CredentialDataResult.Entries#STATUS_USER_AUTHENTICATION_FAILED} is returned the 102 * application should get a 103 * {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} which references this 104 * object and use it with a {@link android.hardware.biometrics.BiometricPrompt}. Upon successful 105 * authentication the application may call 106 * {@link #getCredentialData(String, CredentialDataRequest)} again. 107 * 108 * <p>It is permissible to call this method multiple times using the same credential name. 109 * If this is done the same auth-key will be used. 110 * 111 * <p>If the reader signature is set in the request parameter (via the 112 * {@link CredentialDataRequest.Builder#setReaderSignature(byte[])} method) it must contain 113 * the bytes of a {@code COSE_Sign1} structure as defined in RFC 8152. For the payload 114 * {@code nil} shall be used and the detached payload is the {@code ReaderAuthenticationBytes} 115 * CBOR described below. 116 * <pre> 117 * ReaderAuthentication = [ 118 * "ReaderAuthentication", 119 * SessionTranscript, 120 * ItemsRequestBytes 121 * ] 122 * 123 * ItemsRequestBytes = #6.24(bstr .cbor ItemsRequest) 124 * 125 * ReaderAuthenticationBytes = #6.24(bstr .cbor ReaderAuthentication) 126 * </pre> 127 * 128 * <p>where {@code ItemsRequestBytes} are the bytes of the request message set in 129 * the request parameter (via the 130 * {@link CredentialDataRequest.Builder#setRequestMessage(byte[])} method). 131 * 132 * <p>The public key corresponding to the key used to make the signature, can be found in the 133 * {@code x5chain} unprotected header element of the {@code COSE_Sign1} structure (as as 134 * described in 135 * <a href="https://tools.ietf.org/html/draft-ietf-cose-x509-08">draft-ietf-cose-x509-08</a>). 136 * There will be at least one certificate in said element and there may be more (and if so, 137 * each certificate must be signed by its successor). 138 * 139 * <p>Data elements protected by reader authentication are returned if, and only if, 140 * {@code requestMessage} is signed by the top-most certificate in the reader's certificate 141 * chain, and the data element is configured with an {@link AccessControlProfile} configured 142 * with an X.509 certificate for a key which appear in the certificate chain. 143 * 144 * <p>Note that the request message CBOR is used only for enforcing reader authentication, it's 145 * not used for determining which entries this API will return. The application is expected to 146 * have parsed the request message and filtered it according to user preference and/or consent. 147 * 148 * @param credentialName the name of the credential to retrieve. 149 * @param request the data to retrieve from the credential 150 * @return If the credential wasn't found, returns null. Otherwise a 151 * {@link CredentialDataResult} object containing entry data organized by namespace and 152 * a cryptographically authenticated representation of the same data, bound to the 153 * current session. 154 * @throws NoAuthenticationKeyAvailableException if authentication keys were never 155 * provisioned for the credential or if they 156 * are expired or exhausted their use-count. 157 * @throws InvalidRequestMessageException if the requestMessage is malformed. 158 * @throws InvalidReaderSignatureException if the reader signature is invalid, or it 159 * doesn't contain a certificate chain, or if 160 * the signature failed to validate. 161 * @throws EphemeralPublicKeyNotFoundException if the ephemeral public key was not found in 162 * the session transcript. 163 */ getCredentialData( @onNull String credentialName, @NonNull CredentialDataRequest request)164 public abstract @Nullable CredentialDataResult getCredentialData( 165 @NonNull String credentialName, @NonNull CredentialDataRequest request) 166 throws NoAuthenticationKeyAvailableException, InvalidReaderSignatureException, 167 InvalidRequestMessageException, EphemeralPublicKeyNotFoundException; 168 169 /** 170 * Called by android.hardware.biometrics.CryptoObject#getOpId() to get an 171 * operation handle. 172 * 173 * @hide 174 */ getCredstoreOperationHandle()175 public abstract long getCredstoreOperationHandle(); 176 } 177