1 /*
2  * Copyright 2019 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.cts;
18 
19 import android.security.identity.ResultData;
20 import android.security.identity.IdentityCredentialStore;
21 
22 import android.content.Context;
23 import android.content.pm.PackageManager;
24 import android.content.pm.FeatureInfo;
25 import android.os.SystemProperties;
26 import android.security.keystore.KeyProperties;
27 import android.util.Log;
28 
29 import androidx.annotation.NonNull;
30 import androidx.annotation.Nullable;
31 import androidx.test.InstrumentationRegistry;
32 
33 import java.io.ByteArrayInputStream;
34 import java.io.ByteArrayOutputStream;
35 import java.io.IOException;
36 import java.math.BigInteger;
37 import java.security.InvalidAlgorithmParameterException;
38 import java.security.InvalidKeyException;
39 import java.security.KeyStore;
40 import java.security.KeyPair;
41 import java.security.KeyPairGenerator;
42 import java.security.MessageDigest;
43 import java.security.NoSuchAlgorithmException;
44 import java.security.PublicKey;
45 import java.security.PrivateKey;
46 import java.security.Signature;
47 import java.security.SignatureException;
48 import java.security.cert.CertificateEncodingException;
49 import java.security.cert.CertificateException;
50 import java.security.cert.CertificateFactory;
51 import java.security.cert.X509Certificate;
52 import java.security.spec.ECGenParameterSpec;
53 import java.text.DecimalFormat;
54 import java.text.DecimalFormatSymbols;
55 import java.text.ParseException;
56 import java.util.ArrayList;
57 import java.util.Arrays;
58 import java.util.Collection;
59 import java.util.Date;
60 import java.util.List;
61 import java.util.Locale;
62 import java.util.Formatter;
63 import java.util.Map;
64 
65 import javax.crypto.KeyAgreement;
66 import javax.crypto.Mac;
67 import javax.crypto.SecretKey;
68 import javax.crypto.spec.SecretKeySpec;
69 
70 import java.security.interfaces.ECPublicKey;
71 import java.security.spec.ECPoint;
72 
73 import org.bouncycastle.asn1.ASN1InputStream;
74 import org.bouncycastle.asn1.ASN1OctetString;
75 
76 import co.nstant.in.cbor.CborBuilder;
77 import co.nstant.in.cbor.CborDecoder;
78 import co.nstant.in.cbor.CborEncoder;
79 import co.nstant.in.cbor.CborException;
80 import co.nstant.in.cbor.builder.ArrayBuilder;
81 import co.nstant.in.cbor.builder.MapBuilder;
82 import co.nstant.in.cbor.model.AbstractFloat;
83 import co.nstant.in.cbor.model.Array;
84 import co.nstant.in.cbor.model.ByteString;
85 import co.nstant.in.cbor.model.DataItem;
86 import co.nstant.in.cbor.model.DoublePrecisionFloat;
87 import co.nstant.in.cbor.model.MajorType;
88 import co.nstant.in.cbor.model.NegativeInteger;
89 import co.nstant.in.cbor.model.SimpleValue;
90 import co.nstant.in.cbor.model.SimpleValueType;
91 import co.nstant.in.cbor.model.SpecialType;
92 import co.nstant.in.cbor.model.UnicodeString;
93 import co.nstant.in.cbor.model.UnsignedInteger;
94 
95 class TestUtil {
96     private static final String TAG = "Util";
97 
98     // Returns 0 if not implemented. Otherwise returns the feature version.
99     //
getFeatureVersion()100     static int getFeatureVersion() {
101         Context appContext = InstrumentationRegistry.getTargetContext();
102         PackageManager pm = appContext.getPackageManager();
103 
104         int featureVersionFromPm = 0;
105         if (pm.hasSystemFeature(PackageManager.FEATURE_IDENTITY_CREDENTIAL_HARDWARE)) {
106             FeatureInfo info = null;
107             FeatureInfo[] infos = pm.getSystemAvailableFeatures();
108             for (int n = 0; n < infos.length; n++) {
109                 FeatureInfo i = infos[n];
110                 if (i.name.equals(PackageManager.FEATURE_IDENTITY_CREDENTIAL_HARDWARE)) {
111                     info = i;
112                     break;
113                 }
114             }
115             if (info != null) {
116                 featureVersionFromPm = info.version;
117             }
118         }
119 
120         // Use of the system feature is not required since Android 12. So for Android 11
121         // return 202009 which is the feature version shipped with Android 11.
122         if (featureVersionFromPm == 0) {
123             IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
124             if (store != null) {
125                 featureVersionFromPm = 202009;
126             }
127         }
128 
129         return featureVersionFromPm;
130     }
131 
132     // Returns true if, and only if, the Identity Credential HAL (and credstore) is implemented
133     // on the device under test.
isHalImplemented()134     static boolean isHalImplemented() {
135         Context appContext = InstrumentationRegistry.getTargetContext();
136         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
137         if (store != null) {
138             return true;
139         }
140         return false;
141     }
142 
143     // Returns true if, and only if, the Direct Access Identity Credential HAL (and credstore) is
144     // implemented on the device under test.
isDirectAccessHalImplemented()145     static boolean isDirectAccessHalImplemented() {
146         Context appContext = InstrumentationRegistry.getTargetContext();
147         IdentityCredentialStore store = IdentityCredentialStore.getDirectAccessInstance(appContext);
148         if (store != null) {
149             return true;
150         }
151         return false;
152     }
153 
154     // Returns true if the device supports secure lock screen.
isLockScreenSupported()155     static boolean isLockScreenSupported() {
156         Context appContext = InstrumentationRegistry.getTargetContext();
157         PackageManager pm = appContext.getPackageManager();
158         return pm.hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN);
159     }
160 }
161