1 /**
2  * Copyright (C) 2022 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 com.android.rkpdapp;
18 
19 import java.time.Duration;
20 import java.time.Instant;
21 import java.util.HashMap;
22 import java.util.Map;
23 
24 /**
25  * Convenience class for packaging up the values returned by the server when initially requesting
26  * an Endpoint Encryption Key for remote provisioning. Those values are described by the following
27  * CDDL Schema:
28  *    GeekResponse = [
29  *        [+CurveAndEek],
30  *        challenge : bstr,
31  *        ? Config,
32  *    ]
33  *    CurveAndEek = [
34  *        curve: uint,
35  *        EekChain
36  *    ]
37  *    Config = {
38  *        ? "num_extra_attestation_keys": uint,
39  *        ? "time_to_refresh_hours" : uint,
40  *        ? "provisioning_url": tstr,
41  *    }
42  *
43  * The CDDL that defines EekChain is defined in the RemoteProvisioning HAL, but this app does not
44  * require any semantic understanding of the format to perform its function.
45  */
46 public class GeekResponse {
47     public static final int NO_EXTRA_KEY_UPDATE = -1;
48     private byte[] mChallenge;
49     private final Map<Integer, byte[]> mCurveToGeek;
50     public int numExtraAttestationKeys;
51     public Duration timeToRefresh;
52     public String provisioningUrl;
53     public Instant lastBadCertTimeStart;
54     public Instant lastBadCertTimeEnd;
55 
56     /**
57      * Default initializer.
58      */
GeekResponse()59     public GeekResponse() {
60         mCurveToGeek = new HashMap<>();
61         numExtraAttestationKeys = NO_EXTRA_KEY_UPDATE;
62         lastBadCertTimeStart = null;
63         lastBadCertTimeEnd = null;
64     }
65 
66     /**
67      * Add a CBOR encoded array containing a GEEK and the corresponding certificate chain, keyed
68      * on the EC {@code curve}.
69      *
70      * @param curve an integer which represents an EC curve.
71      * @param geekChain the encoded CBOR array containing an ECDH key and corresponding certificate
72      *                  chain.
73      */
addGeek(int curve, byte[] geekChain)74     public void addGeek(int curve, byte[] geekChain) {
75         mCurveToGeek.put(curve, geekChain);
76     }
77 
78     /**
79      * Returns the encoded CBOR array with an ECDH key corresponding to the provided {@code curve}.
80      *
81      * @param curve an integer which represents an EC curve.
82      * @return the corresponding encoded CBOR array.
83      */
getGeekChain(int curve)84     public byte[] getGeekChain(int curve) {
85         return mCurveToGeek.get(curve);
86     }
87 
88     /**
89      * Sets the {@code challenge}.
90      */
setChallenge(byte[] challenge)91     public void setChallenge(byte[] challenge) {
92         mChallenge = challenge;
93     }
94 
95     /**
96      * Returns the {@code challenge}.
97      *
98      * @return the challenge that will be embedded in the CSR sent to the server.
99      */
getChallenge()100     public byte[] getChallenge() {
101         return mChallenge;
102     }
103 }
104