diff --git a/identity/support/Android.bp b/identity/support/Android.bp
new file mode 100644
index 0000000..38dc10b
--- /dev/null
+++ b/identity/support/Android.bp
@@ -0,0 +1,103 @@
+// Copyright (C) 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.
+//
+
+cc_library {
+    name: "android.hardware.identity-support-lib",
+    vendor_available: true,
+    srcs: [
+        "src/IdentityCredentialSupport.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+    shared_libs: [
+        "android.hardware.identity@1.0",
+        "libcrypto",
+        "libbase",
+        "libhidlbase",
+        "libhardware",
+    ],
+    static_libs: [
+        "libcppbor",
+    ],
+}
+
+cc_test {
+    name: "android.hardware.identity-support-lib-test",
+    srcs: [
+        "tests/IdentityCredentialSupportTest.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.identity-support-lib",
+        "android.hardware.identity@1.0",
+        "libcrypto",
+        "libbase",
+        "libhidlbase",
+        "libhardware",
+    ],
+    static_libs: [
+        "libcppbor",
+        "libgmock",
+    ],
+    test_suites: ["general-tests"],
+}
+
+// --
+
+cc_library {
+    name: "libcppbor",
+    vendor_available: true,
+    host_supported: true,
+    srcs: [
+        "src/cppbor.cpp",
+        "src/cppbor_parse.cpp",
+    ],
+    export_include_dirs: [
+        "include/cppbor",
+    ],
+    shared_libs: [
+        "libbase",
+    ],
+}
+
+cc_test {
+    name: "cppbor_test",
+    srcs: [
+        "tests/cppbor_test.cpp",
+    ],
+    shared_libs: [
+        "libcppbor",
+        "libbase",
+    ],
+    static_libs: [
+        "libgmock",
+    ],
+    test_suites: ["general-tests"],
+}
+
+cc_test_host {
+    name: "cppbor_host_test",
+    srcs: [
+        "tests/cppbor_test.cpp",
+    ],
+    shared_libs: [
+        "libcppbor",
+        "libbase",
+    ],
+    static_libs: [
+        "libgmock",
+    ],
+    test_suites: ["general-tests"],
+}
diff --git a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
new file mode 100644
index 0000000..485571a
--- /dev/null
+++ b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
@@ -0,0 +1,303 @@
+/*
+ * 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.
+ */
+
+#ifndef IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
+#define IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
+
+#include <cstdint>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include <android/hardware/identity/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace identity {
+namespace support {
+
+using ::std::optional;
+using ::std::string;
+using ::std::tuple;
+using ::std::vector;
+
+using ::android::hardware::identity::V1_0::Result;
+using ::android::hardware::identity::V1_0::ResultCode;
+using ::android::hardware::identity::V1_0::SecureAccessControlProfile;
+
+// ---------------------------------------------------------------------------
+// Miscellaneous utilities.
+// ---------------------------------------------------------------------------
+
+// Dumps the data in |data| to stderr. The written data will be of the following
+// form for the call hexdump("signature", data) where |data| is of size 71:
+//
+//   signature: dumping 71 bytes
+//   0000  30 45 02 21 00 ac c6 12 60 56 a2 e9 ee 16 be 14  0E.!....`V......
+//   0010  69 7f c4 00 95 8c e8 55 1f 22 de 34 0b 08 8a 3b  i......U.".4...;
+//   0020  a0 56 54 05 07 02 20 58 77 d9 8c f9 eb 41 df fd  .VT... Xw....A..
+//   0030  c1 a3 14 e0 bf b0 a2 c5 0c b6 85 8c 4a 0d f9 2b  ............J..+
+//   0040  b7 8f d2 1d 9b 11 ac                             .......
+//
+// This should only be used for debugging.
+void hexdump(const string& name, const vector<uint8_t>& data);
+
+string encodeHex(const string& str);
+
+string encodeHex(const vector<uint8_t>& data);
+
+string encodeHex(const uint8_t* data, size_t dataLen);
+
+optional<vector<uint8_t>> decodeHex(const string& hexEncoded);
+
+// ---------------------------------------------------------------------------
+// CBOR utilities.
+// ---------------------------------------------------------------------------
+
+// Returns pretty-printed CBOR for |value|.
+//
+// Only valid CBOR should be passed to this function.
+//
+// If a byte-string is larger than |maxBStrSize| its contents will not be
+// printed, instead the value of the form "<bstr size=1099016
+// sha1=ef549cca331f73dfae2090e6a37c04c23f84b07b>" will be printed. Pass zero
+// for |maxBStrSize| to disable this.
+//
+// The |mapKeysToNotPrint| parameter specifies the name of map values
+// to not print. This is useful for unit tests.
+string cborPrettyPrint(const vector<uint8_t>& encodedCbor, size_t maxBStrSize = 32,
+                       const vector<string>& mapKeysToNotPrint = {});
+
+// ---------------------------------------------------------------------------
+// Crypto functionality / abstraction.
+// ---------------------------------------------------------------------------
+
+constexpr size_t kAesGcmIvSize = 12;
+constexpr size_t kAesGcmTagSize = 16;
+constexpr size_t kAes128GcmKeySize = 16;
+
+// Returns |numBytes| bytes of random data.
+optional<vector<uint8_t>> getRandom(size_t numBytes);
+
+// Calculates the SHA-256 of |data|.
+vector<uint8_t> sha256(const vector<uint8_t>& data);
+
+// Decrypts |encryptedData| using |key| and |additionalAuthenticatedData|,
+// returns resulting plaintext. The format of |encryptedData| must
+// be as specified in the encryptAes128Gcm() function.
+optional<vector<uint8_t>> decryptAes128Gcm(const vector<uint8_t>& key,
+                                           const vector<uint8_t>& encryptedData,
+                                           const vector<uint8_t>& additionalAuthenticatedData);
+
+// Encrypts |data| with |key| and |additionalAuthenticatedData| using |nonce|,
+// returns the resulting (nonce || ciphertext || tag).
+optional<vector<uint8_t>> encryptAes128Gcm(const vector<uint8_t>& key, const vector<uint8_t>& nonce,
+                                           const vector<uint8_t>& data,
+                                           const vector<uint8_t>& additionalAuthenticatedData);
+
+// ---------------------------------------------------------------------------
+// EC crypto functionality / abstraction (only supports P-256).
+// ---------------------------------------------------------------------------
+
+// Creates an 256-bit EC key using the NID_X9_62_prime256v1 curve, returns the
+// PKCS#8 encoded key-pair.
+//
+optional<vector<uint8_t>> createEcKeyPair();
+
+// For an EC key |keyPair| encoded in PKCS#8 format, extracts the public key in
+// uncompressed point form.
+//
+optional<vector<uint8_t>> ecKeyPairGetPublicKey(const vector<uint8_t>& keyPair);
+
+// For an EC key |keyPair| encoded in PKCS#8 format, extracts the private key as
+// an EC uncompressed key.
+//
+optional<vector<uint8_t>> ecKeyPairGetPrivateKey(const vector<uint8_t>& keyPair);
+
+// For an EC key |keyPair| encoded in PKCS#8 format, creates a PKCS#12 structure
+// with the key-pair (not using a password to encrypt the data). The public key
+// in the created structure is included as a certificate, using the given fields
+// |serialDecimal|, |issuer|, |subject|, |validityNotBefore|, and
+// |validityNotAfter|.
+//
+optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, const string& name,
+                                             const string& serialDecimal, const string& issuer,
+                                             const string& subject, time_t validityNotBefore,
+                                             time_t validityNotAfter);
+
+// Signs |data| with |key| (which must be in the format returned by
+// ecKeyPairGetPrivateKey()). Signature is returned and will be in DER format.
+//
+optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data);
+
+// Calculates the HMAC with SHA-256 for |data| using |key|. The calculated HMAC
+// is returned and will be 32 bytes.
+//
+optional<vector<uint8_t>> hmacSha256(const vector<uint8_t>& key, const vector<uint8_t>& data);
+
+// Checks that |signature| (in DER format) is a valid signature of |digest|,
+// made with |publicKey| (which must be in the format returned by
+// ecKeyPairGetPublicKey()).
+//
+bool checkEcDsaSignature(const vector<uint8_t>& digest, const vector<uint8_t>& signature,
+                         const vector<uint8_t>& publicKey);
+
+// Extracts the public-key from the top-most certificate in |certificateChain|
+// (which should be a concatenated chain of DER-encoded X.509 certificates).
+//
+// The returned public key will be in the same format as returned by
+// ecKeyPairGetPublicKey().
+//
+optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& certificateChain);
+
+// Generates a X.509 certificate for |publicKey| (which must be in the format
+// returned by ecKeyPairGetPublicKey()).
+//
+// The certificate is signed by |signingKey| (which must be in the format
+// returned by ecKeyPairGetPrivateKey())
+//
+optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
+        const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey,
+        const string& serialDecimal, const string& issuer, const string& subject,
+        time_t validityNotBefore, time_t validityNotAfter);
+
+// Performs Elliptic-curve Diffie-Helman using |publicKey| (which must be in the
+// format returned by ecKeyPairGetPublicKey()) and |privateKey| (which must be
+// in the format returned by ecKeyPairGetPrivateKey()).
+//
+// On success, the computed shared secret is returned.
+//
+optional<vector<uint8_t>> ecdh(const vector<uint8_t>& publicKey, const vector<uint8_t>& privateKey);
+
+// Key derivation function using SHA-256, conforming to RFC 5869.
+//
+// On success, the derived key is returned.
+//
+optional<vector<uint8_t>> hkdf(const vector<uint8_t>& sharedSecret, const vector<uint8_t>& salt,
+                               const vector<uint8_t>& info, size_t size);
+
+// Returns the X and Y coordinates from |publicKey| (which must be in the format
+// returned by ecKeyPairGetPublicKey()).
+//
+// Success is indicated by the first value in the returned tuple. If successful,
+// the returned coordinates will be in uncompressed form.
+//
+tuple<bool, vector<uint8_t>, vector<uint8_t>> ecPublicKeyGetXandY(const vector<uint8_t>& publicKey);
+
+// Concatenates all certificates into |certificateChain| together into a
+// single bytestring.
+//
+// This is the reverse operation of certificateChainSplit().
+vector<uint8_t> certificateChainJoin(const vector<vector<uint8_t>>& certificateChain);
+
+// Splits all the certificates in a single bytestring into individual
+// certificates.
+//
+// Returns nothing if |certificateChain| contains invalid data.
+//
+// This is the reverse operation of certificateChainJoin().
+optional<vector<vector<uint8_t>>> certificateChainSplit(const vector<uint8_t>& certificateChain);
+
+// Validates that the certificate chain is valid. In particular, checks that each
+// certificate in the chain is signed by the public key in the following certificate.
+//
+// Returns false if |certificateChain| failed validation or if each certificate
+// is not signed by its successor.
+//
+bool certificateChainValidate(const vector<uint8_t>& certificateChain);
+
+// Signs |data| and |detachedContent| with |key| (which must be in the format
+// returned by ecKeyPairGetPrivateKey()).
+//
+// On success, the Signature is returned and will be in COSE_Sign1 format.
+//
+// If |certificateChain| is non-empty it's included in the 'x5chain'
+// protected header element (as as described in'draft-ietf-cose-x509-04').
+//
+optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data,
+                                        const vector<uint8_t>& detachedContent,
+                                        const vector<uint8_t>& certificateChain);
+
+// Checks that |signatureCoseSign1| (in COSE_Sign1 format) is a valid signature
+// made with |public_key| (which must be in the format returned by
+// ecKeyPairGetPublicKey()) where |detachedContent| is the detached content.
+//
+bool coseCheckEcDsaSignature(const vector<uint8_t>& signatureCoseSign1,
+                             const vector<uint8_t>& detachedContent,
+                             const vector<uint8_t>& publicKey);
+
+// Extracts the payload from a COSE_Sign1.
+optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1);
+
+// Extracts the X.509 certificate chain, if present. Returns the data as a
+// concatenated chain of DER-encoded X.509 certificates
+//
+// Returns nothing if there is no 'x5chain' element or an error occurs.
+//
+optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCoseSign1);
+
+// MACs |data| and |detachedContent| with |key| (which can be any sequence of
+// bytes).
+//
+// If successful, the MAC is returned and will be in COSE_Mac0 format.
+//
+optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint8_t>& data,
+                                   const vector<uint8_t>& detachedContent);
+
+// ---------------------------------------------------------------------------
+// Platform abstraction.
+// ---------------------------------------------------------------------------
+
+// Returns the hardware-bound AES-128 key.
+const vector<uint8_t>& getHardwareBoundKey();
+
+// ---------------------------------------------------------------------------
+// Utility functions specific to IdentityCredential.
+// ---------------------------------------------------------------------------
+
+// Returns a reference to a Result with code OK and empty message.
+const Result& resultOK();
+
+// Returns a new Result with the given code and message.
+Result result(ResultCode code, const char* format, ...) __attribute__((format(printf, 2, 3)));
+
+// Splits the given bytestring into chunks. If the given vector is smaller or equal to
+// |maxChunkSize| a vector with |content| as the only element is returned. Otherwise
+// |content| is split into N vectors each of size |maxChunkSize| except the final element
+// may be smaller than |maxChunkSize|.
+vector<vector<uint8_t>> chunkVector(const vector<uint8_t>& content, size_t maxChunkSize);
+
+// Calculates the MAC for |profile| using |storageKey|.
+optional<vector<uint8_t>> secureAccessControlProfileCalcMac(
+        const SecureAccessControlProfile& profile, const vector<uint8_t>& storageKey);
+
+// Checks authenticity of the MAC in |profile| using |storageKey|.
+bool secureAccessControlProfileCheckMac(const SecureAccessControlProfile& profile,
+                                        const vector<uint8_t>& storageKey);
+
+// Returns the testing AES-128 key where all bits are set to 0.
+const vector<uint8_t>& getTestHardwareBoundKey();
+
+// Creates the AdditionalData CBOR used in the addEntryValue() HIDL method.
+vector<uint8_t> entryCreateAdditionalData(const string& nameSpace, const string& name,
+                                          const vector<uint16_t> accessControlProfileIds);
+
+}  // namespace support
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
+
+#endif  // IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
diff --git a/identity/support/include/cppbor/README.md b/identity/support/include/cppbor/README.md
new file mode 100644
index 0000000..723bfcf
--- /dev/null
+++ b/identity/support/include/cppbor/README.md
@@ -0,0 +1,216 @@
+CppBor: A Modern C++ CBOR Parser and Generator
+==============================================
+
+CppBor provides a natural and easy-to-use syntax for constructing and
+parsing CBOR messages.  It does not (yet) support all features of
+CBOR, nor (yet) support validation against CDDL schemata, though both
+are planned.  CBOR features that aren't supported include:
+
+* Indefinite length values
+* Semantic tagging
+* Floating point
+
+CppBor requires C++-17.
+
+## CBOR representation
+
+CppBor represents CBOR data items as instances of the `Item` class or,
+more precisely, as instances of subclasses of `Item`, since `Item` is a
+pure interface.  The subclasses of `Item` correspond almost one-to-one
+with CBOR major types, and are named to match the CDDL names to which
+they correspond.  They are:
+
+* `Uint` corresponds to major type 0, and can hold unsigned integers
+  up through (2^64 - 1).
+* `Nint` corresponds to major type 1.  It can only hold values from -1
+  to -(2^63 - 1), since it's internal representation is an int64_t.
+  This can be fixed, but it seems unlikely that applications will need
+  the omitted range from -(2^63) to (2^64 - 1), since it's
+  inconvenient to represent them in many programming languages.
+* `Int` is an abstract base of `Uint` and `Nint` that facilitates
+  working with all signed integers representable with int64_t.
+* `Bstr` corresponds to major type 2, a byte string.
+* `Tstr` corresponds to major type 3, a text string.
+* `Array` corresponds to major type 4, an Array.  It holds a
+  variable-length array of `Item`s.
+* `Map` corresponds to major type 5, a Map.  It holds a
+  variable-length array of pairs of `Item`s.
+* `Simple` corresponds to major type 7.  It's an abstract class since
+  items require more specific type.
+* `Bool` is the only currently-implemented subclass of `Simple`.
+
+Note that major type 6, semantic tag, is not yet implemented.
+
+In practice, users of CppBor will rarely use most of these classes
+when generating CBOR encodings.  This is because CppBor provides
+straightforward conversions from the obvious normal C++ types.
+Specifically, the following conversions are provided in appropriate
+contexts:
+
+* Signed and unsigned integers convert to `Uint` or `Nint`, as
+  appropriate.
+* `std::string`, `std::string_view`, `const char*` and
+  `std::pair<char iterator, char iterator>` convert to `Tstr`.
+* `std::vector<uint8_t>`, `std::pair<uint8_t iterator, uint8_t
+  iterator>` and `std::pair<uint8_t*, size_t>` convert to `Bstr`.
+* `bool` converts to `Bool`.
+
+## CBOR generation
+
+### Complete tree generation
+
+The set of `encode` methods in `Item` provide the interface for
+producing encoded CBOR.  The basic process for "complete tree"
+generation (as opposed to "incremental" generation, which is discussed
+below) is to construct an `Item` which models the data to be encoded,
+and then call one of the `encode` methods, whichever is convenient for
+the encoding destination.  A trivial example:
+
+```
+cppbor::Uint val(0);
+std::vector<uint8_t> encoding = val.encode();
+```
+
+    It's relatively rare that single values are encoded as above.  More often, the
+    "root" data item will be an `Array` or `Map` which contains a more complex structure.For example
+    :
+
+``` using cppbor::Map;
+using cppbor::Array;
+
+std::vector<uint8_t> vec =  // ...
+    Map val("key1", Array(Map("key_a", 99 "key_b", vec), "foo"), "key2", true);
+std::vector<uint8_t> encoding = val.encode();
+```
+
+This creates a map with two entries, with `Tstr` keys "Outer1" and
+"Outer2", respectively.  The "Outer1" entry has as its value an
+`Array` containing a `Map` and a `Tstr`.  The "Outer2" entry has a
+`Bool` value.
+
+This example demonstrates how automatic conversion of C++ types to
+CppBor `Item` subclass instances is done.  Where the caller provides a
+C++ or C string, a `Tstr` entry is added.  Where the caller provides
+an integer literal or variable, a `Uint` or `Nint` is added, depending
+on whether the value is positive or negative.
+
+As an alternative, a more fluent-style API is provided for building up
+structures.  For example:
+
+```
+using cppbor::Map;
+using cppbor::Array;
+
+std::vector<uint8_t> vec =  // ...
+    Map val();
+val.add("key1", Array().add(Map().add("key_a", 99).add("key_b", vec)).add("foo")).add("key2", true);
+std::vector<uint8_t> encoding = val.encode();
+```
+
+    An advantage of this interface over the constructor -
+    based creation approach above is that it need not be done all at once
+        .The `add` methods return a reference to the object added to to allow calls to be chained,
+    but chaining is not necessary; calls can be made
+sequentially, as the data to add is available.
+
+#### `encode` methods
+
+There are several variations of `Item::encode`, all of which
+accomplish the same task but output the encoded data in different
+ways, and with somewhat different performance characteristics.  The
+provided options are:
+
+* `bool encode(uint8\_t** pos, const uint8\_t* end)` encodes into the
+  buffer referenced by the range [`*pos`, end).  `*pos` is moved.  If
+  the encoding runs out of buffer space before finishing, the method
+  returns false.  This is the most efficient way to encode, into an
+  already-allocated buffer.
+* `void encode(EncodeCallback encodeCallback)` calls `encodeCallback`
+  for each encoded byte.  It's the responsibility of the implementor
+  of the callback to behave safely in the event that the output buffer
+  (if applicable) is exhausted.  This is less efficient than the prior
+  method because it imposes an additional function call for each byte.
+* `template </*...*/> void encode(OutputIterator i)`
+  encodes into the provided iterator.  SFINAE ensures that the
+  template doesn't match for non-iterators.  The implementation
+  actually uses the callback-based method, plus has whatever overhead
+  the iterator adds.
+* `std::vector<uint8_t> encode()` creates a new std::vector, reserves
+  sufficient capacity to hold the encoding, and inserts the encoded
+  bytes with a std::pushback_iterator and the previous method.
+* `std::string toString()` does the same as the previous method, but
+  returns a string instead of a vector.
+
+### Incremental generation
+
+Incremental generation requires deeper understanding of CBOR, because
+the library can't do as much to ensure that the output is valid.  The
+basic tool for intcremental generation is the `encodeHeader`
+function.  There are two variations, one which writes into a buffer,
+and one which uses a callback.  Both simply write out the bytes of a
+header.  To construct the same map as in the above examples,
+incrementally, one might write:
+
+```
+using namespace cppbor;  // For example brevity
+
+std::vector encoding;
+auto iter = std::back_inserter(result);
+encodeHeader(MAP, 2 /* # of map entries */, iter);
+std::string s = "key1";
+encodeHeader(TSTR, s.size(), iter);
+std::copy(s.begin(), s.end(), iter);
+encodeHeader(ARRAY, 2 /* # of array entries */, iter);
+Map().add("key_a", 99).add("key_b", vec).encode(iter)
+s = "foo";
+encodeHeader(TSTR, foo.size(), iter);
+std::copy(s.begin(), s.end(), iter);
+s = "key2";
+encodeHeader(TSTR, foo.size(), iter);
+std::copy(s.begin(), s.end(), iter);
+encodeHeader(SIMPLE, TRUE, iter);
+```
+
+As the above example demonstrates, the styles can be mixed -- Note the
+creation and encoding of the inner Map using the fluent style.
+
+## Parsing
+
+CppBor also supports parsing of encoded CBOR data, with the same
+feature set as encoding.  There are two basic approaches to parsing,
+"full" and "stream"
+
+### Full parsing
+
+Full parsing means completely parsing a (possibly-compound) data
+item from a byte buffer.  The `parse` functions that do not take a
+`ParseClient` pointer do this.  They return a `ParseResult` which is a
+tuple of three values:
+
+* std::unique_ptr<Item> that points to the parsed item, or is nullptr
+  if there was a parse error.
+* const uint8_t* that points to the byte after the end of the decoded
+  item, or to the first unparseable byte in the event of an error.
+* std::string that is empty on success or contains an error message if
+  a parse error occurred.
+
+Assuming a successful parse, you can then use `Item::type()` to
+discover the type of the parsed item (e.g. MAP), and then use the
+appropriate `Item::as*()` method (e.g. `Item::asMap()`) to get a
+pointer to an interface which allows you to retrieve specific values.
+
+### Stream parsing
+
+Stream parsing is more complex, but more flexible.  To use
+StreamParsing, you must create your own subclass of `ParseClient` and
+call one of the `parse` functions that accepts it.  See the
+`ParseClient` methods docstrings for details.
+
+One unusual feature of stream parsing is that the `ParseClient`
+callback methods not only provide the parsed Item, but also pointers
+to the portion of the buffer that encode that Item.  This is useful
+if, for example, you want to find an element inside of a structure,
+and then copy the encoding of that sub-structure, without bothering to
+parse the rest.
+
+The full parser is implemented with the stream parser.
diff --git a/identity/support/include/cppbor/cppbor.h b/identity/support/include/cppbor/cppbor.h
new file mode 100644
index 0000000..a755db1
--- /dev/null
+++ b/identity/support/include/cppbor/cppbor.h
@@ -0,0 +1,827 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <numeric>
+#include <string>
+#include <vector>
+
+namespace cppbor {
+
+enum MajorType : uint8_t {
+    UINT = 0 << 5,
+    NINT = 1 << 5,
+    BSTR = 2 << 5,
+    TSTR = 3 << 5,
+    ARRAY = 4 << 5,
+    MAP = 5 << 5,
+    SEMANTIC = 6 << 5,
+    SIMPLE = 7 << 5,
+};
+
+enum SimpleType {
+    BOOLEAN,
+    NULL_T,  // Only two supported, as yet.
+};
+
+enum SpecialAddlInfoValues : uint8_t {
+    FALSE = 20,
+    TRUE = 21,
+    NULL_V = 22,
+    ONE_BYTE_LENGTH = 24,
+    TWO_BYTE_LENGTH = 25,
+    FOUR_BYTE_LENGTH = 26,
+    EIGHT_BYTE_LENGTH = 27,
+};
+
+class Item;
+class Uint;
+class Nint;
+class Int;
+class Tstr;
+class Bstr;
+class Simple;
+class Bool;
+class Array;
+class Map;
+class Null;
+class Semantic;
+
+/**
+ * Returns the size of a CBOR header that contains the additional info value addlInfo.
+ */
+size_t headerSize(uint64_t addlInfo);
+
+/**
+ * Encodes a CBOR header with the specified type and additional info into the range [pos, end).
+ * Returns a pointer to one past the last byte written, or nullptr if there isn't sufficient space
+ * to write the header.
+ */
+uint8_t* encodeHeader(MajorType type, uint64_t addlInfo, uint8_t* pos, const uint8_t* end);
+
+using EncodeCallback = std::function<void(uint8_t)>;
+
+/**
+ * Encodes a CBOR header with the specified type and additional info, passing each byte in turn to
+ * encodeCallback.
+ */
+void encodeHeader(MajorType type, uint64_t addlInfo, EncodeCallback encodeCallback);
+
+/**
+ * Encodes a CBOR header with the specified type and additional info, writing each byte to the
+ * provided OutputIterator.
+ */
+template <typename OutputIterator,
+          typename = std::enable_if_t<std::is_base_of_v<
+                  std::output_iterator_tag,
+                  typename std::iterator_traits<OutputIterator>::iterator_category>>>
+void encodeHeader(MajorType type, uint64_t addlInfo, OutputIterator iter) {
+    return encodeHeader(type, addlInfo, [&](uint8_t v) { *iter++ = v; });
+}
+
+/**
+ * Item represents a CBOR-encodeable data item.  Item is an abstract interface with a set of virtual
+ * methods that allow encoding of the item or conversion to the appropriate derived type.
+ */
+class Item {
+  public:
+    virtual ~Item() {}
+
+    /**
+     * Returns the CBOR type of the item.
+     */
+    virtual MajorType type() const = 0;
+
+    // These methods safely downcast an Item to the appropriate subclass.
+    virtual const Int* asInt() const { return nullptr; }
+    virtual const Uint* asUint() const { return nullptr; }
+    virtual const Nint* asNint() const { return nullptr; }
+    virtual const Tstr* asTstr() const { return nullptr; }
+    virtual const Bstr* asBstr() const { return nullptr; }
+    virtual const Simple* asSimple() const { return nullptr; }
+    virtual const Map* asMap() const { return nullptr; }
+    virtual const Array* asArray() const { return nullptr; }
+    virtual const Semantic* asSemantic() const { return nullptr; }
+
+    /**
+     * Returns true if this is a "compound" item, i.e. one that contains one or more other items.
+     */
+    virtual bool isCompound() const { return false; }
+
+    bool operator==(const Item& other) const&;
+    bool operator!=(const Item& other) const& { return !(*this == other); }
+
+    /**
+     * Returns the number of bytes required to encode this Item into CBOR.  Note that if this is a
+     * complex Item, calling this method will require walking the whole tree.
+     */
+    virtual size_t encodedSize() const = 0;
+
+    /**
+     * Encodes the Item into buffer referenced by range [*pos, end).  Returns a pointer to one past
+     * the last position written.  Returns nullptr if there isn't enough space to encode.
+     */
+    virtual uint8_t* encode(uint8_t* pos, const uint8_t* end) const = 0;
+
+    /**
+     * Encodes the Item by passing each encoded byte to encodeCallback.
+     */
+    virtual void encode(EncodeCallback encodeCallback) const = 0;
+
+    /**
+     * Clones the Item
+     */
+    virtual std::unique_ptr<Item> clone() const = 0;
+
+    /**
+     * Encodes the Item into the provided OutputIterator.
+     */
+    template <typename OutputIterator,
+              typename = typename std::iterator_traits<OutputIterator>::iterator_category>
+    void encode(OutputIterator i) const {
+        return encode([&](uint8_t v) { *i++ = v; });
+    }
+
+    /**
+     * Encodes the Item into a new std::vector<uint8_t>.
+     */
+    std::vector<uint8_t> encode() const {
+        std::vector<uint8_t> retval;
+        retval.reserve(encodedSize());
+        encode(std::back_inserter(retval));
+        return retval;
+    }
+
+    /**
+     * Encodes the Item into a new std::string.
+     */
+    std::string toString() const {
+        std::string retval;
+        retval.reserve(encodedSize());
+        encode([&](uint8_t v) { retval.push_back(v); });
+        return retval;
+    }
+
+    /**
+     * Encodes only the header of the Item.
+     */
+    inline uint8_t* encodeHeader(uint64_t addlInfo, uint8_t* pos, const uint8_t* end) const {
+        return ::cppbor::encodeHeader(type(), addlInfo, pos, end);
+    }
+
+    /**
+     * Encodes only the header of the Item.
+     */
+    inline void encodeHeader(uint64_t addlInfo, EncodeCallback encodeCallback) const {
+        ::cppbor::encodeHeader(type(), addlInfo, encodeCallback);
+    }
+};
+
+/**
+ * Int is an abstraction that allows Uint and Nint objects to be manipulated without caring about
+ * the sign.
+ */
+class Int : public Item {
+  public:
+    bool operator==(const Int& other) const& { return value() == other.value(); }
+
+    virtual int64_t value() const = 0;
+
+    const Int* asInt() const override { return this; }
+};
+
+/**
+ * Uint is a concrete Item that implements CBOR major type 0.
+ */
+class Uint : public Int {
+  public:
+    static constexpr MajorType kMajorType = UINT;
+
+    explicit Uint(uint64_t v) : mValue(v) {}
+
+    bool operator==(const Uint& other) const& { return mValue == other.mValue; }
+
+    MajorType type() const override { return kMajorType; }
+    const Uint* asUint() const override { return this; }
+
+    size_t encodedSize() const override { return headerSize(mValue); }
+
+    int64_t value() const override { return mValue; }
+    uint64_t unsignedValue() const { return mValue; }
+
+    using Item::encode;
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override {
+        return encodeHeader(mValue, pos, end);
+    }
+    void encode(EncodeCallback encodeCallback) const override {
+        encodeHeader(mValue, encodeCallback);
+    }
+
+    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Uint>(mValue); }
+
+  private:
+    uint64_t mValue;
+};
+
+/**
+ * Nint is a concrete Item that implements CBOR major type 1.
+
+ * Note that it is incapable of expressing the full range of major type 1 values, becaue it can only
+ * express values that fall into the range [std::numeric_limits<int64_t>::min(), -1].  It cannot
+ * express values in the range [std::numeric_limits<int64_t>::min() - 1,
+ * -std::numeric_limits<uint64_t>::max()].
+ */
+class Nint : public Int {
+  public:
+    static constexpr MajorType kMajorType = NINT;
+
+    explicit Nint(int64_t v);
+
+    bool operator==(const Nint& other) const& { return mValue == other.mValue; }
+
+    MajorType type() const override { return kMajorType; }
+    const Nint* asNint() const override { return this; }
+    size_t encodedSize() const override { return headerSize(addlInfo()); }
+
+    int64_t value() const override { return mValue; }
+
+    using Item::encode;
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override {
+        return encodeHeader(addlInfo(), pos, end);
+    }
+    void encode(EncodeCallback encodeCallback) const override {
+        encodeHeader(addlInfo(), encodeCallback);
+    }
+
+    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Nint>(mValue); }
+
+  private:
+    uint64_t addlInfo() const { return -1ll - mValue; }
+
+    int64_t mValue;
+};
+
+/**
+ * Bstr is a concrete Item that implements major type 2.
+ */
+class Bstr : public Item {
+  public:
+    static constexpr MajorType kMajorType = BSTR;
+
+    // Construct from a vector
+    explicit Bstr(std::vector<uint8_t> v) : mValue(std::move(v)) {}
+
+    // Construct from a string
+    explicit Bstr(const std::string& v)
+        : mValue(reinterpret_cast<const uint8_t*>(v.data()),
+                 reinterpret_cast<const uint8_t*>(v.data()) + v.size()) {}
+
+    // Construct from a pointer/size pair
+    explicit Bstr(const std::pair<const uint8_t*, size_t>& buf)
+        : mValue(buf.first, buf.first + buf.second) {}
+
+    // Construct from a pair of iterators
+    template <typename I1, typename I2,
+              typename = typename std::iterator_traits<I1>::iterator_category,
+              typename = typename std::iterator_traits<I2>::iterator_category>
+    explicit Bstr(const std::pair<I1, I2>& pair) : mValue(pair.first, pair.second) {}
+
+    // Construct from an iterator range.
+    template <typename I1, typename I2,
+              typename = typename std::iterator_traits<I1>::iterator_category,
+              typename = typename std::iterator_traits<I2>::iterator_category>
+    Bstr(I1 begin, I2 end) : mValue(begin, end) {}
+
+    bool operator==(const Bstr& other) const& { return mValue == other.mValue; }
+
+    MajorType type() const override { return kMajorType; }
+    const Bstr* asBstr() const override { return this; }
+    size_t encodedSize() const override { return headerSize(mValue.size()) + mValue.size(); }
+    using Item::encode;
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override;
+    void encode(EncodeCallback encodeCallback) const override {
+        encodeHeader(mValue.size(), encodeCallback);
+        encodeValue(encodeCallback);
+    }
+
+    const std::vector<uint8_t>& value() const { return mValue; }
+
+    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Bstr>(mValue); }
+
+  private:
+    void encodeValue(EncodeCallback encodeCallback) const;
+
+    std::vector<uint8_t> mValue;
+};
+
+/**
+ * Bstr is a concrete Item that implements major type 3.
+ */
+class Tstr : public Item {
+  public:
+    static constexpr MajorType kMajorType = TSTR;
+
+    // Construct from a string
+    explicit Tstr(std::string v) : mValue(std::move(v)) {}
+
+    // Construct from a string_view
+    explicit Tstr(const std::string_view& v) : mValue(v) {}
+
+    // Construct from a C string
+    explicit Tstr(const char* v) : mValue(std::string(v)) {}
+
+    // Construct from a pair of iterators
+    template <typename I1, typename I2,
+              typename = typename std::iterator_traits<I1>::iterator_category,
+              typename = typename std::iterator_traits<I2>::iterator_category>
+    explicit Tstr(const std::pair<I1, I2>& pair) : mValue(pair.first, pair.second) {}
+
+    // Construct from an iterator range
+    template <typename I1, typename I2,
+              typename = typename std::iterator_traits<I1>::iterator_category,
+              typename = typename std::iterator_traits<I2>::iterator_category>
+    Tstr(I1 begin, I2 end) : mValue(begin, end) {}
+
+    bool operator==(const Tstr& other) const& { return mValue == other.mValue; }
+
+    MajorType type() const override { return kMajorType; }
+    const Tstr* asTstr() const override { return this; }
+    size_t encodedSize() const override { return headerSize(mValue.size()) + mValue.size(); }
+    using Item::encode;
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override;
+    void encode(EncodeCallback encodeCallback) const override {
+        encodeHeader(mValue.size(), encodeCallback);
+        encodeValue(encodeCallback);
+    }
+
+    const std::string& value() const { return mValue; }
+
+    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Tstr>(mValue); }
+
+  private:
+    void encodeValue(EncodeCallback encodeCallback) const;
+
+    std::string mValue;
+};
+
+/**
+ * CompoundItem is an abstract Item that provides common functionality for Items that contain other
+ * items, i.e. Arrays (CBOR type 4) and Maps (CBOR type 5).
+ */
+class CompoundItem : public Item {
+  public:
+    bool operator==(const CompoundItem& other) const&;
+
+    virtual size_t size() const { return mEntries.size(); }
+
+    bool isCompound() const override { return true; }
+
+    size_t encodedSize() const override {
+        return std::accumulate(mEntries.begin(), mEntries.end(), headerSize(size()),
+                               [](size_t sum, auto& entry) { return sum + entry->encodedSize(); });
+    }
+
+    using Item::encode;  // Make base versions visible.
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override;
+    void encode(EncodeCallback encodeCallback) const override;
+
+    virtual uint64_t addlInfo() const = 0;
+
+  protected:
+    std::vector<std::unique_ptr<Item>> mEntries;
+};
+
+/*
+ * Array is a concrete Item that implements CBOR major type 4.
+ *
+ * Note that Arrays are not copyable.  This is because copying them is expensive and making them
+ * move-only ensures that they're never copied accidentally.  If you actually want to copy an Array,
+ * use the clone() method.
+ */
+class Array : public CompoundItem {
+  public:
+    static constexpr MajorType kMajorType = ARRAY;
+
+    Array() = default;
+    Array(const Array& other) = delete;
+    Array(Array&&) = default;
+    Array& operator=(const Array&) = delete;
+    Array& operator=(Array&&) = default;
+
+    /**
+     * Construct an Array from a variable number of arguments of different types.  See
+     * details::makeItem below for details on what types may be provided.  In general, this accepts
+     * all of the types you'd expect and doest the things you'd expect (integral values are addes as
+     * Uint or Nint, std::string and char* are added as Tstr, bools are added as Bool, etc.).
+     */
+    template <typename... Args, typename Enable>
+    Array(Args&&... args);
+
+    /**
+     * Append a single element to the Array, of any compatible type.
+     */
+    template <typename T>
+    Array& add(T&& v) &;
+    template <typename T>
+    Array&& add(T&& v) &&;
+
+    const std::unique_ptr<Item>& operator[](size_t index) const { return mEntries[index]; }
+    std::unique_ptr<Item>& operator[](size_t index) { return mEntries[index]; }
+
+    MajorType type() const override { return kMajorType; }
+    const Array* asArray() const override { return this; }
+
+    virtual std::unique_ptr<Item> clone() const override;
+
+    uint64_t addlInfo() const override { return size(); }
+};
+
+/*
+ * Map is a concrete Item that implements CBOR major type 5.
+ *
+ * Note that Maps are not copyable.  This is because copying them is expensive and making them
+ * move-only ensures that they're never copied accidentally.  If you actually want to copy a
+ * Map, use the clone() method.
+ */
+class Map : public CompoundItem {
+  public:
+    static constexpr MajorType kMajorType = MAP;
+
+    Map() = default;
+    Map(const Map& other) = delete;
+    Map(Map&&) = default;
+    Map& operator=(const Map& other) = delete;
+    Map& operator=(Map&&) = default;
+
+    /**
+     * Construct a Map from a variable number of arguments of different types.  An even number of
+     * arguments must be provided (this is verified statically). See details::makeItem below for
+     * details on what types may be provided.  In general, this accepts all of the types you'd
+     * expect and doest the things you'd expect (integral values are addes as Uint or Nint,
+     * std::string and char* are added as Tstr, bools are added as Bool, etc.).
+     */
+    template <typename... Args, typename Enable>
+    Map(Args&&... args);
+
+    /**
+     * Append a key/value pair to the Map, of any compatible types.
+     */
+    template <typename Key, typename Value>
+    Map& add(Key&& key, Value&& value) &;
+    template <typename Key, typename Value>
+    Map&& add(Key&& key, Value&& value) &&;
+
+    size_t size() const override {
+        assertInvariant();
+        return mEntries.size() / 2;
+    }
+
+    template <typename Key, typename Enable>
+    std::pair<std::unique_ptr<Item>&, bool> get(Key key);
+
+    std::pair<const std::unique_ptr<Item>&, const std::unique_ptr<Item>&> operator[](
+            size_t index) const {
+        assertInvariant();
+        return {mEntries[index * 2], mEntries[index * 2 + 1]};
+    }
+
+    std::pair<std::unique_ptr<Item>&, std::unique_ptr<Item>&> operator[](size_t index) {
+        assertInvariant();
+        return {mEntries[index * 2], mEntries[index * 2 + 1]};
+    }
+
+    MajorType type() const override { return kMajorType; }
+    const Map* asMap() const override { return this; }
+
+    virtual std::unique_ptr<Item> clone() const override;
+
+    uint64_t addlInfo() const override { return size(); }
+
+  private:
+    void assertInvariant() const;
+};
+
+class Semantic : public CompoundItem {
+  public:
+    static constexpr MajorType kMajorType = SEMANTIC;
+
+    template <typename T>
+    explicit Semantic(uint64_t value, T&& child);
+
+    Semantic(const Semantic& other) = delete;
+    Semantic(Semantic&&) = default;
+    Semantic& operator=(const Semantic& other) = delete;
+    Semantic& operator=(Semantic&&) = default;
+
+    size_t size() const override {
+        assertInvariant();
+        return 1;
+    }
+
+    size_t encodedSize() const override {
+        return std::accumulate(mEntries.begin(), mEntries.end(), headerSize(mValue),
+                               [](size_t sum, auto& entry) { return sum + entry->encodedSize(); });
+    }
+
+    MajorType type() const override { return kMajorType; }
+    const Semantic* asSemantic() const override { return this; }
+
+    const std::unique_ptr<Item>& child() const {
+        assertInvariant();
+        return mEntries[0];
+    }
+
+    std::unique_ptr<Item>& child() {
+        assertInvariant();
+        return mEntries[0];
+    }
+
+    uint64_t value() const { return mValue; }
+
+    uint64_t addlInfo() const override { return value(); }
+
+    virtual std::unique_ptr<Item> clone() const override {
+        assertInvariant();
+        return std::make_unique<Semantic>(mValue, mEntries[0]->clone());
+    }
+
+  protected:
+    Semantic() = default;
+    Semantic(uint64_t value) : mValue(value) {}
+    uint64_t mValue;
+
+  private:
+    void assertInvariant() const;
+};
+
+/**
+ * Simple is abstract Item that implements CBOR major type 7.  It is intended to be subclassed to
+ * create concrete Simple types.  At present only Bool is provided.
+ */
+class Simple : public Item {
+  public:
+    static constexpr MajorType kMajorType = SIMPLE;
+
+    bool operator==(const Simple& other) const&;
+
+    virtual SimpleType simpleType() const = 0;
+    MajorType type() const override { return kMajorType; }
+
+    const Simple* asSimple() const override { return this; }
+
+    virtual const Bool* asBool() const { return nullptr; };
+    virtual const Null* asNull() const { return nullptr; };
+};
+
+/**
+ * Bool is a concrete type that implements CBOR major type 7, with additional item values for TRUE
+ * and FALSE.
+ */
+class Bool : public Simple {
+  public:
+    static constexpr SimpleType kSimpleType = BOOLEAN;
+
+    explicit Bool(bool v) : mValue(v) {}
+
+    bool operator==(const Bool& other) const& { return mValue == other.mValue; }
+
+    SimpleType simpleType() const override { return kSimpleType; }
+    const Bool* asBool() const override { return this; }
+
+    size_t encodedSize() const override { return 1; }
+
+    using Item::encode;
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override {
+        return encodeHeader(mValue ? TRUE : FALSE, pos, end);
+    }
+    void encode(EncodeCallback encodeCallback) const override {
+        encodeHeader(mValue ? TRUE : FALSE, encodeCallback);
+    }
+
+    bool value() const { return mValue; }
+
+    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Bool>(mValue); }
+
+  private:
+    bool mValue;
+};
+
+/**
+ * Null is a concrete type that implements CBOR major type 7, with additional item value for NULL
+ */
+class Null : public Simple {
+  public:
+    static constexpr SimpleType kSimpleType = NULL_T;
+
+    explicit Null() {}
+
+    SimpleType simpleType() const override { return kSimpleType; }
+    const Null* asNull() const override { return this; }
+
+    size_t encodedSize() const override { return 1; }
+
+    using Item::encode;
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override {
+        return encodeHeader(NULL_V, pos, end);
+    }
+    void encode(EncodeCallback encodeCallback) const override {
+        encodeHeader(NULL_V, encodeCallback);
+    }
+
+    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Null>(); }
+};
+
+template <typename T>
+std::unique_ptr<T> downcastItem(std::unique_ptr<Item>&& v) {
+    static_assert(std::is_base_of_v<Item, T> && !std::is_abstract_v<T>,
+                  "returned type is not an Item or is an abstract class");
+    if (v && T::kMajorType == v->type()) {
+        if constexpr (std::is_base_of_v<Simple, T>) {
+            if (T::kSimpleType != v->asSimple()->simpleType()) {
+                return nullptr;
+            }
+        }
+        return std::unique_ptr<T>(static_cast<T*>(v.release()));
+    } else {
+        return nullptr;
+    }
+}
+
+/**
+ * Details. Mostly you shouldn't have to look below, except perhaps at the docstring for makeItem.
+ */
+namespace details {
+
+template <typename T, typename V, typename Enable = void>
+struct is_iterator_pair_over : public std::false_type {};
+
+template <typename I1, typename I2, typename V>
+struct is_iterator_pair_over<
+        std::pair<I1, I2>, V,
+        typename std::enable_if_t<std::is_same_v<V, typename std::iterator_traits<I1>::value_type>>>
+    : public std::true_type {};
+
+template <typename T, typename V, typename Enable = void>
+struct is_unique_ptr_of_subclass_of_v : public std::false_type {};
+
+template <typename T, typename P>
+struct is_unique_ptr_of_subclass_of_v<T, std::unique_ptr<P>,
+                                      typename std::enable_if_t<std::is_base_of_v<T, P>>>
+    : public std::true_type {};
+
+/* check if type is one of std::string (1), std::string_view (2), null-terminated char* (3) or pair
+ *     of iterators (4)*/
+template <typename T, typename Enable = void>
+struct is_text_type_v : public std::false_type {};
+
+template <typename T>
+struct is_text_type_v<
+        T, typename std::enable_if_t<
+                   /* case 1 */  //
+                   std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, std::string>
+                   /* case 2 */  //
+                   || std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, std::string_view>
+                   /* case 3 */                                                 //
+                   || std::is_same_v<std::remove_cv_t<std::decay_t<T>>, char*>  //
+                   || std::is_same_v<std::remove_cv_t<std::decay_t<T>>, const char*>
+                   /* case 4 */
+                   || details::is_iterator_pair_over<T, char>::value>> : public std::true_type {};
+
+/**
+ * Construct a unique_ptr<Item> from many argument types. Accepts:
+ *
+ * (a) booleans;
+ * (b) integers, all sizes and signs;
+ * (c) text strings, as defined by is_text_type_v above;
+ * (d) byte strings, as std::vector<uint8_t>(d1), pair of iterators (d2) or pair<uint8_t*, size_T>
+ *     (d3); and
+ * (e) Item subclass instances, including Array and Map.  Items may be provided by naked pointer
+ *     (e1), unique_ptr (e2), reference (e3) or value (e3).  If provided by reference or value, will
+ *     be moved if possible.  If provided by pointer, ownership is taken.
+ * (f) null pointer;
+ */
+template <typename T>
+std::unique_ptr<Item> makeItem(T v) {
+    Item* p = nullptr;
+    if constexpr (/* case a */ std::is_same_v<T, bool>) {
+        p = new Bool(v);
+    } else if constexpr (/* case b */ std::is_integral_v<T>) {  // b
+        if (v < 0) {
+            p = new Nint(v);
+        } else {
+            p = new Uint(static_cast<uint64_t>(v));
+        }
+    } else if constexpr (/* case c */  //
+                         details::is_text_type_v<T>::value) {
+        p = new Tstr(v);
+    } else if constexpr (/* case d1 */  //
+                         std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>,
+                                        std::vector<uint8_t>>
+                         /* case d2 */  //
+                         || details::is_iterator_pair_over<T, uint8_t>::value
+                         /* case d3 */  //
+                         || std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>,
+                                           std::pair<uint8_t*, size_t>>) {
+        p = new Bstr(v);
+    } else if constexpr (/* case e1 */  //
+                         std::is_pointer_v<T> &&
+                         std::is_base_of_v<Item, std::remove_pointer_t<T>>) {
+        p = v;
+    } else if constexpr (/* case e2 */  //
+                         details::is_unique_ptr_of_subclass_of_v<Item, T>::value) {
+        p = v.release();
+    } else if constexpr (/* case e3 */  //
+                         std::is_base_of_v<Item, T>) {
+        p = new T(std::move(v));
+    } else if constexpr (/* case f */ std::is_null_pointer_v<T>) {
+        p = new Null();
+    } else {
+        // It's odd that this can't be static_assert(false), since it shouldn't be evaluated if one
+        // of the above ifs matches.  But static_assert(false) always triggers.
+        static_assert(std::is_same_v<T, bool>, "makeItem called with unsupported type");
+    }
+    return std::unique_ptr<Item>(p);
+}
+
+}  // namespace details
+
+template <typename... Args,
+          /* Prevent use as copy ctor */ typename = std::enable_if_t<
+                  (sizeof...(Args)) != 1 ||
+                  !(std::is_same_v<Array, std::remove_cv_t<std::remove_reference_t<Args>>> || ...)>>
+Array::Array(Args&&... args) {
+    mEntries.reserve(sizeof...(args));
+    (mEntries.push_back(details::makeItem(std::forward<Args>(args))), ...);
+}
+
+template <typename T>
+Array& Array::add(T&& v) & {
+    mEntries.push_back(details::makeItem(std::forward<T>(v)));
+    return *this;
+}
+
+template <typename T>
+Array&& Array::add(T&& v) && {
+    mEntries.push_back(details::makeItem(std::forward<T>(v)));
+    return std::move(*this);
+}
+
+template <typename... Args,
+          /* Prevent use as copy ctor */ typename = std::enable_if_t<(sizeof...(Args)) != 1>>
+Map::Map(Args&&... args) {
+    static_assert((sizeof...(Args)) % 2 == 0, "Map must have an even number of entries");
+    mEntries.reserve(sizeof...(args));
+    (mEntries.push_back(details::makeItem(std::forward<Args>(args))), ...);
+}
+
+template <typename Key, typename Value>
+Map& Map::add(Key&& key, Value&& value) & {
+    mEntries.push_back(details::makeItem(std::forward<Key>(key)));
+    mEntries.push_back(details::makeItem(std::forward<Value>(value)));
+    return *this;
+}
+
+template <typename Key, typename Value>
+Map&& Map::add(Key&& key, Value&& value) && {
+    this->add(std::forward<Key>(key), std::forward<Value>(value));
+    return std::move(*this);
+}
+
+template <typename Key, typename = std::enable_if_t<std::is_integral_v<Key> ||
+                                                    details::is_text_type_v<Key>::value>>
+std::pair<std::unique_ptr<Item>&, bool> Map::get(Key key) {
+    assertInvariant();
+    auto keyItem = details::makeItem(key);
+    for (size_t i = 0; i < mEntries.size(); i += 2) {
+        if (*keyItem == *mEntries[i]) {
+            return {mEntries[i + 1], true};
+        }
+    }
+    return {keyItem, false};
+}
+
+template <typename T>
+Semantic::Semantic(uint64_t value, T&& child) : mValue(value) {
+    mEntries.reserve(1);
+    mEntries.push_back(details::makeItem(std::forward<T>(child)));
+}
+
+}  // namespace cppbor
diff --git a/identity/support/include/cppbor/cppbor_parse.h b/identity/support/include/cppbor/cppbor_parse.h
new file mode 100644
index 0000000..66cd5a3
--- /dev/null
+++ b/identity/support/include/cppbor/cppbor_parse.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#pragma once
+
+#include "cppbor.h"
+
+namespace cppbor {
+
+using ParseResult = std::tuple<std::unique_ptr<Item> /* result */, const uint8_t* /* newPos */,
+                               std::string /* errMsg */>;
+
+/**
+ * Parse the first CBOR data item (possibly compound) from the range [begin, end).
+ *
+ * Returns a tuple of Item pointer, buffer pointer and error message.  If parsing is successful, the
+ * Item pointer is non-null, the buffer pointer points to the first byte after the
+ * successfully-parsed item and the error message string is empty.  If parsing fails, the Item
+ * pointer is null, the buffer pointer points to the first byte that was unparseable (the first byte
+ * of a data item header that is malformed in some way, e.g. an invalid value, or a length that is
+ * too large for the remining buffer, etc.) and the string contains an error message describing the
+ * problem encountered.
+ */
+ParseResult parse(const uint8_t* begin, const uint8_t* end);
+
+/**
+ * Parse the first CBOR data item (possibly compound) from the byte vector.
+ *
+ * Returns a tuple of Item pointer, buffer pointer and error message.  If parsing is successful, the
+ * Item pointer is non-null, the buffer pointer points to the first byte after the
+ * successfully-parsed item and the error message string is empty.  If parsing fails, the Item
+ * pointer is null, the buffer pointer points to the first byte that was unparseable (the first byte
+ * of a data item header that is malformed in some way, e.g. an invalid value, or a length that is
+ * too large for the remining buffer, etc.) and the string contains an error message describing the
+ * problem encountered.
+ */
+inline ParseResult parse(const std::vector<uint8_t>& encoding) {
+    return parse(encoding.data(), encoding.data() + encoding.size());
+}
+
+/**
+ * Parse the first CBOR data item (possibly compound) from the range [begin, begin + size).
+ *
+ * Returns a tuple of Item pointer, buffer pointer and error message.  If parsing is successful, the
+ * Item pointer is non-null, the buffer pointer points to the first byte after the
+ * successfully-parsed item and the error message string is empty.  If parsing fails, the Item
+ * pointer is null, the buffer pointer points to the first byte that was unparseable (the first byte
+ * of a data item header that is malformed in some way, e.g. an invalid value, or a length that is
+ * too large for the remining buffer, etc.) and the string contains an error message describing the
+ * problem encountered.
+ */
+inline ParseResult parse(const uint8_t* begin, size_t size) {
+    return parse(begin, begin + size);
+}
+
+class ParseClient;
+
+/**
+ * Parse the CBOR data in the range [begin, end) in streaming fashion, calling methods on the
+ * provided ParseClient when elements are found.
+ */
+void parse(const uint8_t* begin, const uint8_t* end, ParseClient* parseClient);
+
+/**
+ * Parse the CBOR data in the vector in streaming fashion, calling methods on the
+ * provided ParseClient when elements are found.
+ */
+inline void parse(const std::vector<uint8_t>& encoding, ParseClient* parseClient) {
+    return parse(encoding.data(), encoding.data() + encoding.size(), parseClient);
+}
+
+/**
+ * A pure interface that callers of the streaming parse functions must implement.
+ */
+class ParseClient {
+  public:
+    virtual ~ParseClient() {}
+
+    /**
+     * Called when an item is found.  The Item pointer points to the found item; use type() and
+     * the appropriate as*() method to examine the value.  hdrBegin points to the first byte of the
+     * header, valueBegin points to the first byte of the value and end points one past the end of
+     * the item.  In the case of header-only items, such as integers, and compound items (ARRAY,
+     * MAP or SEMANTIC) whose end has not yet been found, valueBegin and end are equal and point to
+     * the byte past the header.
+     *
+     * Note that for compound types (ARRAY, MAP, and SEMANTIC), the Item will have no content.  For
+     * Map and Array items, the size() method will return a correct value, but the index operators
+     * are unsafe, and the object cannot be safely compared with another Array/Map.
+     *
+     * The method returns a ParseClient*.  In most cases "return this;" will be the right answer,
+     * but a different ParseClient may be returned, which the parser will begin using. If the method
+     * returns nullptr, parsing will be aborted immediately.
+     */
+    virtual ParseClient* item(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
+                              const uint8_t* valueBegin, const uint8_t* end) = 0;
+
+    /**
+     * Called when the end of a compound item (MAP or ARRAY) is found.  The item argument will be
+     * the same one passed to the item() call -- and may be empty if item() moved its value out.
+     * hdrBegin, valueBegin and end point to the beginning of the item header, the beginning of the
+     * first contained value, and one past the end of the last contained value, respectively.
+     *
+     * Note that the Item will have no content.
+     *
+     * As with item(), itemEnd() can change the ParseClient by returning a different one, or end the
+     * parsing by returning nullptr;
+     */
+    virtual ParseClient* itemEnd(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
+                                 const uint8_t* valueBegin, const uint8_t* end) = 0;
+
+    /**
+     * Called when parsing encounters an error.  position is set to the first unparsed byte (one
+     * past the last successfully-parsed byte) and errorMessage contains an message explaining what
+     * sort of error occurred.
+     */
+    virtual void error(const uint8_t* position, const std::string& errorMessage) = 0;
+};
+
+}  // namespace cppbor
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
new file mode 100644
index 0000000..7d93a4b
--- /dev/null
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -0,0 +1,1815 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "IdentityCredentialSupport"
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#define _POSIX_C_SOURCE 199309L
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <time.h>
+#include <iomanip>
+
+#include <openssl/aes.h>
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/hkdf.h>
+#include <openssl/hmac.h>
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+namespace android {
+namespace hardware {
+namespace identity {
+namespace support {
+
+using ::std::pair;
+using ::std::unique_ptr;
+
+// ---------------------------------------------------------------------------
+// Miscellaneous utilities.
+// ---------------------------------------------------------------------------
+
+void hexdump(const string& name, const vector<uint8_t>& data) {
+    fprintf(stderr, "%s: dumping %zd bytes\n", name.c_str(), data.size());
+    size_t n, m, o;
+    for (n = 0; n < data.size(); n += 16) {
+        fprintf(stderr, "%04zx  ", n);
+        for (m = 0; m < 16 && n + m < data.size(); m++) {
+            fprintf(stderr, "%02x ", data[n + m]);
+        }
+        for (o = m; o < 16; o++) {
+            fprintf(stderr, "   ");
+        }
+        fprintf(stderr, " ");
+        for (m = 0; m < 16 && n + m < data.size(); m++) {
+            int c = data[n + m];
+            fprintf(stderr, "%c", isprint(c) ? c : '.');
+        }
+        fprintf(stderr, "\n");
+    }
+    fprintf(stderr, "\n");
+}
+
+string encodeHex(const uint8_t* data, size_t dataLen) {
+    static const char hexDigits[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
+                                       '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+    string ret;
+    ret.resize(dataLen * 2);
+    for (size_t n = 0; n < dataLen; n++) {
+        uint8_t byte = data[n];
+        ret[n * 2 + 0] = hexDigits[byte >> 4];
+        ret[n * 2 + 1] = hexDigits[byte & 0x0f];
+    }
+
+    return ret;
+}
+
+string encodeHex(const string& str) {
+    return encodeHex(reinterpret_cast<const uint8_t*>(str.data()), str.size());
+}
+
+string encodeHex(const vector<uint8_t>& data) {
+    return encodeHex(data.data(), data.size());
+}
+
+// Returns -1 on error, otherwise an integer in the range 0 through 15, both inclusive.
+int parseHexDigit(char hexDigit) {
+    if (hexDigit >= '0' && hexDigit <= '9') {
+        return int(hexDigit) - '0';
+    } else if (hexDigit >= 'a' && hexDigit <= 'f') {
+        return int(hexDigit) - 'a' + 10;
+    } else if (hexDigit >= 'A' && hexDigit <= 'F') {
+        return int(hexDigit) - 'A' + 10;
+    }
+    return -1;
+}
+
+optional<vector<uint8_t>> decodeHex(const string& hexEncoded) {
+    vector<uint8_t> out;
+    size_t hexSize = hexEncoded.size();
+    if ((hexSize & 1) != 0) {
+        LOG(ERROR) << "Size of data cannot be odd";
+        return {};
+    }
+
+    out.resize(hexSize / 2);
+    for (size_t n = 0; n < hexSize / 2; n++) {
+        int upperNibble = parseHexDigit(hexEncoded[n * 2]);
+        int lowerNibble = parseHexDigit(hexEncoded[n * 2 + 1]);
+        if (upperNibble == -1 || lowerNibble == -1) {
+            LOG(ERROR) << "Invalid hex digit at position " << n;
+            return {};
+        }
+        out[n] = (upperNibble << 4) + lowerNibble;
+    }
+
+    return out;
+}
+
+// ---------------------------------------------------------------------------
+// CBOR utilities.
+// ---------------------------------------------------------------------------
+
+static bool cborAreAllElementsNonCompound(const cppbor::CompoundItem* compoundItem) {
+    if (compoundItem->type() == cppbor::ARRAY) {
+        const cppbor::Array* array = compoundItem->asArray();
+        for (size_t n = 0; n < array->size(); n++) {
+            const cppbor::Item* entry = (*array)[n].get();
+            switch (entry->type()) {
+                case cppbor::ARRAY:
+                case cppbor::MAP:
+                    return false;
+                default:
+                    break;
+            }
+        }
+    } else {
+        const cppbor::Map* map = compoundItem->asMap();
+        for (size_t n = 0; n < map->size(); n++) {
+            auto [keyEntry, valueEntry] = (*map)[n];
+            switch (keyEntry->type()) {
+                case cppbor::ARRAY:
+                case cppbor::MAP:
+                    return false;
+                default:
+                    break;
+            }
+            switch (valueEntry->type()) {
+                case cppbor::ARRAY:
+                case cppbor::MAP:
+                    return false;
+                default:
+                    break;
+            }
+        }
+    }
+    return true;
+}
+
+static bool cborPrettyPrintInternal(const cppbor::Item* item, string& out, size_t indent,
+                                    size_t maxBStrSize, const vector<string>& mapKeysToNotPrint) {
+    char buf[80];
+
+    string indentString(indent, ' ');
+
+    switch (item->type()) {
+        case cppbor::UINT:
+            snprintf(buf, sizeof(buf), "%" PRIu64, item->asUint()->unsignedValue());
+            out.append(buf);
+            break;
+
+        case cppbor::NINT:
+            snprintf(buf, sizeof(buf), "%" PRId64, item->asNint()->value());
+            out.append(buf);
+            break;
+
+        case cppbor::BSTR: {
+            const cppbor::Bstr* bstr = item->asBstr();
+            const vector<uint8_t>& value = bstr->value();
+            if (value.size() > maxBStrSize) {
+                unsigned char digest[SHA_DIGEST_LENGTH];
+                SHA_CTX ctx;
+                SHA1_Init(&ctx);
+                SHA1_Update(&ctx, value.data(), value.size());
+                SHA1_Final(digest, &ctx);
+                char buf2[SHA_DIGEST_LENGTH * 2 + 1];
+                for (size_t n = 0; n < SHA_DIGEST_LENGTH; n++) {
+                    snprintf(buf2 + n * 2, 3, "%02x", digest[n]);
+                }
+                snprintf(buf, sizeof(buf), "<bstr size=%zd sha1=%s>", value.size(), buf2);
+                out.append(buf);
+            } else {
+                out.append("{");
+                for (size_t n = 0; n < value.size(); n++) {
+                    if (n > 0) {
+                        out.append(", ");
+                    }
+                    snprintf(buf, sizeof(buf), "0x%02x", value[n]);
+                    out.append(buf);
+                }
+                out.append("}");
+            }
+        } break;
+
+        case cppbor::TSTR:
+            out.append("'");
+            {
+                // TODO: escape "'" characters
+                out.append(item->asTstr()->value().c_str());
+            }
+            out.append("'");
+            break;
+
+        case cppbor::ARRAY: {
+            const cppbor::Array* array = item->asArray();
+            if (array->size() == 0) {
+                out.append("[]");
+            } else if (cborAreAllElementsNonCompound(array)) {
+                out.append("[");
+                for (size_t n = 0; n < array->size(); n++) {
+                    if (!cborPrettyPrintInternal((*array)[n].get(), out, indent + 2, maxBStrSize,
+                                                 mapKeysToNotPrint)) {
+                        return false;
+                    }
+                    out.append(", ");
+                }
+                out.append("]");
+            } else {
+                out.append("[\n" + indentString);
+                for (size_t n = 0; n < array->size(); n++) {
+                    out.append("  ");
+                    if (!cborPrettyPrintInternal((*array)[n].get(), out, indent + 2, maxBStrSize,
+                                                 mapKeysToNotPrint)) {
+                        return false;
+                    }
+                    out.append(",\n" + indentString);
+                }
+                out.append("]");
+            }
+        } break;
+
+        case cppbor::MAP: {
+            const cppbor::Map* map = item->asMap();
+
+            if (map->size() == 0) {
+                out.append("{}");
+            } else {
+                out.append("{\n" + indentString);
+                for (size_t n = 0; n < map->size(); n++) {
+                    out.append("  ");
+
+                    auto [map_key, map_value] = (*map)[n];
+
+                    if (!cborPrettyPrintInternal(map_key.get(), out, indent + 2, maxBStrSize,
+                                                 mapKeysToNotPrint)) {
+                        return false;
+                    }
+                    out.append(" : ");
+                    if (map_key->type() == cppbor::TSTR &&
+                        std::find(mapKeysToNotPrint.begin(), mapKeysToNotPrint.end(),
+                                  map_key->asTstr()->value()) != mapKeysToNotPrint.end()) {
+                        out.append("<not printed>");
+                    } else {
+                        if (!cborPrettyPrintInternal(map_value.get(), out, indent + 2, maxBStrSize,
+                                                     mapKeysToNotPrint)) {
+                            return false;
+                        }
+                    }
+                    out.append(",\n" + indentString);
+                }
+                out.append("}");
+            }
+        } break;
+
+        case cppbor::SEMANTIC: {
+            const cppbor::Semantic* semantic = item->asSemantic();
+            snprintf(buf, sizeof(buf), "tag %" PRIu64 " ", semantic->value());
+            out.append(buf);
+            cborPrettyPrintInternal(semantic->child().get(), out, indent, maxBStrSize,
+                                    mapKeysToNotPrint);
+        } break;
+
+        case cppbor::SIMPLE:
+            const cppbor::Bool* asBool = item->asSimple()->asBool();
+            const cppbor::Null* asNull = item->asSimple()->asNull();
+            if (asBool != nullptr) {
+                out.append(asBool->value() ? "true" : "false");
+            } else if (asNull != nullptr) {
+                out.append("null");
+            } else {
+                LOG(ERROR) << "Only boolean/null is implemented for SIMPLE";
+                return false;
+            }
+            break;
+    }
+
+    return true;
+}
+
+string cborPrettyPrint(const vector<uint8_t>& encodedCbor, size_t maxBStrSize,
+                       const vector<string>& mapKeysToNotPrint) {
+    auto [item, _, message] = cppbor::parse(encodedCbor);
+    if (item == nullptr) {
+        LOG(ERROR) << "Data to pretty print is not valid CBOR: " << message;
+        return "";
+    }
+
+    string out;
+    cborPrettyPrintInternal(item.get(), out, 0, maxBStrSize, mapKeysToNotPrint);
+    return out;
+}
+
+// ---------------------------------------------------------------------------
+// Crypto functionality / abstraction.
+// ---------------------------------------------------------------------------
+
+struct EVP_CIPHER_CTX_Deleter {
+    void operator()(EVP_CIPHER_CTX* ctx) const {
+        if (ctx != nullptr) {
+            EVP_CIPHER_CTX_free(ctx);
+        }
+    }
+};
+
+using EvpCipherCtxPtr = unique_ptr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_Deleter>;
+
+// bool getRandom(size_t numBytes, vector<uint8_t>& output) {
+optional<vector<uint8_t>> getRandom(size_t numBytes) {
+    vector<uint8_t> output;
+    output.resize(numBytes);
+    if (RAND_bytes(output.data(), numBytes) != 1) {
+        LOG(ERROR) << "RAND_bytes: failed getting " << numBytes << " random";
+        return {};
+    }
+    return output;
+}
+
+optional<vector<uint8_t>> decryptAes128Gcm(const vector<uint8_t>& key,
+                                           const vector<uint8_t>& encryptedData,
+                                           const vector<uint8_t>& additionalAuthenticatedData) {
+    int cipherTextSize = int(encryptedData.size()) - kAesGcmIvSize - kAesGcmTagSize;
+    if (cipherTextSize < 0) {
+        LOG(ERROR) << "encryptedData too small";
+        return {};
+    }
+    unsigned char* nonce = (unsigned char*)encryptedData.data();
+    unsigned char* cipherText = nonce + kAesGcmIvSize;
+    unsigned char* tag = cipherText + cipherTextSize;
+
+    vector<uint8_t> plainText;
+    plainText.resize(cipherTextSize);
+
+    auto ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new());
+    if (ctx.get() == nullptr) {
+        LOG(ERROR) << "EVP_CIPHER_CTX_new: failed";
+        return {};
+    }
+
+    if (EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, NULL, NULL) != 1) {
+        LOG(ERROR) << "EVP_DecryptInit_ex: failed";
+        return {};
+    }
+
+    if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, kAesGcmIvSize, NULL) != 1) {
+        LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed setting nonce length";
+        return {};
+    }
+
+    if (EVP_DecryptInit_ex(ctx.get(), NULL, NULL, (unsigned char*)key.data(), nonce) != 1) {
+        LOG(ERROR) << "EVP_DecryptInit_ex: failed";
+        return {};
+    }
+
+    int numWritten;
+    if (additionalAuthenticatedData.size() > 0) {
+        if (EVP_DecryptUpdate(ctx.get(), NULL, &numWritten,
+                              (unsigned char*)additionalAuthenticatedData.data(),
+                              additionalAuthenticatedData.size()) != 1) {
+            LOG(ERROR) << "EVP_DecryptUpdate: failed for additionalAuthenticatedData";
+            return {};
+        }
+        if ((size_t)numWritten != additionalAuthenticatedData.size()) {
+            LOG(ERROR) << "EVP_DecryptUpdate: Unexpected outl=" << numWritten << " (expected "
+                       << additionalAuthenticatedData.size() << ") for additionalAuthenticatedData";
+            return {};
+        }
+    }
+
+    if (EVP_DecryptUpdate(ctx.get(), (unsigned char*)plainText.data(), &numWritten, cipherText,
+                          cipherTextSize) != 1) {
+        LOG(ERROR) << "EVP_DecryptUpdate: failed";
+        return {};
+    }
+    if (numWritten != cipherTextSize) {
+        LOG(ERROR) << "EVP_DecryptUpdate: Unexpected outl=" << numWritten << " (expected "
+                   << cipherTextSize << ")";
+        return {};
+    }
+
+    if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kAesGcmTagSize, tag)) {
+        LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed setting expected tag";
+        return {};
+    }
+
+    int ret = EVP_DecryptFinal_ex(ctx.get(), (unsigned char*)plainText.data() + numWritten,
+                                  &numWritten);
+    if (ret != 1) {
+        LOG(ERROR) << "EVP_DecryptFinal_ex: failed";
+        return {};
+    }
+    if (numWritten != 0) {
+        LOG(ERROR) << "EVP_DecryptFinal_ex: Unexpected non-zero outl=" << numWritten;
+        return {};
+    }
+
+    return plainText;
+}
+
+optional<vector<uint8_t>> encryptAes128Gcm(const vector<uint8_t>& key, const vector<uint8_t>& nonce,
+                                           const vector<uint8_t>& data,
+                                           const vector<uint8_t>& additionalAuthenticatedData) {
+    if (key.size() != kAes128GcmKeySize) {
+        LOG(ERROR) << "key is not kAes128GcmKeySize bytes";
+        return {};
+    }
+    if (nonce.size() != kAesGcmIvSize) {
+        LOG(ERROR) << "nonce is not kAesGcmIvSize bytes";
+        return {};
+    }
+
+    // The result is the nonce (kAesGcmIvSize bytes), the ciphertext, and
+    // finally the tag (kAesGcmTagSize bytes).
+    vector<uint8_t> encryptedData;
+    encryptedData.resize(data.size() + kAesGcmIvSize + kAesGcmTagSize);
+    unsigned char* noncePtr = (unsigned char*)encryptedData.data();
+    unsigned char* cipherText = noncePtr + kAesGcmIvSize;
+    unsigned char* tag = cipherText + data.size();
+    memcpy(noncePtr, nonce.data(), kAesGcmIvSize);
+
+    auto ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new());
+    if (ctx.get() == nullptr) {
+        LOG(ERROR) << "EVP_CIPHER_CTX_new: failed";
+        return {};
+    }
+
+    if (EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, NULL, NULL) != 1) {
+        LOG(ERROR) << "EVP_EncryptInit_ex: failed";
+        return {};
+    }
+
+    if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, kAesGcmIvSize, NULL) != 1) {
+        LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed setting nonce length";
+        return {};
+    }
+
+    if (EVP_EncryptInit_ex(ctx.get(), NULL, NULL, (unsigned char*)key.data(),
+                           (unsigned char*)nonce.data()) != 1) {
+        LOG(ERROR) << "EVP_EncryptInit_ex: failed";
+        return {};
+    }
+
+    int numWritten;
+    if (additionalAuthenticatedData.size() > 0) {
+        if (EVP_EncryptUpdate(ctx.get(), NULL, &numWritten,
+                              (unsigned char*)additionalAuthenticatedData.data(),
+                              additionalAuthenticatedData.size()) != 1) {
+            LOG(ERROR) << "EVP_EncryptUpdate: failed for additionalAuthenticatedData";
+            return {};
+        }
+        if ((size_t)numWritten != additionalAuthenticatedData.size()) {
+            LOG(ERROR) << "EVP_EncryptUpdate: Unexpected outl=" << numWritten << " (expected "
+                       << additionalAuthenticatedData.size() << ") for additionalAuthenticatedData";
+            return {};
+        }
+    }
+
+    if (data.size() > 0) {
+        if (EVP_EncryptUpdate(ctx.get(), cipherText, &numWritten, (unsigned char*)data.data(),
+                              data.size()) != 1) {
+            LOG(ERROR) << "EVP_EncryptUpdate: failed";
+            return {};
+        }
+        if ((size_t)numWritten != data.size()) {
+            LOG(ERROR) << "EVP_EncryptUpdate: Unexpected outl=" << numWritten << " (expected "
+                       << data.size() << ")";
+            return {};
+        }
+    }
+
+    if (EVP_EncryptFinal_ex(ctx.get(), cipherText + numWritten, &numWritten) != 1) {
+        LOG(ERROR) << "EVP_EncryptFinal_ex: failed";
+        return {};
+    }
+    if (numWritten != 0) {
+        LOG(ERROR) << "EVP_EncryptFinal_ex: Unexpected non-zero outl=" << numWritten;
+        return {};
+    }
+
+    if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kAesGcmTagSize, tag) != 1) {
+        LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed getting tag";
+        return {};
+    }
+
+    return encryptedData;
+}
+
+struct EC_KEY_Deleter {
+    void operator()(EC_KEY* key) const {
+        if (key != nullptr) {
+            EC_KEY_free(key);
+        }
+    }
+};
+using EC_KEY_Ptr = unique_ptr<EC_KEY, EC_KEY_Deleter>;
+
+struct EVP_PKEY_Deleter {
+    void operator()(EVP_PKEY* key) const {
+        if (key != nullptr) {
+            EVP_PKEY_free(key);
+        }
+    }
+};
+using EVP_PKEY_Ptr = unique_ptr<EVP_PKEY, EVP_PKEY_Deleter>;
+
+struct EVP_PKEY_CTX_Deleter {
+    void operator()(EVP_PKEY_CTX* ctx) const {
+        if (ctx != nullptr) {
+            EVP_PKEY_CTX_free(ctx);
+        }
+    }
+};
+using EVP_PKEY_CTX_Ptr = unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_Deleter>;
+
+struct EC_GROUP_Deleter {
+    void operator()(EC_GROUP* group) const {
+        if (group != nullptr) {
+            EC_GROUP_free(group);
+        }
+    }
+};
+using EC_GROUP_Ptr = unique_ptr<EC_GROUP, EC_GROUP_Deleter>;
+
+struct EC_POINT_Deleter {
+    void operator()(EC_POINT* point) const {
+        if (point != nullptr) {
+            EC_POINT_free(point);
+        }
+    }
+};
+
+using EC_POINT_Ptr = unique_ptr<EC_POINT, EC_POINT_Deleter>;
+
+struct ECDSA_SIG_Deleter {
+    void operator()(ECDSA_SIG* sig) const {
+        if (sig != nullptr) {
+            ECDSA_SIG_free(sig);
+        }
+    }
+};
+using ECDSA_SIG_Ptr = unique_ptr<ECDSA_SIG, ECDSA_SIG_Deleter>;
+
+struct X509_Deleter {
+    void operator()(X509* x509) const {
+        if (x509 != nullptr) {
+            X509_free(x509);
+        }
+    }
+};
+using X509_Ptr = unique_ptr<X509, X509_Deleter>;
+
+struct PKCS12_Deleter {
+    void operator()(PKCS12* pkcs12) const {
+        if (pkcs12 != nullptr) {
+            PKCS12_free(pkcs12);
+        }
+    }
+};
+using PKCS12_Ptr = unique_ptr<PKCS12, PKCS12_Deleter>;
+
+struct BIGNUM_Deleter {
+    void operator()(BIGNUM* bignum) const {
+        if (bignum != nullptr) {
+            BN_free(bignum);
+        }
+    }
+};
+using BIGNUM_Ptr = unique_ptr<BIGNUM, BIGNUM_Deleter>;
+
+struct ASN1_INTEGER_Deleter {
+    void operator()(ASN1_INTEGER* value) const {
+        if (value != nullptr) {
+            ASN1_INTEGER_free(value);
+        }
+    }
+};
+using ASN1_INTEGER_Ptr = unique_ptr<ASN1_INTEGER, ASN1_INTEGER_Deleter>;
+
+struct ASN1_TIME_Deleter {
+    void operator()(ASN1_TIME* value) const {
+        if (value != nullptr) {
+            ASN1_TIME_free(value);
+        }
+    }
+};
+using ASN1_TIME_Ptr = unique_ptr<ASN1_TIME, ASN1_TIME_Deleter>;
+
+struct X509_NAME_Deleter {
+    void operator()(X509_NAME* value) const {
+        if (value != nullptr) {
+            X509_NAME_free(value);
+        }
+    }
+};
+using X509_NAME_Ptr = unique_ptr<X509_NAME, X509_NAME_Deleter>;
+
+vector<uint8_t> certificateChainJoin(const vector<vector<uint8_t>>& certificateChain) {
+    vector<uint8_t> ret;
+    for (const vector<uint8_t>& certificate : certificateChain) {
+        ret.insert(ret.end(), certificate.begin(), certificate.end());
+    }
+    return ret;
+}
+
+optional<vector<vector<uint8_t>>> certificateChainSplit(const vector<uint8_t>& certificateChain) {
+    const unsigned char* pStart = (unsigned char*)certificateChain.data();
+    const unsigned char* p = pStart;
+    const unsigned char* pEnd = p + certificateChain.size();
+    vector<vector<uint8_t>> certificates;
+    while (p < pEnd) {
+        size_t begin = p - pStart;
+        auto x509 = X509_Ptr(d2i_X509(nullptr, &p, pEnd - p));
+        size_t next = p - pStart;
+        if (x509 == nullptr) {
+            LOG(ERROR) << "Error parsing X509 certificate";
+            return {};
+        }
+        vector<uint8_t> cert =
+                vector<uint8_t>(certificateChain.begin() + begin, certificateChain.begin() + next);
+        certificates.push_back(std::move(cert));
+    }
+    return certificates;
+}
+
+static bool parseX509Certificates(const vector<uint8_t>& certificateChain,
+                                  vector<X509_Ptr>& parsedCertificates) {
+    const unsigned char* p = (unsigned char*)certificateChain.data();
+    const unsigned char* pEnd = p + certificateChain.size();
+    parsedCertificates.resize(0);
+    while (p < pEnd) {
+        auto x509 = X509_Ptr(d2i_X509(nullptr, &p, pEnd - p));
+        if (x509 == nullptr) {
+            LOG(ERROR) << "Error parsing X509 certificate";
+            return false;
+        }
+        parsedCertificates.push_back(std::move(x509));
+    }
+    return true;
+}
+
+// TODO: Right now the only check we perform is to check that each certificate
+//       is signed by its successor. We should - but currently don't - also check
+//       things like valid dates etc.
+//
+//       It would be nice to use X509_verify_cert() instead of doing our own thing.
+//
+bool certificateChainValidate(const vector<uint8_t>& certificateChain) {
+    vector<X509_Ptr> certs;
+
+    if (!parseX509Certificates(certificateChain, certs)) {
+        LOG(ERROR) << "Error parsing X509 certificates";
+        return false;
+    }
+
+    if (certs.size() == 1) {
+        return true;
+    }
+
+    for (size_t n = 1; n < certs.size(); n++) {
+        const X509_Ptr& keyCert = certs[n - 1];
+        const X509_Ptr& signingCert = certs[n];
+        EVP_PKEY_Ptr signingPubkey(X509_get_pubkey(signingCert.get()));
+        if (X509_verify(keyCert.get(), signingPubkey.get()) != 1) {
+            LOG(ERROR) << "Error validating cert at index " << n - 1
+                       << " is signed by its successor";
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool checkEcDsaSignature(const vector<uint8_t>& digest, const vector<uint8_t>& signature,
+                         const vector<uint8_t>& publicKey) {
+    const unsigned char* p = (unsigned char*)signature.data();
+    auto sig = ECDSA_SIG_Ptr(d2i_ECDSA_SIG(nullptr, &p, signature.size()));
+    if (sig.get() == nullptr) {
+        LOG(ERROR) << "Error decoding DER encoded signature";
+        return false;
+    }
+
+    auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
+    if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
+        1) {
+        LOG(ERROR) << "Error decoding publicKey";
+        return false;
+    }
+    auto ecKey = EC_KEY_Ptr(EC_KEY_new());
+    auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    if (ecKey.get() == nullptr || pkey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return false;
+    }
+    if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
+        LOG(ERROR) << "Error setting group";
+        return false;
+    }
+    if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
+        LOG(ERROR) << "Error setting point";
+        return false;
+    }
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
+        LOG(ERROR) << "Error setting key";
+        return false;
+    }
+
+    int rc = ECDSA_do_verify(digest.data(), digest.size(), sig.get(), ecKey.get());
+    if (rc != 1) {
+        LOG(ERROR) << "Error verifying signature (rc=" << rc << ")";
+        return false;
+    }
+
+    return true;
+}
+
+vector<uint8_t> sha256(const vector<uint8_t>& data) {
+    vector<uint8_t> ret;
+    ret.resize(SHA256_DIGEST_LENGTH);
+    SHA256_CTX ctx;
+    SHA256_Init(&ctx);
+    SHA256_Update(&ctx, data.data(), data.size());
+    SHA256_Final((unsigned char*)ret.data(), &ctx);
+    return ret;
+}
+
+optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data) {
+    auto bn = BIGNUM_Ptr(BN_bin2bn(key.data(), key.size(), nullptr));
+    if (bn.get() == nullptr) {
+        LOG(ERROR) << "Error creating BIGNUM";
+        return {};
+    }
+
+    auto ec_key = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+    if (EC_KEY_set_private_key(ec_key.get(), bn.get()) != 1) {
+        LOG(ERROR) << "Error setting private key from BIGNUM";
+        return {};
+    }
+
+    auto digest = sha256(data);
+    ECDSA_SIG* sig = ECDSA_do_sign(digest.data(), digest.size(), ec_key.get());
+    if (sig == nullptr) {
+        LOG(ERROR) << "Error signing digest";
+        return {};
+    }
+    size_t len = i2d_ECDSA_SIG(sig, nullptr);
+    vector<uint8_t> signature;
+    signature.resize(len);
+    unsigned char* p = (unsigned char*)signature.data();
+    i2d_ECDSA_SIG(sig, &p);
+    ECDSA_SIG_free(sig);
+    return signature;
+}
+
+optional<vector<uint8_t>> hmacSha256(const vector<uint8_t>& key, const vector<uint8_t>& data) {
+    HMAC_CTX ctx;
+    HMAC_CTX_init(&ctx);
+    if (HMAC_Init_ex(&ctx, key.data(), key.size(), EVP_sha256(), nullptr /* impl */) != 1) {
+        LOG(ERROR) << "Error initializing HMAC_CTX";
+        return {};
+    }
+    if (HMAC_Update(&ctx, data.data(), data.size()) != 1) {
+        LOG(ERROR) << "Error updating HMAC_CTX";
+        return {};
+    }
+    vector<uint8_t> hmac;
+    hmac.resize(32);
+    unsigned int size = 0;
+    if (HMAC_Final(&ctx, hmac.data(), &size) != 1) {
+        LOG(ERROR) << "Error finalizing HMAC_CTX";
+        return {};
+    }
+    if (size != 32) {
+        LOG(ERROR) << "Expected 32 bytes from HMAC_Final, got " << size;
+        return {};
+    }
+    return hmac;
+}
+
+optional<vector<uint8_t>> createEcKeyPair() {
+    auto ec_key = EC_KEY_Ptr(EC_KEY_new());
+    auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    if (ec_key.get() == nullptr || pkey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return {};
+    }
+
+    if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
+        EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
+        LOG(ERROR) << "Error generating key";
+        return {};
+    }
+
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
+        LOG(ERROR) << "Error getting private key";
+        return {};
+    }
+
+    int size = i2d_PrivateKey(pkey.get(), nullptr);
+    if (size == 0) {
+        LOG(ERROR) << "Error generating public key encoding";
+        return {};
+    }
+    vector<uint8_t> keyPair;
+    keyPair.resize(size);
+    unsigned char* p = keyPair.data();
+    i2d_PrivateKey(pkey.get(), &p);
+    return keyPair;
+}
+
+optional<vector<uint8_t>> ecKeyPairGetPublicKey(const vector<uint8_t>& keyPair) {
+    const unsigned char* p = (const unsigned char*)keyPair.data();
+    auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
+    if (pkey.get() == nullptr) {
+        LOG(ERROR) << "Error parsing keyPair";
+        return {};
+    }
+
+    auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
+    if (ecKey.get() == nullptr) {
+        LOG(ERROR) << "Failed getting EC key";
+        return {};
+    }
+
+    auto ecGroup = EC_KEY_get0_group(ecKey.get());
+    auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
+    int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
+                                  nullptr);
+    if (size == 0) {
+        LOG(ERROR) << "Error generating public key encoding";
+        return {};
+    }
+
+    vector<uint8_t> publicKey;
+    publicKey.resize(size);
+    EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
+                       publicKey.size(), nullptr);
+    return publicKey;
+}
+
+optional<vector<uint8_t>> ecKeyPairGetPrivateKey(const vector<uint8_t>& keyPair) {
+    const unsigned char* p = (const unsigned char*)keyPair.data();
+    auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
+    if (pkey.get() == nullptr) {
+        LOG(ERROR) << "Error parsing keyPair";
+        return {};
+    }
+
+    auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
+    if (ecKey.get() == nullptr) {
+        LOG(ERROR) << "Failed getting EC key";
+        return {};
+    }
+
+    const BIGNUM* bignum = EC_KEY_get0_private_key(ecKey.get());
+    if (bignum == nullptr) {
+        LOG(ERROR) << "Error getting bignum from private key";
+        return {};
+    }
+    vector<uint8_t> privateKey;
+    privateKey.resize(BN_num_bytes(bignum));
+    BN_bn2bin(bignum, privateKey.data());
+    return privateKey;
+}
+
+optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, const string& name,
+                                             const string& serialDecimal, const string& issuer,
+                                             const string& subject, time_t validityNotBefore,
+                                             time_t validityNotAfter) {
+    const unsigned char* p = (const unsigned char*)keyPair.data();
+    auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
+    if (pkey.get() == nullptr) {
+        LOG(ERROR) << "Error parsing keyPair";
+        return {};
+    }
+
+    auto x509 = X509_Ptr(X509_new());
+    if (!x509.get()) {
+        LOG(ERROR) << "Error creating X509 certificate";
+        return {};
+    }
+
+    if (!X509_set_version(x509.get(), 2 /* version 3, but zero-based */)) {
+        LOG(ERROR) << "Error setting version to 3";
+        return {};
+    }
+
+    if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
+        LOG(ERROR) << "Error setting public key";
+        return {};
+    }
+
+    BIGNUM* bignumSerial = nullptr;
+    if (BN_dec2bn(&bignumSerial, serialDecimal.c_str()) == 0) {
+        LOG(ERROR) << "Error parsing serial";
+        return {};
+    }
+    auto bignumSerialPtr = BIGNUM_Ptr(bignumSerial);
+    auto asnSerial = ASN1_INTEGER_Ptr(BN_to_ASN1_INTEGER(bignumSerial, nullptr));
+    if (X509_set_serialNumber(x509.get(), asnSerial.get()) != 1) {
+        LOG(ERROR) << "Error setting serial";
+        return {};
+    }
+
+    auto x509Issuer = X509_NAME_Ptr(X509_NAME_new());
+    if (x509Issuer.get() == nullptr ||
+        X509_NAME_add_entry_by_txt(x509Issuer.get(), "CN", MBSTRING_ASC,
+                                   (const uint8_t*)issuer.c_str(), issuer.size(), -1 /* loc */,
+                                   0 /* set */) != 1 ||
+        X509_set_issuer_name(x509.get(), x509Issuer.get()) != 1) {
+        LOG(ERROR) << "Error setting issuer";
+        return {};
+    }
+
+    auto x509Subject = X509_NAME_Ptr(X509_NAME_new());
+    if (x509Subject.get() == nullptr ||
+        X509_NAME_add_entry_by_txt(x509Subject.get(), "CN", MBSTRING_ASC,
+                                   (const uint8_t*)subject.c_str(), subject.size(), -1 /* loc */,
+                                   0 /* set */) != 1 ||
+        X509_set_subject_name(x509.get(), x509Subject.get()) != 1) {
+        LOG(ERROR) << "Error setting subject";
+        return {};
+    }
+
+    auto asnNotBefore = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotBefore));
+    if (asnNotBefore.get() == nullptr || X509_set_notBefore(x509.get(), asnNotBefore.get()) != 1) {
+        LOG(ERROR) << "Error setting notBefore";
+        return {};
+    }
+
+    auto asnNotAfter = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotAfter));
+    if (asnNotAfter.get() == nullptr || X509_set_notAfter(x509.get(), asnNotAfter.get()) != 1) {
+        LOG(ERROR) << "Error setting notAfter";
+        return {};
+    }
+
+    if (X509_sign(x509.get(), pkey.get(), EVP_sha256()) == 0) {
+        LOG(ERROR) << "Error signing X509 certificate";
+        return {};
+    }
+
+    // Ideally we wouldn't encrypt it (we're only using this function for
+    // sending a key-pair over binder to the Android app) but BoringSSL does not
+    // support this: from pkcs8_x509.c in BoringSSL: "In OpenSSL, -1 here means
+    // to use no encryption, which we do not currently support."
+    //
+    // Passing nullptr as |pass|, though, means "no password". So we'll do that.
+    // Compare with the receiving side - CredstoreIdentityCredential.java - where
+    // an empty char[] is passed as the password.
+    //
+    auto pkcs12 = PKCS12_Ptr(PKCS12_create(nullptr, name.c_str(), pkey.get(), x509.get(),
+                                           nullptr,  // ca
+                                           0,        // nid_key
+                                           0,        // nid_cert
+                                           0,        // iter,
+                                           0,        // mac_iter,
+                                           0));      // keytype
+    if (pkcs12.get() == nullptr) {
+        char buf[128];
+        long errCode = ERR_get_error();
+        ERR_error_string_n(errCode, buf, sizeof buf);
+        LOG(ERROR) << "Error creating PKCS12, code " << errCode << ": " << buf;
+        return {};
+    }
+
+    unsigned char* buffer = nullptr;
+    int length = i2d_PKCS12(pkcs12.get(), &buffer);
+    if (length < 0) {
+        LOG(ERROR) << "Error encoding PKCS12";
+        return {};
+    }
+    vector<uint8_t> pkcs12Bytes;
+    pkcs12Bytes.resize(length);
+    memcpy(pkcs12Bytes.data(), buffer, length);
+    OPENSSL_free(buffer);
+
+    return pkcs12Bytes;
+}
+
+optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
+        const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey,
+        const string& serialDecimal, const string& issuer, const string& subject,
+        time_t validityNotBefore, time_t validityNotAfter) {
+    auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
+    if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
+        1) {
+        LOG(ERROR) << "Error decoding publicKey";
+        return {};
+    }
+    auto ecKey = EC_KEY_Ptr(EC_KEY_new());
+    auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    if (ecKey.get() == nullptr || pkey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return {};
+    }
+    if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
+        LOG(ERROR) << "Error setting group";
+        return {};
+    }
+    if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
+        LOG(ERROR) << "Error setting point";
+        return {};
+    }
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
+        LOG(ERROR) << "Error setting key";
+        return {};
+    }
+
+    auto bn = BIGNUM_Ptr(BN_bin2bn(signingKey.data(), signingKey.size(), nullptr));
+    if (bn.get() == nullptr) {
+        LOG(ERROR) << "Error creating BIGNUM for private key";
+        return {};
+    }
+    auto privEcKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+    if (EC_KEY_set_private_key(privEcKey.get(), bn.get()) != 1) {
+        LOG(ERROR) << "Error setting private key from BIGNUM";
+        return {};
+    }
+    auto privPkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    if (EVP_PKEY_set1_EC_KEY(privPkey.get(), privEcKey.get()) != 1) {
+        LOG(ERROR) << "Error setting private key";
+        return {};
+    }
+
+    auto x509 = X509_Ptr(X509_new());
+    if (!x509.get()) {
+        LOG(ERROR) << "Error creating X509 certificate";
+        return {};
+    }
+
+    if (!X509_set_version(x509.get(), 2 /* version 3, but zero-based */)) {
+        LOG(ERROR) << "Error setting version to 3";
+        return {};
+    }
+
+    if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
+        LOG(ERROR) << "Error setting public key";
+        return {};
+    }
+
+    BIGNUM* bignumSerial = nullptr;
+    if (BN_dec2bn(&bignumSerial, serialDecimal.c_str()) == 0) {
+        LOG(ERROR) << "Error parsing serial";
+        return {};
+    }
+    auto bignumSerialPtr = BIGNUM_Ptr(bignumSerial);
+    auto asnSerial = ASN1_INTEGER_Ptr(BN_to_ASN1_INTEGER(bignumSerial, nullptr));
+    if (X509_set_serialNumber(x509.get(), asnSerial.get()) != 1) {
+        LOG(ERROR) << "Error setting serial";
+        return {};
+    }
+
+    auto x509Issuer = X509_NAME_Ptr(X509_NAME_new());
+    if (x509Issuer.get() == nullptr ||
+        X509_NAME_add_entry_by_txt(x509Issuer.get(), "CN", MBSTRING_ASC,
+                                   (const uint8_t*)issuer.c_str(), issuer.size(), -1 /* loc */,
+                                   0 /* set */) != 1 ||
+        X509_set_issuer_name(x509.get(), x509Issuer.get()) != 1) {
+        LOG(ERROR) << "Error setting issuer";
+        return {};
+    }
+
+    auto x509Subject = X509_NAME_Ptr(X509_NAME_new());
+    if (x509Subject.get() == nullptr ||
+        X509_NAME_add_entry_by_txt(x509Subject.get(), "CN", MBSTRING_ASC,
+                                   (const uint8_t*)subject.c_str(), subject.size(), -1 /* loc */,
+                                   0 /* set */) != 1 ||
+        X509_set_subject_name(x509.get(), x509Subject.get()) != 1) {
+        LOG(ERROR) << "Error setting subject";
+        return {};
+    }
+
+    auto asnNotBefore = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotBefore));
+    if (asnNotBefore.get() == nullptr || X509_set_notBefore(x509.get(), asnNotBefore.get()) != 1) {
+        LOG(ERROR) << "Error setting notBefore";
+        return {};
+    }
+
+    auto asnNotAfter = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotAfter));
+    if (asnNotAfter.get() == nullptr || X509_set_notAfter(x509.get(), asnNotAfter.get()) != 1) {
+        LOG(ERROR) << "Error setting notAfter";
+        return {};
+    }
+
+    if (X509_sign(x509.get(), privPkey.get(), EVP_sha256()) == 0) {
+        LOG(ERROR) << "Error signing X509 certificate";
+        return {};
+    }
+
+    unsigned char* buffer = nullptr;
+    int length = i2d_X509(x509.get(), &buffer);
+    if (length < 0) {
+        LOG(ERROR) << "Error DER encoding X509 certificate";
+        return {};
+    }
+
+    vector<uint8_t> certificate;
+    certificate.resize(length);
+    memcpy(certificate.data(), buffer, length);
+    OPENSSL_free(buffer);
+    return certificate;
+}
+
+optional<vector<uint8_t>> ecdh(const vector<uint8_t>& publicKey,
+                               const vector<uint8_t>& privateKey) {
+    auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
+    if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
+        1) {
+        LOG(ERROR) << "Error decoding publicKey";
+        return {};
+    }
+    auto ecKey = EC_KEY_Ptr(EC_KEY_new());
+    auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    if (ecKey.get() == nullptr || pkey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return {};
+    }
+    if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
+        LOG(ERROR) << "Error setting group";
+        return {};
+    }
+    if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
+        LOG(ERROR) << "Error setting point";
+        return {};
+    }
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
+        LOG(ERROR) << "Error setting key";
+        return {};
+    }
+
+    auto bn = BIGNUM_Ptr(BN_bin2bn(privateKey.data(), privateKey.size(), nullptr));
+    if (bn.get() == nullptr) {
+        LOG(ERROR) << "Error creating BIGNUM for private key";
+        return {};
+    }
+    auto privEcKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+    if (EC_KEY_set_private_key(privEcKey.get(), bn.get()) != 1) {
+        LOG(ERROR) << "Error setting private key from BIGNUM";
+        return {};
+    }
+    auto privPkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    if (EVP_PKEY_set1_EC_KEY(privPkey.get(), privEcKey.get()) != 1) {
+        LOG(ERROR) << "Error setting private key";
+        return {};
+    }
+
+    auto ctx = EVP_PKEY_CTX_Ptr(EVP_PKEY_CTX_new(privPkey.get(), NULL));
+    if (ctx.get() == nullptr) {
+        LOG(ERROR) << "Error creating context";
+        return {};
+    }
+
+    if (EVP_PKEY_derive_init(ctx.get()) != 1) {
+        LOG(ERROR) << "Error initializing context";
+        return {};
+    }
+
+    if (EVP_PKEY_derive_set_peer(ctx.get(), pkey.get()) != 1) {
+        LOG(ERROR) << "Error setting peer";
+        return {};
+    }
+
+    /* Determine buffer length for shared secret */
+    size_t secretLen = 0;
+    if (EVP_PKEY_derive(ctx.get(), NULL, &secretLen) != 1) {
+        LOG(ERROR) << "Error determing length of shared secret";
+        return {};
+    }
+    vector<uint8_t> sharedSecret;
+    sharedSecret.resize(secretLen);
+
+    if (EVP_PKEY_derive(ctx.get(), sharedSecret.data(), &secretLen) != 1) {
+        LOG(ERROR) << "Error deriving shared secret";
+        return {};
+    }
+    return sharedSecret;
+}
+
+optional<vector<uint8_t>> hkdf(const vector<uint8_t>& sharedSecret, const vector<uint8_t>& salt,
+                               const vector<uint8_t>& info, size_t size) {
+    vector<uint8_t> derivedKey;
+    derivedKey.resize(size);
+    if (HKDF(derivedKey.data(), derivedKey.size(), EVP_sha256(), sharedSecret.data(),
+             sharedSecret.size(), salt.data(), salt.size(), info.data(), info.size()) != 1) {
+        LOG(ERROR) << "Error deriving key";
+        return {};
+    }
+    return derivedKey;
+}
+
+void removeLeadingZeroes(vector<uint8_t>& vec) {
+    while (vec.size() >= 1 && vec[0] == 0x00) {
+        vec.erase(vec.begin());
+    }
+}
+
+tuple<bool, vector<uint8_t>, vector<uint8_t>> ecPublicKeyGetXandY(
+        const vector<uint8_t>& publicKey) {
+    if (publicKey.size() != 65 || publicKey[0] != 0x04) {
+        LOG(ERROR) << "publicKey is not in the expected format";
+        return std::make_tuple(false, vector<uint8_t>(), vector<uint8_t>());
+    }
+    vector<uint8_t> x, y;
+    x.resize(32);
+    y.resize(32);
+    memcpy(x.data(), publicKey.data() + 1, 32);
+    memcpy(y.data(), publicKey.data() + 33, 32);
+
+    removeLeadingZeroes(x);
+    removeLeadingZeroes(y);
+
+    return std::make_tuple(true, x, y);
+}
+
+optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& certificateChain) {
+    vector<X509_Ptr> certs;
+    if (!parseX509Certificates(certificateChain, certs)) {
+        return {};
+    }
+    if (certs.size() < 1) {
+        LOG(ERROR) << "No certificates in chain";
+        return {};
+    }
+
+    int algoId = OBJ_obj2nid(certs[0]->cert_info->key->algor->algorithm);
+    if (algoId != NID_X9_62_id_ecPublicKey) {
+        LOG(ERROR) << "Expected NID_X9_62_id_ecPublicKey, got " << OBJ_nid2ln(algoId);
+        return {};
+    }
+
+    auto pkey = EVP_PKEY_Ptr(X509_get_pubkey(certs[0].get()));
+    if (pkey.get() == nullptr) {
+        LOG(ERROR) << "No public key";
+        return {};
+    }
+
+    auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
+    if (ecKey.get() == nullptr) {
+        LOG(ERROR) << "Failed getting EC key";
+        return {};
+    }
+
+    auto ecGroup = EC_KEY_get0_group(ecKey.get());
+    auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
+    int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
+                                  nullptr);
+    if (size == 0) {
+        LOG(ERROR) << "Error generating public key encoding";
+        return {};
+    }
+    vector<uint8_t> publicKey;
+    publicKey.resize(size);
+    EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
+                       publicKey.size(), nullptr);
+    return publicKey;
+}
+
+// ---------------------------------------------------------------------------
+// COSE Utility Functions
+// ---------------------------------------------------------------------------
+
+vector<uint8_t> coseBuildToBeSigned(const vector<uint8_t>& encodedProtectedHeaders,
+                                    const vector<uint8_t>& data,
+                                    const vector<uint8_t>& detachedContent) {
+    cppbor::Array sigStructure;
+    sigStructure.add("Signature1");
+    sigStructure.add(encodedProtectedHeaders);
+
+    // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
+    // so external_aad is the empty bstr
+    vector<uint8_t> emptyExternalAad;
+    sigStructure.add(emptyExternalAad);
+
+    // Next field is the payload, independently of how it's transported (RFC
+    // 8152 section 4.4). Since our API specifies only one of |data| and
+    // |detachedContent| can be non-empty, it's simply just the non-empty one.
+    if (data.size() > 0) {
+        sigStructure.add(data);
+    } else {
+        sigStructure.add(detachedContent);
+    }
+    return sigStructure.encode();
+}
+
+vector<uint8_t> coseEncodeHeaders(const cppbor::Map& protectedHeaders) {
+    if (protectedHeaders.size() == 0) {
+        cppbor::Bstr emptyBstr(vector<uint8_t>({}));
+        return emptyBstr.encode();
+    }
+    return protectedHeaders.encode();
+}
+
+// From https://tools.ietf.org/html/rfc8152
+const int COSE_LABEL_ALG = 1;
+const int COSE_LABEL_X5CHAIN = 33;  // temporary identifier
+
+// From "COSE Algorithms" registry
+const int COSE_ALG_ECDSA_256 = -7;
+const int COSE_ALG_HMAC_256_256 = 5;
+
+bool ecdsaSignatureCoseToDer(const vector<uint8_t>& ecdsaCoseSignature,
+                             vector<uint8_t>& ecdsaDerSignature) {
+    if (ecdsaCoseSignature.size() != 64) {
+        LOG(ERROR) << "COSE signature length is " << ecdsaCoseSignature.size() << ", expected 64";
+        return false;
+    }
+
+    auto rBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data(), 32, nullptr));
+    if (rBn.get() == nullptr) {
+        LOG(ERROR) << "Error creating BIGNUM for r";
+        return false;
+    }
+
+    auto sBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data() + 32, 32, nullptr));
+    if (sBn.get() == nullptr) {
+        LOG(ERROR) << "Error creating BIGNUM for s";
+        return false;
+    }
+
+    ECDSA_SIG sig;
+    sig.r = rBn.get();
+    sig.s = sBn.get();
+
+    size_t len = i2d_ECDSA_SIG(&sig, nullptr);
+    ecdsaDerSignature.resize(len);
+    unsigned char* p = (unsigned char*)ecdsaDerSignature.data();
+    i2d_ECDSA_SIG(&sig, &p);
+
+    return true;
+}
+
+bool ecdsaSignatureDerToCose(const vector<uint8_t>& ecdsaDerSignature,
+                             vector<uint8_t>& ecdsaCoseSignature) {
+    ECDSA_SIG* sig;
+    const unsigned char* p = ecdsaDerSignature.data();
+    sig = d2i_ECDSA_SIG(nullptr, &p, ecdsaDerSignature.size());
+    if (sig == nullptr) {
+        LOG(ERROR) << "Error decoding DER signature";
+        return false;
+    }
+
+    ecdsaCoseSignature.clear();
+    ecdsaCoseSignature.resize(64);
+    if (BN_bn2binpad(sig->r, ecdsaCoseSignature.data(), 32) != 32) {
+        LOG(ERROR) << "Error encoding r";
+        return false;
+    }
+    if (BN_bn2binpad(sig->s, ecdsaCoseSignature.data() + 32, 32) != 32) {
+        LOG(ERROR) << "Error encoding s";
+        return false;
+    }
+    return true;
+}
+
+optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data,
+                                        const vector<uint8_t>& detachedContent,
+                                        const vector<uint8_t>& certificateChain) {
+    cppbor::Map unprotectedHeaders;
+    cppbor::Map protectedHeaders;
+
+    if (data.size() > 0 && detachedContent.size() > 0) {
+        LOG(ERROR) << "data and detachedContent cannot both be non-empty";
+        return {};
+    }
+
+    protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_ECDSA_256);
+
+    if (certificateChain.size() != 0) {
+        optional<vector<vector<uint8_t>>> certs = support::certificateChainSplit(certificateChain);
+        if (!certs) {
+            LOG(ERROR) << "Error splitting certificate chain";
+            return {};
+        }
+        if (certs.value().size() == 1) {
+            unprotectedHeaders.add(COSE_LABEL_X5CHAIN, certs.value()[0]);
+        } else {
+            cppbor::Array certArray;
+            for (const vector<uint8_t>& cert : certs.value()) {
+                certArray.add(cert);
+            }
+            unprotectedHeaders.add(COSE_LABEL_X5CHAIN, std::move(certArray));
+        }
+    }
+
+    vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
+    vector<uint8_t> toBeSigned =
+            coseBuildToBeSigned(encodedProtectedHeaders, data, detachedContent);
+
+    optional<vector<uint8_t>> derSignature = signEcDsa(key, toBeSigned);
+    if (!derSignature) {
+        LOG(ERROR) << "Error signing toBeSigned data";
+        return {};
+    }
+    vector<uint8_t> coseSignature;
+    if (!ecdsaSignatureDerToCose(derSignature.value(), coseSignature)) {
+        LOG(ERROR) << "Error converting ECDSA signature from DER to COSE format";
+        return {};
+    }
+
+    cppbor::Array coseSign1;
+    coseSign1.add(encodedProtectedHeaders);
+    coseSign1.add(std::move(unprotectedHeaders));
+    if (data.size() == 0) {
+        cppbor::Null nullValue;
+        coseSign1.add(std::move(nullValue));
+    } else {
+        coseSign1.add(data);
+    }
+    coseSign1.add(coseSignature);
+    vector<uint8_t> signatureCoseSign1;
+    signatureCoseSign1 = coseSign1.encode();
+    return signatureCoseSign1;
+}
+
+bool coseCheckEcDsaSignature(const vector<uint8_t>& signatureCoseSign1,
+                             const vector<uint8_t>& detachedContent,
+                             const vector<uint8_t>& publicKey) {
+    auto [item, _, message] = cppbor::parse(signatureCoseSign1);
+    if (item == nullptr) {
+        LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
+        return false;
+    }
+    const cppbor::Array* array = item->asArray();
+    if (array == nullptr) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array";
+        return false;
+    }
+    if (array->size() != 4) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
+        return false;
+    }
+
+    const cppbor::Bstr* encodedProtectedHeadersBstr = (*array)[0]->asBstr();
+    ;
+    if (encodedProtectedHeadersBstr == nullptr) {
+        LOG(ERROR) << "Value for encodedProtectedHeaders is not a bstr";
+        return false;
+    }
+    const vector<uint8_t> encodedProtectedHeaders = encodedProtectedHeadersBstr->value();
+
+    const cppbor::Map* unprotectedHeaders = (*array)[1]->asMap();
+    if (unprotectedHeaders == nullptr) {
+        LOG(ERROR) << "Value for unprotectedHeaders is not a map";
+        return false;
+    }
+
+    vector<uint8_t> data;
+    const cppbor::Simple* payloadAsSimple = (*array)[2]->asSimple();
+    if (payloadAsSimple != nullptr) {
+        if (payloadAsSimple->asNull() == nullptr) {
+            LOG(ERROR) << "Value for payload is not null or a bstr";
+            return false;
+        }
+    } else {
+        const cppbor::Bstr* payloadAsBstr = (*array)[2]->asBstr();
+        if (payloadAsBstr == nullptr) {
+            LOG(ERROR) << "Value for payload is not null or a bstr";
+            return false;
+        }
+        data = payloadAsBstr->value();  // TODO: avoid copy
+    }
+
+    if (data.size() > 0 && detachedContent.size() > 0) {
+        LOG(ERROR) << "data and detachedContent cannot both be non-empty";
+        return false;
+    }
+
+    const cppbor::Bstr* signatureBstr = (*array)[3]->asBstr();
+    if (signatureBstr == nullptr) {
+        LOG(ERROR) << "Value for signature is a bstr";
+        return false;
+    }
+    const vector<uint8_t>& coseSignature = signatureBstr->value();
+
+    vector<uint8_t> derSignature;
+    if (!ecdsaSignatureCoseToDer(coseSignature, derSignature)) {
+        LOG(ERROR) << "Error converting ECDSA signature from COSE to DER format";
+        return false;
+    }
+
+    vector<uint8_t> toBeSigned =
+            coseBuildToBeSigned(encodedProtectedHeaders, data, detachedContent);
+    if (!checkEcDsaSignature(support::sha256(toBeSigned), derSignature, publicKey)) {
+        LOG(ERROR) << "Signature check failed";
+        return false;
+    }
+    return true;
+}
+
+optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1) {
+    auto [item, _, message] = cppbor::parse(signatureCoseSign1);
+    if (item == nullptr) {
+        LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
+        return {};
+    }
+    const cppbor::Array* array = item->asArray();
+    if (array == nullptr) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array";
+        return {};
+    }
+    if (array->size() != 4) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
+        return {};
+    }
+
+    vector<uint8_t> data;
+    const cppbor::Simple* payloadAsSimple = (*array)[2]->asSimple();
+    if (payloadAsSimple != nullptr) {
+        if (payloadAsSimple->asNull() == nullptr) {
+            LOG(ERROR) << "Value for payload is not null or a bstr";
+            return {};
+        }
+        // payload is null, so |data| should be empty (as it is)
+    } else {
+        const cppbor::Bstr* payloadAsBstr = (*array)[2]->asBstr();
+        if (payloadAsBstr == nullptr) {
+            LOG(ERROR) << "Value for payload is not null or a bstr";
+            return {};
+        }
+        // Copy payload into |data|
+        data = payloadAsBstr->value();
+    }
+
+    return data;
+}
+
+optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCoseSign1) {
+    auto [item, _, message] = cppbor::parse(signatureCoseSign1);
+    if (item == nullptr) {
+        LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
+        return {};
+    }
+    const cppbor::Array* array = item->asArray();
+    if (array == nullptr) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array";
+        return {};
+    }
+    if (array->size() != 4) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
+        return {};
+    }
+
+    const cppbor::Map* unprotectedHeaders = (*array)[1]->asMap();
+    if (unprotectedHeaders == nullptr) {
+        LOG(ERROR) << "Value for unprotectedHeaders is not a map";
+        return {};
+    }
+
+    for (size_t n = 0; n < unprotectedHeaders->size(); n++) {
+        auto [keyItem, valueItem] = (*unprotectedHeaders)[n];
+        const cppbor::Int* number = keyItem->asInt();
+        if (number == nullptr) {
+            LOG(ERROR) << "Key item in top-level map is not a number";
+            return {};
+        }
+        int label = number->value();
+        if (label == COSE_LABEL_X5CHAIN) {
+            const cppbor::Bstr* bstr = valueItem->asBstr();
+            if (bstr != nullptr) {
+                return bstr->value();
+            }
+            const cppbor::Array* array = valueItem->asArray();
+            if (array != nullptr) {
+                vector<uint8_t> certs;
+                for (size_t m = 0; m < array->size(); m++) {
+                    const cppbor::Bstr* bstr = ((*array)[m])->asBstr();
+                    if (bstr == nullptr) {
+                        LOG(ERROR) << "Item in x5chain array is not a bstr";
+                        return {};
+                    }
+                    const vector<uint8_t>& certValue = bstr->value();
+                    certs.insert(certs.end(), certValue.begin(), certValue.end());
+                }
+                return certs;
+            }
+            LOG(ERROR) << "Value for x5chain label is not a bstr or array";
+            return {};
+        }
+    }
+    LOG(ERROR) << "Did not find x5chain label in unprotected headers";
+    return {};
+}
+
+vector<uint8_t> coseBuildToBeMACed(const vector<uint8_t>& encodedProtectedHeaders,
+                                   const vector<uint8_t>& data,
+                                   const vector<uint8_t>& detachedContent) {
+    cppbor::Array macStructure;
+    macStructure.add("MAC0");
+    macStructure.add(encodedProtectedHeaders);
+
+    // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
+    // so external_aad is the empty bstr
+    vector<uint8_t> emptyExternalAad;
+    macStructure.add(emptyExternalAad);
+
+    // Next field is the payload, independently of how it's transported (RFC
+    // 8152 section 4.4). Since our API specifies only one of |data| and
+    // |detachedContent| can be non-empty, it's simply just the non-empty one.
+    if (data.size() > 0) {
+        macStructure.add(data);
+    } else {
+        macStructure.add(detachedContent);
+    }
+
+    return macStructure.encode();
+}
+
+optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint8_t>& data,
+                                   const vector<uint8_t>& detachedContent) {
+    cppbor::Map unprotectedHeaders;
+    cppbor::Map protectedHeaders;
+
+    if (data.size() > 0 && detachedContent.size() > 0) {
+        LOG(ERROR) << "data and detachedContent cannot both be non-empty";
+        return {};
+    }
+
+    protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_HMAC_256_256);
+
+    vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
+    vector<uint8_t> toBeMACed = coseBuildToBeMACed(encodedProtectedHeaders, data, detachedContent);
+
+    optional<vector<uint8_t>> mac = hmacSha256(key, toBeMACed);
+    if (!mac) {
+        LOG(ERROR) << "Error MACing toBeMACed data";
+        return {};
+    }
+
+    cppbor::Array array;
+    array.add(encodedProtectedHeaders);
+    array.add(std::move(unprotectedHeaders));
+    if (data.size() == 0) {
+        cppbor::Null nullValue;
+        array.add(std::move(nullValue));
+    } else {
+        array.add(data);
+    }
+    array.add(mac.value());
+    return array.encode();
+}
+
+// ---------------------------------------------------------------------------
+// Platform abstraction.
+// ---------------------------------------------------------------------------
+
+// This is not a very random HBK but that's OK because this is the SW
+// implementation where it can't be kept secret.
+vector<uint8_t> hardwareBoundKey = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+
+const vector<uint8_t>& getHardwareBoundKey() {
+    return hardwareBoundKey;
+}
+
+// ---------------------------------------------------------------------------
+// Utility functions specific to IdentityCredential.
+// ---------------------------------------------------------------------------
+
+Result okResult{ResultCode::OK, ""};
+
+const Result& resultOK() {
+    return okResult;
+}
+
+Result result(ResultCode code, const char* format, ...) {
+    va_list ap;
+    va_start(ap, format);
+    string str;
+    android::base::StringAppendV(&str, format, ap);
+    va_end(ap);
+    return Result{code, str};
+}
+
+vector<vector<uint8_t>> chunkVector(const vector<uint8_t>& content, size_t maxChunkSize) {
+    vector<vector<uint8_t>> ret;
+
+    size_t contentSize = content.size();
+    if (contentSize <= maxChunkSize) {
+        ret.push_back(content);
+        return ret;
+    }
+
+    size_t numChunks = (contentSize + maxChunkSize - 1) / maxChunkSize;
+
+    size_t pos = 0;
+    for (size_t n = 0; n < numChunks; n++) {
+        size_t size = contentSize - pos;
+        if (size > maxChunkSize) {
+            size = maxChunkSize;
+        }
+        auto begin = content.begin() + pos;
+        auto end = content.begin() + pos + size;
+        ret.emplace_back(vector<uint8_t>(begin, end));
+        pos += maxChunkSize;
+    }
+
+    return ret;
+}
+
+vector<uint8_t> secureAccessControlProfileEncodeCbor(const SecureAccessControlProfile& profile) {
+    cppbor::Map map;
+    map.add("id", profile.id);
+
+    if (profile.readerCertificate.size() > 0) {
+        map.add("readerCertificate", cppbor::Bstr(profile.readerCertificate));
+    }
+
+    if (profile.userAuthenticationRequired) {
+        map.add("userAuthenticationRequired", profile.userAuthenticationRequired);
+        map.add("timeoutMillis", profile.timeoutMillis);
+        map.add("secureUserId", profile.secureUserId);
+    }
+
+    return map.encode();
+}
+
+optional<vector<uint8_t>> secureAccessControlProfileCalcMac(
+        const SecureAccessControlProfile& profile, const vector<uint8_t>& storageKey) {
+    vector<uint8_t> cborData = secureAccessControlProfileEncodeCbor(profile);
+
+    optional<vector<uint8_t>> nonce = getRandom(12);
+    if (!nonce) {
+        return {};
+    }
+    optional<vector<uint8_t>> macO = encryptAes128Gcm(storageKey, nonce.value(), {}, cborData);
+    if (!macO) {
+        return {};
+    }
+    return macO.value();
+}
+
+bool secureAccessControlProfileCheckMac(const SecureAccessControlProfile& profile,
+                                        const vector<uint8_t>& storageKey) {
+    vector<uint8_t> cborData = secureAccessControlProfileEncodeCbor(profile);
+
+    if (profile.mac.size() < kAesGcmIvSize) {
+        return false;
+    }
+    vector<uint8_t> nonce =
+            vector<uint8_t>(profile.mac.begin(), profile.mac.begin() + kAesGcmIvSize);
+    optional<vector<uint8_t>> mac = encryptAes128Gcm(storageKey, nonce, {}, cborData);
+    if (!mac) {
+        return false;
+    }
+    if (mac.value() != vector<uint8_t>(profile.mac)) {
+        return false;
+    }
+    return true;
+}
+
+vector<uint8_t> testHardwareBoundKey = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+const vector<uint8_t>& getTestHardwareBoundKey() {
+    return testHardwareBoundKey;
+}
+
+vector<uint8_t> entryCreateAdditionalData(const string& nameSpace, const string& name,
+                                          const vector<uint16_t> accessControlProfileIds) {
+    cppbor::Map map;
+    map.add("Namespace", nameSpace);
+    map.add("Name", name);
+
+    cppbor::Array acpIds;
+    for (auto id : accessControlProfileIds) {
+        acpIds.add(id);
+    }
+    map.add("AccessControlProfileIds", std::move(acpIds));
+    return map.encode();
+}
+
+}  // namespace support
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
diff --git a/identity/support/src/cppbor.cpp b/identity/support/src/cppbor.cpp
new file mode 100644
index 0000000..d289985
--- /dev/null
+++ b/identity/support/src/cppbor.cpp
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#include "cppbor.h"
+#include "cppbor_parse.h"
+
+#define LOG_TAG "CppBor"
+#include <android-base/logging.h>
+
+namespace cppbor {
+
+namespace {
+
+template <typename T, typename Iterator, typename = std::enable_if<std::is_unsigned<T>::value>>
+Iterator writeBigEndian(T value, Iterator pos) {
+    for (unsigned i = 0; i < sizeof(value); ++i) {
+        *pos++ = static_cast<uint8_t>(value >> (8 * (sizeof(value) - 1)));
+        value = static_cast<T>(value << 8);
+    }
+    return pos;
+}
+
+template <typename T, typename = std::enable_if<std::is_unsigned<T>::value>>
+void writeBigEndian(T value, std::function<void(uint8_t)>& cb) {
+    for (unsigned i = 0; i < sizeof(value); ++i) {
+        cb(static_cast<uint8_t>(value >> (8 * (sizeof(value) - 1))));
+        value = static_cast<T>(value << 8);
+    }
+}
+
+}  // namespace
+
+size_t headerSize(uint64_t addlInfo) {
+    if (addlInfo < ONE_BYTE_LENGTH) return 1;
+    if (addlInfo <= std::numeric_limits<uint8_t>::max()) return 2;
+    if (addlInfo <= std::numeric_limits<uint16_t>::max()) return 3;
+    if (addlInfo <= std::numeric_limits<uint32_t>::max()) return 5;
+    return 9;
+}
+
+uint8_t* encodeHeader(MajorType type, uint64_t addlInfo, uint8_t* pos, const uint8_t* end) {
+    size_t sz = headerSize(addlInfo);
+    if (end - pos < static_cast<ssize_t>(sz)) return nullptr;
+    switch (sz) {
+        case 1:
+            *pos++ = type | static_cast<uint8_t>(addlInfo);
+            return pos;
+        case 2:
+            *pos++ = type | ONE_BYTE_LENGTH;
+            *pos++ = static_cast<uint8_t>(addlInfo);
+            return pos;
+        case 3:
+            *pos++ = type | TWO_BYTE_LENGTH;
+            return writeBigEndian(static_cast<uint16_t>(addlInfo), pos);
+        case 5:
+            *pos++ = type | FOUR_BYTE_LENGTH;
+            return writeBigEndian(static_cast<uint32_t>(addlInfo), pos);
+        case 9:
+            *pos++ = type | EIGHT_BYTE_LENGTH;
+            return writeBigEndian(addlInfo, pos);
+        default:
+            CHECK(false);  // Impossible to get here.
+            return nullptr;
+    }
+}
+
+void encodeHeader(MajorType type, uint64_t addlInfo, EncodeCallback encodeCallback) {
+    size_t sz = headerSize(addlInfo);
+    switch (sz) {
+        case 1:
+            encodeCallback(type | static_cast<uint8_t>(addlInfo));
+            break;
+        case 2:
+            encodeCallback(type | ONE_BYTE_LENGTH);
+            encodeCallback(static_cast<uint8_t>(addlInfo));
+            break;
+        case 3:
+            encodeCallback(type | TWO_BYTE_LENGTH);
+            writeBigEndian(static_cast<uint16_t>(addlInfo), encodeCallback);
+            break;
+        case 5:
+            encodeCallback(type | FOUR_BYTE_LENGTH);
+            writeBigEndian(static_cast<uint32_t>(addlInfo), encodeCallback);
+            break;
+        case 9:
+            encodeCallback(type | EIGHT_BYTE_LENGTH);
+            writeBigEndian(addlInfo, encodeCallback);
+            break;
+        default:
+            CHECK(false);  // Impossible to get here.
+    }
+}
+
+bool Item::operator==(const Item& other) const& {
+    if (type() != other.type()) return false;
+    switch (type()) {
+        case UINT:
+            return *asUint() == *(other.asUint());
+        case NINT:
+            return *asNint() == *(other.asNint());
+        case BSTR:
+            return *asBstr() == *(other.asBstr());
+        case TSTR:
+            return *asTstr() == *(other.asTstr());
+        case ARRAY:
+            return *asArray() == *(other.asArray());
+        case MAP:
+            return *asMap() == *(other.asMap());
+        case SIMPLE:
+            return *asSimple() == *(other.asSimple());
+        case SEMANTIC:
+            return *asSemantic() == *(other.asSemantic());
+        default:
+            CHECK(false);  // Impossible to get here.
+            return false;
+    }
+}
+
+Nint::Nint(int64_t v) : mValue(v) {
+    CHECK(v < 0) << "Only negative values allowed";
+}
+
+bool Simple::operator==(const Simple& other) const& {
+    if (simpleType() != other.simpleType()) return false;
+
+    switch (simpleType()) {
+        case BOOLEAN:
+            return *asBool() == *(other.asBool());
+        case NULL_T:
+            return true;
+        default:
+            CHECK(false);  // Impossible to get here.
+            return false;
+    }
+}
+
+uint8_t* Bstr::encode(uint8_t* pos, const uint8_t* end) const {
+    pos = encodeHeader(mValue.size(), pos, end);
+    if (!pos || end - pos < static_cast<ptrdiff_t>(mValue.size())) return nullptr;
+    return std::copy(mValue.begin(), mValue.end(), pos);
+}
+
+void Bstr::encodeValue(EncodeCallback encodeCallback) const {
+    for (auto c : mValue) {
+        encodeCallback(c);
+    }
+}
+
+uint8_t* Tstr::encode(uint8_t* pos, const uint8_t* end) const {
+    pos = encodeHeader(mValue.size(), pos, end);
+    if (!pos || end - pos < static_cast<ptrdiff_t>(mValue.size())) return nullptr;
+    return std::copy(mValue.begin(), mValue.end(), pos);
+}
+
+void Tstr::encodeValue(EncodeCallback encodeCallback) const {
+    for (auto c : mValue) {
+        encodeCallback(static_cast<uint8_t>(c));
+    }
+}
+
+bool CompoundItem::operator==(const CompoundItem& other) const& {
+    return type() == other.type()             //
+           && addlInfo() == other.addlInfo()  //
+           // Can't use vector::operator== because the contents are pointers.  std::equal lets us
+           // provide a predicate that does the dereferencing.
+           && std::equal(mEntries.begin(), mEntries.end(), other.mEntries.begin(),
+                         [](auto& a, auto& b) -> bool { return *a == *b; });
+}
+
+uint8_t* CompoundItem::encode(uint8_t* pos, const uint8_t* end) const {
+    pos = encodeHeader(addlInfo(), pos, end);
+    if (!pos) return nullptr;
+    for (auto& entry : mEntries) {
+        pos = entry->encode(pos, end);
+        if (!pos) return nullptr;
+    }
+    return pos;
+}
+
+void CompoundItem::encode(EncodeCallback encodeCallback) const {
+    encodeHeader(addlInfo(), encodeCallback);
+    for (auto& entry : mEntries) {
+        entry->encode(encodeCallback);
+    }
+}
+
+void Map::assertInvariant() const {
+    CHECK(mEntries.size() % 2 == 0);
+}
+
+std::unique_ptr<Item> Map::clone() const {
+    assertInvariant();
+    auto res = std::make_unique<Map>();
+    for (size_t i = 0; i < mEntries.size(); i += 2) {
+        res->add(mEntries[i]->clone(), mEntries[i + 1]->clone());
+    }
+    return res;
+}
+
+std::unique_ptr<Item> Array::clone() const {
+    auto res = std::make_unique<Array>();
+    for (size_t i = 0; i < mEntries.size(); i++) {
+        res->add(mEntries[i]->clone());
+    }
+    return res;
+}
+
+void Semantic::assertInvariant() const {
+    CHECK(mEntries.size() == 1);
+}
+
+}  // namespace cppbor
diff --git a/identity/support/src/cppbor_parse.cpp b/identity/support/src/cppbor_parse.cpp
new file mode 100644
index 0000000..c9ebb8a
--- /dev/null
+++ b/identity/support/src/cppbor_parse.cpp
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#include "cppbor_parse.h"
+
+#include <sstream>
+#include <stack>
+
+#define LOG_TAG "CppBor"
+#include <android-base/logging.h>
+
+namespace cppbor {
+
+namespace {
+
+std::string insufficientLengthString(size_t bytesNeeded, size_t bytesAvail,
+                                     const std::string& type) {
+    std::stringstream errStream;
+    errStream << "Need " << bytesNeeded << " byte(s) for " << type << ", have " << bytesAvail
+              << ".";
+    return errStream.str();
+}
+
+template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
+std::tuple<bool, uint64_t, const uint8_t*> parseLength(const uint8_t* pos, const uint8_t* end,
+                                                       ParseClient* parseClient) {
+    if (pos + sizeof(T) > end) {
+        parseClient->error(pos - 1, insufficientLengthString(sizeof(T), end - pos, "length field"));
+        return {false, 0, pos};
+    }
+
+    const uint8_t* intEnd = pos + sizeof(T);
+    T result = 0;
+    do {
+        result = static_cast<T>((result << 8) | *pos++);
+    } while (pos < intEnd);
+    return {true, result, pos};
+}
+
+std::tuple<const uint8_t*, ParseClient*> parseRecursively(const uint8_t* begin, const uint8_t* end,
+                                                          ParseClient* parseClient);
+
+std::tuple<const uint8_t*, ParseClient*> handleUint(uint64_t value, const uint8_t* hdrBegin,
+                                                    const uint8_t* hdrEnd,
+                                                    ParseClient* parseClient) {
+    std::unique_ptr<Item> item = std::make_unique<Uint>(value);
+    return {hdrEnd,
+            parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
+}
+
+std::tuple<const uint8_t*, ParseClient*> handleNint(uint64_t value, const uint8_t* hdrBegin,
+                                                    const uint8_t* hdrEnd,
+                                                    ParseClient* parseClient) {
+    if (value > std::numeric_limits<int64_t>::max()) {
+        parseClient->error(hdrBegin, "NINT values that don't fit in int64_t are not supported.");
+        return {hdrBegin, nullptr /* end parsing */};
+    }
+    std::unique_ptr<Item> item = std::make_unique<Nint>(-1 - static_cast<uint64_t>(value));
+    return {hdrEnd,
+            parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
+}
+
+std::tuple<const uint8_t*, ParseClient*> handleBool(uint64_t value, const uint8_t* hdrBegin,
+                                                    const uint8_t* hdrEnd,
+                                                    ParseClient* parseClient) {
+    std::unique_ptr<Item> item = std::make_unique<Bool>(value == TRUE);
+    return {hdrEnd,
+            parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
+}
+
+std::tuple<const uint8_t*, ParseClient*> handleNull(const uint8_t* hdrBegin, const uint8_t* hdrEnd,
+                                                    ParseClient* parseClient) {
+    std::unique_ptr<Item> item = std::make_unique<Null>();
+    return {hdrEnd,
+            parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
+}
+
+template <typename T>
+std::tuple<const uint8_t*, ParseClient*> handleString(uint64_t length, const uint8_t* hdrBegin,
+                                                      const uint8_t* valueBegin, const uint8_t* end,
+                                                      const std::string& errLabel,
+                                                      ParseClient* parseClient) {
+    if (end - valueBegin < static_cast<ssize_t>(length)) {
+        parseClient->error(hdrBegin, insufficientLengthString(length, end - valueBegin, errLabel));
+        return {hdrBegin, nullptr /* end parsing */};
+    }
+
+    std::unique_ptr<Item> item = std::make_unique<T>(valueBegin, valueBegin + length);
+    return {valueBegin + length,
+            parseClient->item(item, hdrBegin, valueBegin, valueBegin + length)};
+}
+
+class IncompleteItem {
+  public:
+    virtual ~IncompleteItem() {}
+    virtual void add(std::unique_ptr<Item> item) = 0;
+};
+
+class IncompleteArray : public Array, public IncompleteItem {
+  public:
+    IncompleteArray(size_t size) : mSize(size) {}
+
+    // We return the "complete" size, rather than the actual size.
+    size_t size() const override { return mSize; }
+
+    void add(std::unique_ptr<Item> item) override {
+        mEntries.reserve(mSize);
+        mEntries.push_back(std::move(item));
+    }
+
+  private:
+    size_t mSize;
+};
+
+class IncompleteMap : public Map, public IncompleteItem {
+  public:
+    IncompleteMap(size_t size) : mSize(size) {}
+
+    // We return the "complete" size, rather than the actual size.
+    size_t size() const override { return mSize; }
+
+    void add(std::unique_ptr<Item> item) override {
+        mEntries.reserve(mSize * 2);
+        mEntries.push_back(std::move(item));
+    }
+
+  private:
+    size_t mSize;
+};
+
+class IncompleteSemantic : public Semantic, public IncompleteItem {
+  public:
+    IncompleteSemantic(uint64_t value) : Semantic(value) {}
+
+    // We return the "complete" size, rather than the actual size.
+    size_t size() const override { return 1; }
+
+    void add(std::unique_ptr<Item> item) override {
+        mEntries.reserve(1);
+        mEntries.push_back(std::move(item));
+    }
+};
+
+std::tuple<const uint8_t*, ParseClient*> handleEntries(size_t entryCount, const uint8_t* hdrBegin,
+                                                       const uint8_t* pos, const uint8_t* end,
+                                                       const std::string& typeName,
+                                                       ParseClient* parseClient) {
+    while (entryCount > 0) {
+        --entryCount;
+        if (pos == end) {
+            parseClient->error(hdrBegin, "Not enough entries for " + typeName + ".");
+            return {hdrBegin, nullptr /* end parsing */};
+        }
+        std::tie(pos, parseClient) = parseRecursively(pos, end, parseClient);
+        if (!parseClient) return {hdrBegin, nullptr};
+    }
+    return {pos, parseClient};
+}
+
+std::tuple<const uint8_t*, ParseClient*> handleCompound(
+        std::unique_ptr<Item> item, uint64_t entryCount, const uint8_t* hdrBegin,
+        const uint8_t* valueBegin, const uint8_t* end, const std::string& typeName,
+        ParseClient* parseClient) {
+    parseClient =
+            parseClient->item(item, hdrBegin, valueBegin, valueBegin /* don't know the end yet */);
+    if (!parseClient) return {hdrBegin, nullptr};
+
+    const uint8_t* pos;
+    std::tie(pos, parseClient) =
+            handleEntries(entryCount, hdrBegin, valueBegin, end, typeName, parseClient);
+    if (!parseClient) return {hdrBegin, nullptr};
+
+    return {pos, parseClient->itemEnd(item, hdrBegin, valueBegin, pos)};
+}
+
+std::tuple<const uint8_t*, ParseClient*> parseRecursively(const uint8_t* begin, const uint8_t* end,
+                                                          ParseClient* parseClient) {
+    const uint8_t* pos = begin;
+
+    MajorType type = static_cast<MajorType>(*pos & 0xE0);
+    uint8_t tagInt = *pos & 0x1F;
+    ++pos;
+
+    bool success = true;
+    uint64_t addlData;
+    if (tagInt < ONE_BYTE_LENGTH || tagInt > EIGHT_BYTE_LENGTH) {
+        addlData = tagInt;
+    } else {
+        switch (tagInt) {
+            case ONE_BYTE_LENGTH:
+                std::tie(success, addlData, pos) = parseLength<uint8_t>(pos, end, parseClient);
+                break;
+
+            case TWO_BYTE_LENGTH:
+                std::tie(success, addlData, pos) = parseLength<uint16_t>(pos, end, parseClient);
+                break;
+
+            case FOUR_BYTE_LENGTH:
+                std::tie(success, addlData, pos) = parseLength<uint32_t>(pos, end, parseClient);
+                break;
+
+            case EIGHT_BYTE_LENGTH:
+                std::tie(success, addlData, pos) = parseLength<uint64_t>(pos, end, parseClient);
+                break;
+
+            default:
+                CHECK(false);  //  It's impossible to get here
+                break;
+        }
+    }
+
+    if (!success) return {begin, nullptr};
+
+    switch (type) {
+        case UINT:
+            return handleUint(addlData, begin, pos, parseClient);
+
+        case NINT:
+            return handleNint(addlData, begin, pos, parseClient);
+
+        case BSTR:
+            return handleString<Bstr>(addlData, begin, pos, end, "byte string", parseClient);
+
+        case TSTR:
+            return handleString<Tstr>(addlData, begin, pos, end, "text string", parseClient);
+
+        case ARRAY:
+            return handleCompound(std::make_unique<IncompleteArray>(addlData), addlData, begin, pos,
+                                  end, "array", parseClient);
+
+        case MAP:
+            return handleCompound(std::make_unique<IncompleteMap>(addlData), addlData * 2, begin,
+                                  pos, end, "map", parseClient);
+
+        case SEMANTIC:
+            return handleCompound(std::make_unique<IncompleteSemantic>(addlData), 1, begin, pos,
+                                  end, "semantic", parseClient);
+
+        case SIMPLE:
+            switch (addlData) {
+                case TRUE:
+                case FALSE:
+                    return handleBool(addlData, begin, pos, parseClient);
+                case NULL_V:
+                    return handleNull(begin, pos, parseClient);
+            }
+    }
+    CHECK(false);  // Impossible to get here.
+    return {};
+}
+
+class FullParseClient : public ParseClient {
+  public:
+    virtual ParseClient* item(std::unique_ptr<Item>& item, const uint8_t*, const uint8_t*,
+                              const uint8_t* end) override {
+        if (mParentStack.empty() && !item->isCompound()) {
+            // This is the first and only item.
+            mTheItem = std::move(item);
+            mPosition = end;
+            return nullptr;  //  We're done.
+        }
+
+        if (item->isCompound()) {
+            // Starting a new compound data item, i.e. a new parent.  Save it on the parent stack.
+            // It's safe to save a raw pointer because the unique_ptr is guaranteed to stay in
+            // existence until the corresponding itemEnd() call.
+            assert(dynamic_cast<CompoundItem*>(item.get()));
+            mParentStack.push(static_cast<CompoundItem*>(item.get()));
+            return this;
+        } else {
+            appendToLastParent(std::move(item));
+            return this;
+        }
+    }
+
+    virtual ParseClient* itemEnd(std::unique_ptr<Item>& item, const uint8_t*, const uint8_t*,
+                                 const uint8_t* end) override {
+        CHECK(item->isCompound() && item.get() == mParentStack.top());
+        mParentStack.pop();
+
+        if (mParentStack.empty()) {
+            mTheItem = std::move(item);
+            mPosition = end;
+            return nullptr;  // We're done
+        } else {
+            appendToLastParent(std::move(item));
+            return this;
+        }
+    }
+
+    virtual void error(const uint8_t* position, const std::string& errorMessage) override {
+        mPosition = position;
+        mErrorMessage = errorMessage;
+    }
+
+    std::tuple<std::unique_ptr<Item> /* result */, const uint8_t* /* newPos */,
+               std::string /* errMsg */>
+    parseResult() {
+        std::unique_ptr<Item> p = std::move(mTheItem);
+        return {std::move(p), mPosition, std::move(mErrorMessage)};
+    }
+
+  private:
+    void appendToLastParent(std::unique_ptr<Item> item) {
+        auto parent = mParentStack.top();
+        assert(dynamic_cast<IncompleteItem*>(parent));
+        if (parent->type() == ARRAY) {
+            static_cast<IncompleteArray*>(parent)->add(std::move(item));
+        } else if (parent->type() == MAP) {
+            static_cast<IncompleteMap*>(parent)->add(std::move(item));
+        } else if (parent->type() == SEMANTIC) {
+            static_cast<IncompleteSemantic*>(parent)->add(std::move(item));
+        } else {
+            CHECK(false);  // Impossible to get here.
+        }
+    }
+
+    std::unique_ptr<Item> mTheItem;
+    std::stack<CompoundItem*> mParentStack;
+    const uint8_t* mPosition = nullptr;
+    std::string mErrorMessage;
+};
+
+}  // anonymous namespace
+
+void parse(const uint8_t* begin, const uint8_t* end, ParseClient* parseClient) {
+    parseRecursively(begin, end, parseClient);
+}
+
+std::tuple<std::unique_ptr<Item> /* result */, const uint8_t* /* newPos */,
+           std::string /* errMsg */>
+parse(const uint8_t* begin, const uint8_t* end) {
+    FullParseClient parseClient;
+    parse(begin, end, &parseClient);
+    return parseClient.parseResult();
+}
+
+}  // namespace cppbor
diff --git a/identity/support/tests/IdentityCredentialSupportTest.cpp b/identity/support/tests/IdentityCredentialSupportTest.cpp
new file mode 100644
index 0000000..c356549
--- /dev/null
+++ b/identity/support/tests/IdentityCredentialSupportTest.cpp
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+using std::optional;
+using std::string;
+using std::vector;
+
+namespace android {
+namespace hardware {
+namespace identity {
+
+TEST(IdentityCredentialSupport, encodeHex) {
+    EXPECT_EQ("", support::encodeHex(vector<uint8_t>({})));
+    EXPECT_EQ("01", support::encodeHex(vector<uint8_t>({1})));
+    EXPECT_EQ("000102030405060708090a0b0c0d0e0f10",
+              support::encodeHex(
+                      vector<uint8_t>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})));
+    EXPECT_EQ("0102ffe060", support::encodeHex(vector<uint8_t>({1, 2, 255, 224, 96})));
+}
+
+TEST(IdentityCredentialSupport, decodeHex) {
+    EXPECT_EQ(vector<uint8_t>({}), support::decodeHex(""));
+    EXPECT_EQ(vector<uint8_t>({1}), support::decodeHex("01"));
+
+    EXPECT_EQ(vector<uint8_t>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}),
+              support::decodeHex("000102030405060708090a0b0c0d0e0f10"));
+
+    EXPECT_FALSE(support::decodeHex("0g"));
+    EXPECT_FALSE(support::decodeHex("0"));
+    EXPECT_FALSE(support::decodeHex("012"));
+}
+
+TEST(IdentityCredentialSupport, CborPrettyPrint) {
+    EXPECT_EQ("'Some text'", support::cborPrettyPrint(cppbor::Tstr("Some text").encode()));
+
+    EXPECT_EQ("''", support::cborPrettyPrint(cppbor::Tstr("").encode()));
+
+    EXPECT_EQ("{0x01, 0x00, 0x02, 0xf0, 0xff, 0x40}",
+              support::cborPrettyPrint(
+                      cppbor::Bstr(vector<uint8_t>({1, 0, 2, 240, 255, 64})).encode()));
+
+    EXPECT_EQ("{}", support::cborPrettyPrint(cppbor::Bstr(vector<uint8_t>()).encode()));
+
+    EXPECT_EQ("true", support::cborPrettyPrint(cppbor::Bool(true).encode()));
+
+    EXPECT_EQ("false", support::cborPrettyPrint(cppbor::Bool(false).encode()));
+
+    EXPECT_EQ("42", support::cborPrettyPrint(cppbor::Uint(42).encode()));
+
+    EXPECT_EQ("9223372036854775807",  // 0x7fff ffff ffff ffff
+              support::cborPrettyPrint(cppbor::Uint(std::numeric_limits<int64_t>::max()).encode()));
+
+    EXPECT_EQ("-42", support::cborPrettyPrint(cppbor::Nint(-42).encode()));
+
+    EXPECT_EQ("-9223372036854775808",  // -0x8000 0000 0000 0000
+              support::cborPrettyPrint(cppbor::Nint(std::numeric_limits<int64_t>::min()).encode()));
+}
+
+TEST(IdentityCredentialSupport, CborPrettyPrintCompound) {
+    cppbor::Array array = cppbor::Array("foo", "bar", "baz");
+    EXPECT_EQ("['foo', 'bar', 'baz', ]", support::cborPrettyPrint(array.encode()));
+
+    cppbor::Map map = cppbor::Map().add("foo", 42).add("bar", 43).add("baz", 44);
+    EXPECT_EQ(
+            "{\n"
+            "  'foo' : 42,\n"
+            "  'bar' : 43,\n"
+            "  'baz' : 44,\n"
+            "}",
+            support::cborPrettyPrint(map.encode()));
+
+    cppbor::Array array2 = cppbor::Array(cppbor::Tstr("Some text"), cppbor::Nint(-42));
+    EXPECT_EQ("['Some text', -42, ]", support::cborPrettyPrint(array2.encode()));
+
+    cppbor::Map map2 = cppbor::Map().add(42, "foo").add(43, "bar").add(44, "baz");
+    EXPECT_EQ(
+            "{\n"
+            "  42 : 'foo',\n"
+            "  43 : 'bar',\n"
+            "  44 : 'baz',\n"
+            "}",
+            support::cborPrettyPrint(map2.encode()));
+
+    cppbor::Array deeplyNestedArrays =
+            cppbor::Array(cppbor::Array(cppbor::Array("a", "b", "c")),
+                          cppbor::Array(cppbor::Array("d", "e", cppbor::Array("f", "g"))));
+    EXPECT_EQ(
+            "[\n"
+            "  ['a', 'b', 'c', ],\n"
+            "  [\n    'd',\n"
+            "    'e',\n"
+            "    ['f', 'g', ],\n"
+            "  ],\n"
+            "]",
+            support::cborPrettyPrint(deeplyNestedArrays.encode()));
+
+    EXPECT_EQ(
+            "[\n"
+            "  {0x0a, 0x0b},\n"
+            "  'foo',\n"
+            "  42,\n"
+            "  ['foo', 'bar', 'baz', ],\n"
+            "  {\n"
+            "    'foo' : 42,\n"
+            "    'bar' : 43,\n"
+            "    'baz' : 44,\n"
+            "  },\n"
+            "  {\n"
+            "    'deep1' : ['Some text', -42, ],\n"
+            "    'deep2' : {\n"
+            "      42 : 'foo',\n"
+            "      43 : 'bar',\n"
+            "      44 : 'baz',\n"
+            "    },\n"
+            "  },\n"
+            "]",
+            support::cborPrettyPrint(cppbor::Array(cppbor::Bstr(vector<uint8_t>{10, 11}),
+                                                   cppbor::Tstr("foo"), cppbor::Uint(42),
+                                                   std::move(array), std::move(map),
+                                                   (cppbor::Map()
+                                                            .add("deep1", std::move(array2))
+                                                            .add("deep2", std::move(map2))))
+                                             .encode()));
+}
+
+TEST(IdentityCredentialSupport, Signatures) {
+    vector<uint8_t> data = {1, 2, 3};
+
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    ASSERT_TRUE(keyPair);
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(privKey);
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(pubKey);
+
+    optional<vector<uint8_t>> signature = support::signEcDsa(privKey.value(), data);
+    ASSERT_TRUE(
+            support::checkEcDsaSignature(support::sha256(data), signature.value(), pubKey.value()));
+
+    // Manipulate the signature, check that verification fails.
+    vector<uint8_t> modifiedSignature = signature.value();
+    modifiedSignature[0] ^= 0xff;
+    ASSERT_FALSE(
+            support::checkEcDsaSignature(support::sha256(data), modifiedSignature, pubKey.value()));
+
+    // Manipulate the data being checked, check that verification fails.
+    vector<uint8_t> modifiedDigest = support::sha256(data);
+    modifiedDigest[0] ^= 0xff;
+    ASSERT_FALSE(support::checkEcDsaSignature(modifiedDigest, signature.value(), pubKey.value()));
+}
+
+string replaceLine(const string& str, ssize_t lineNumber, const string& replacement) {
+    vector<string> lines;
+    std::istringstream f(str);
+    string s;
+    while (std::getline(f, s, '\n')) {
+        lines.push_back(s);
+    }
+
+    size_t numLines = lines.size();
+    if (lineNumber < 0) {
+        lineNumber = numLines - (-lineNumber);
+    }
+
+    string ret;
+    size_t n = 0;
+    for (const string& line : lines) {
+        if (n == lineNumber) {
+            ret += replacement + "\n";
+        } else {
+            ret += line + "\n";
+        }
+        n++;
+    }
+    return ret;
+}
+
+TEST(IdentityCredentialSupport, CoseSignatures) {
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    ASSERT_TRUE(keyPair);
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(privKey);
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(pubKey);
+
+    vector<uint8_t> data = {1, 2, 3};
+    optional<vector<uint8_t>> coseSign1 = support::coseSignEcDsa(
+            privKey.value(), data, {} /* detachedContent */, {} /* x5chain */);
+    ASSERT_TRUE(support::coseCheckEcDsaSignature(coseSign1.value(), {} /* detachedContent */,
+                                                 pubKey.value()));
+
+    optional<vector<uint8_t>> payload = support::coseSignGetPayload(coseSign1.value());
+    ASSERT_TRUE(payload);
+    ASSERT_EQ(data, payload.value());
+
+    // Finally, check that |coseSign1| are the bytes of a valid COSE_Sign1 message
+    string out = support::cborPrettyPrint(coseSign1.value());
+    out = replaceLine(out, -2, "  [] // Signature Removed");
+    EXPECT_EQ(
+            "[\n"
+            "  {0xa1, 0x01, 0x26},\n"  // Bytes of {1:-7} 1 is 'alg' label and -7 is "ECDSA 256"
+            "  {},\n"
+            "  {0x01, 0x02, 0x03},\n"
+            "  [] // Signature Removed\n"
+            "]\n",
+            out);
+}
+
+TEST(IdentityCredentialSupport, CoseSignaturesAdditionalData) {
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    ASSERT_TRUE(keyPair);
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(privKey);
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(pubKey);
+
+    vector<uint8_t> detachedContent = {1, 2, 3};
+    optional<vector<uint8_t>> coseSign1 = support::coseSignEcDsa(privKey.value(), {} /* data */,
+                                                                 detachedContent, {} /* x5chain */);
+    ASSERT_TRUE(
+            support::coseCheckEcDsaSignature(coseSign1.value(), detachedContent, pubKey.value()));
+
+    optional<vector<uint8_t>> payload = support::coseSignGetPayload(coseSign1.value());
+    ASSERT_TRUE(payload);
+    ASSERT_EQ(0, payload.value().size());
+
+    // Finally, check that |coseSign1| are the bytes of a valid COSE_Sign1 message
+    string out = support::cborPrettyPrint(coseSign1.value());
+    out = replaceLine(out, -2, "  [] // Signature Removed");
+    EXPECT_EQ(
+            "[\n"
+            "  {0xa1, 0x01, 0x26},\n"  // Bytes of {1:-7} 1 is 'alg' label and -7 is "ECDSA 256"
+            "  {},\n"
+            "  null,\n"
+            "  [] // Signature Removed\n"
+            "]\n",
+            out);
+}
+
+vector<uint8_t> generateCertChain(size_t numCerts) {
+    vector<vector<uint8_t>> certs;
+
+    for (size_t n = 0; n < numCerts; n++) {
+        optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+        optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+        optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+
+        optional<vector<uint8_t>> cert = support::ecPublicKeyGenerateCertificate(
+                pubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0);
+        certs.push_back(cert.value());
+    }
+    return support::certificateChainJoin(certs);
+}
+
+TEST(IdentityCredentialSupport, CoseSignaturesX5ChainWithSingleCert) {
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    ASSERT_TRUE(keyPair);
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(privKey);
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(pubKey);
+
+    vector<uint8_t> certChain = generateCertChain(1);
+    optional<vector<vector<uint8_t>>> splitCerts = support::certificateChainSplit(certChain);
+    ASSERT_EQ(1, splitCerts.value().size());
+
+    vector<uint8_t> detachedContent = {1, 2, 3};
+    optional<vector<uint8_t>> coseSign1 =
+            support::coseSignEcDsa(privKey.value(), {} /* data */, detachedContent, certChain);
+    ASSERT_TRUE(
+            support::coseCheckEcDsaSignature(coseSign1.value(), detachedContent, pubKey.value()));
+
+    optional<vector<uint8_t>> payload = support::coseSignGetPayload(coseSign1.value());
+    ASSERT_TRUE(payload);
+    ASSERT_EQ(0, payload.value().size());
+
+    optional<vector<uint8_t>> certsRecovered = support::coseSignGetX5Chain(coseSign1.value());
+    EXPECT_EQ(certsRecovered.value(), certChain);
+}
+
+TEST(IdentityCredentialSupport, CoseSignaturesX5ChainWithMultipleCerts) {
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    ASSERT_TRUE(keyPair);
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(privKey);
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(pubKey);
+
+    vector<uint8_t> certChain = generateCertChain(5);
+    optional<vector<vector<uint8_t>>> splitCerts = support::certificateChainSplit(certChain);
+    ASSERT_EQ(5, splitCerts.value().size());
+
+    vector<uint8_t> detachedContent = {1, 2, 3};
+    optional<vector<uint8_t>> coseSign1 =
+            support::coseSignEcDsa(privKey.value(), {} /* data */, detachedContent, certChain);
+    ASSERT_TRUE(
+            support::coseCheckEcDsaSignature(coseSign1.value(), detachedContent, pubKey.value()));
+
+    optional<vector<uint8_t>> payload = support::coseSignGetPayload(coseSign1.value());
+    ASSERT_TRUE(payload);
+    ASSERT_EQ(0, payload.value().size());
+
+    optional<vector<uint8_t>> certsRecovered = support::coseSignGetX5Chain(coseSign1.value());
+    EXPECT_EQ(certsRecovered.value(), certChain);
+}
+
+TEST(IdentityCredentialSupport, CertificateChain) {
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    ASSERT_TRUE(keyPair);
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(privKey);
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(pubKey);
+
+    optional<vector<uint8_t>> cert = support::ecPublicKeyGenerateCertificate(
+            pubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0);
+
+    optional<vector<uint8_t>> extractedPubKey =
+            support::certificateChainGetTopMostKey(cert.value());
+    ASSERT_TRUE(extractedPubKey);
+    ASSERT_EQ(pubKey.value(), extractedPubKey.value());
+
+    // We expect to the chain returned by ecPublicKeyGenerateCertificate() to only have a
+    // single element
+    optional<vector<vector<uint8_t>>> splitCerts = support::certificateChainSplit(cert.value());
+    ASSERT_EQ(1, splitCerts.value().size());
+    ASSERT_EQ(splitCerts.value()[0], cert.value());
+
+    optional<vector<uint8_t>> otherKeyPair = support::createEcKeyPair();
+    ASSERT_TRUE(otherKeyPair);
+    optional<vector<uint8_t>> otherPrivKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(otherPrivKey);
+    optional<vector<uint8_t>> otherPubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(otherPubKey);
+    optional<vector<uint8_t>> otherCert = support::ecPublicKeyGenerateCertificate(
+            otherPubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0);
+
+    // Now both cert and otherCert are two distinct certificates. Let's make a
+    // chain and check that certificateChainSplit() works as expected.
+    ASSERT_NE(cert.value(), otherCert.value());
+    const vector<vector<uint8_t>> certs2 = {cert.value(), otherCert.value()};
+    vector<uint8_t> certs2combined = support::certificateChainJoin(certs2);
+    ASSERT_EQ(certs2combined.size(), cert.value().size() + otherCert.value().size());
+    optional<vector<vector<uint8_t>>> splitCerts2 = support::certificateChainSplit(certs2combined);
+    ASSERT_EQ(certs2, splitCerts2.value());
+}
+
+vector<uint8_t> strToVec(const string& str) {
+    vector<uint8_t> ret;
+    size_t size = str.size();
+    ret.resize(size);
+    memcpy(ret.data(), str.data(), size);
+    return ret;
+}
+
+// Test vector from https://en.wikipedia.org/wiki/HMAC
+TEST(IdentityCredentialSupport, hmacSha256) {
+    vector<uint8_t> key = strToVec("key");
+    vector<uint8_t> data = strToVec("The quick brown fox jumps over the lazy dog");
+
+    vector<uint8_t> expected =
+            support::decodeHex("f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8")
+                    .value();
+
+    optional<vector<uint8_t>> hmac = support::hmacSha256(key, data);
+    ASSERT_TRUE(hmac);
+    ASSERT_EQ(expected, hmac.value());
+}
+
+// See also CoseMac0 test in UtilUnitTest.java inside cts/tests/tests/identity/
+TEST(IdentityCredentialSupport, CoseMac0) {
+    vector<uint8_t> key;
+    key.resize(32);
+    vector<uint8_t> data = {0x10, 0x11, 0x12, 0x13};
+    vector<uint8_t> detachedContent = {};
+
+    optional<vector<uint8_t>> mac = support::coseMac0(key, data, detachedContent);
+    ASSERT_TRUE(mac);
+
+    EXPECT_EQ(
+            "[\n"
+            "  {0xa1, 0x01, 0x05},\n"
+            "  {},\n"
+            "  {0x10, 0x11, 0x12, 0x13},\n"
+            "  {0x6c, 0xec, 0xb5, 0x6a, 0xc9, 0x5c, 0xae, 0x3b, 0x41, 0x13, 0xde, 0xa4, 0xd8, "
+            "0x86, 0x5c, 0x28, 0x2c, 0xd5, 0xa5, 0x13, 0xff, 0x3b, 0xd1, 0xde, 0x70, 0x5e, 0xbb, "
+            "0xe2, 0x2d, 0x42, 0xbe, 0x53},\n"
+            "]",
+            support::cborPrettyPrint(mac.value()));
+}
+
+TEST(IdentityCredentialSupport, CoseMac0DetachedContent) {
+    vector<uint8_t> key;
+    key.resize(32);
+    vector<uint8_t> data = {};
+    vector<uint8_t> detachedContent = {0x10, 0x11, 0x12, 0x13};
+
+    optional<vector<uint8_t>> mac = support::coseMac0(key, data, detachedContent);
+    ASSERT_TRUE(mac);
+
+    // Same HMAC as in CoseMac0 test, only difference is that payload is null.
+    EXPECT_EQ(
+            "[\n"
+            "  {0xa1, 0x01, 0x05},\n"
+            "  {},\n"
+            "  null,\n"
+            "  {0x6c, 0xec, 0xb5, 0x6a, 0xc9, 0x5c, 0xae, 0x3b, 0x41, 0x13, 0xde, 0xa4, 0xd8, "
+            "0x86, 0x5c, 0x28, 0x2c, 0xd5, 0xa5, 0x13, 0xff, 0x3b, 0xd1, 0xde, 0x70, 0x5e, 0xbb, "
+            "0xe2, 0x2d, 0x42, 0xbe, 0x53},\n"
+            "]",
+            support::cborPrettyPrint(mac.value()));
+}
+
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/identity/support/tests/cppbor_test.cpp b/identity/support/tests/cppbor_test.cpp
new file mode 100644
index 0000000..3eb5598
--- /dev/null
+++ b/identity/support/tests/cppbor_test.cpp
@@ -0,0 +1,1013 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#include <iomanip>
+#include <sstream>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "cppbor.h"
+#include "cppbor_parse.h"
+
+using namespace cppbor;
+using namespace std;
+
+using ::testing::_;
+using ::testing::AllOf;
+using ::testing::ByRef;
+using ::testing::InSequence;
+using ::testing::IsNull;
+using ::testing::NotNull;
+using ::testing::Return;
+using ::testing::Truly;
+using ::testing::Unused;
+
+string hexDump(const string& str) {
+    stringstream s;
+    for (auto c : str) {
+        s << setfill('0') << setw(2) << hex << (static_cast<unsigned>(c) & 0xff);
+    }
+    return s.str();
+}
+
+TEST(SimpleValueTest, UnsignedValueSizes) {
+    // Check that unsigned integers encode to correct lengths, and that encodedSize() is correct.
+    vector<pair<uint64_t /* value */, size_t /* expected encoded size */>> testCases{
+            {0, 1},
+            {1, 1},
+            {23, 1},
+            {24, 2},
+            {255, 2},
+            {256, 3},
+            {65535, 3},
+            {65536, 5},
+            {4294967295, 5},
+            {4294967296, 9},
+            {std::numeric_limits<uint64_t>::max(), 9},
+    };
+    for (auto& testCase : testCases) {
+        Uint val(testCase.first);
+        EXPECT_EQ(testCase.second, val.encodedSize()) << "Wrong size for value " << testCase.first;
+        EXPECT_EQ(val.encodedSize(), val.toString().size())
+                << "encodedSize and encoding disagree for value " << testCase.first;
+    }
+}
+
+TEST(SimpleValueTest, UnsignedValueEncodings) {
+    EXPECT_EQ("\x00"s, Uint(0u).toString());
+    EXPECT_EQ("\x01"s, Uint(1u).toString());
+    EXPECT_EQ("\x0a"s, Uint(10u).toString());
+    EXPECT_EQ("\x17"s, Uint(23u).toString());
+    EXPECT_EQ("\x18\x18"s, Uint(24u).toString());
+    EXPECT_EQ("\x18\x19"s, Uint(25u).toString());
+    EXPECT_EQ("\x18\x64"s, Uint(100u).toString());
+    EXPECT_EQ("\x19\x03\xe8"s, Uint(1000u).toString());
+    EXPECT_EQ("\x1a\x00\x0f\x42\x40"s, Uint(1000000u).toString());
+    EXPECT_EQ("\x1b\x00\x00\x00\xe8\xd4\xa5\x10\x00"s, Uint(1000000000000u).toString());
+    EXPECT_EQ("\x1B\x7f\xff\xff\xff\xff\xff\xff\xff"s,
+              Uint(std::numeric_limits<int64_t>::max()).toString());
+}
+
+TEST(SimpleValueTest, NegativeValueEncodings) {
+    EXPECT_EQ("\x20"s, Nint(-1).toString());
+    EXPECT_EQ("\x28"s, Nint(-9).toString());
+    EXPECT_EQ("\x29"s, Nint(-10).toString());
+    EXPECT_EQ("\x36"s, Nint(-23).toString());
+    EXPECT_EQ("\x37"s, Nint(-24).toString());
+    EXPECT_EQ("\x38\x18"s, Nint(-25).toString());
+    EXPECT_EQ("\x38\x62"s, Nint(-99).toString());
+    EXPECT_EQ("\x38\x63"s, Nint(-100).toString());
+    EXPECT_EQ("\x39\x03\xe6"s, Nint(-999).toString());
+    EXPECT_EQ("\x39\x03\xe7"s, Nint(-1000).toString());
+    EXPECT_EQ("\x3a\x00\x0f\x42\x3F"s, Nint(-1000000).toString());
+    EXPECT_EQ("\x3b\x00\x00\x00\xe8\xd4\xa5\x0f\xff"s, Nint(-1000000000000).toString());
+    EXPECT_EQ("\x3B\x7f\xff\xff\xff\xff\xff\xff\xff"s,
+              Nint(std::numeric_limits<int64_t>::min()).toString());
+}
+
+TEST(SimpleValueDeathTest, NegativeValueEncodings) {
+    EXPECT_DEATH(Nint(0), "");
+    EXPECT_DEATH(Nint(1), "");
+}
+
+TEST(SimpleValueTest, BooleanEncodings) {
+    EXPECT_EQ("\xf4"s, Bool(false).toString());
+    EXPECT_EQ("\xf5"s, Bool(true).toString());
+}
+
+TEST(SimpleValueTest, ByteStringEncodings) {
+    EXPECT_EQ("\x40", Bstr("").toString());
+    EXPECT_EQ("\x41\x61", Bstr("a").toString());
+    EXPECT_EQ("\x41\x41", Bstr("A").toString());
+    EXPECT_EQ("\x44\x49\x45\x54\x46", Bstr("IETF").toString());
+    EXPECT_EQ("\x42\x22\x5c", Bstr("\"\\").toString());
+    EXPECT_EQ("\x42\xc3\xbc", Bstr("\xc3\xbc").toString());
+    EXPECT_EQ("\x43\xe6\xb0\xb4", Bstr("\xe6\xb0\xb4").toString());
+    EXPECT_EQ("\x44\xf0\x90\x85\x91", Bstr("\xf0\x90\x85\x91").toString());
+    EXPECT_EQ("\x44\x01\x02\x03\x04", Bstr("\x01\x02\x03\x04").toString());
+    EXPECT_EQ("\x44\x40\x40\x40\x40", Bstr("@@@@").toString());
+}
+
+TEST(SimpleValueTest, TextStringEncodings) {
+    EXPECT_EQ("\x60"s, Tstr("").toString());
+    EXPECT_EQ("\x61\x61"s, Tstr("a").toString());
+    EXPECT_EQ("\x61\x41"s, Tstr("A").toString());
+    EXPECT_EQ("\x64\x49\x45\x54\x46"s, Tstr("IETF").toString());
+    EXPECT_EQ("\x62\x22\x5c"s, Tstr("\"\\").toString());
+    EXPECT_EQ("\x62\xc3\xbc"s, Tstr("\xc3\xbc").toString());
+    EXPECT_EQ("\x63\xe6\xb0\xb4"s, Tstr("\xe6\xb0\xb4").toString());
+    EXPECT_EQ("\x64\xf0\x90\x85\x91"s, Tstr("\xf0\x90\x85\x91").toString());
+    EXPECT_EQ("\x64\x01\x02\x03\x04"s, Tstr("\x01\x02\x03\x04").toString());
+}
+
+TEST(IsIteratorPairOverTest, All) {
+    EXPECT_TRUE((
+            details::is_iterator_pair_over<pair<string::iterator, string::iterator>, char>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<string::const_iterator, string::iterator>,
+                                                char>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<string::iterator, string::const_iterator>,
+                                                char>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<char*, char*>, char>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<const char*, char*>, char>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<char*, const char*>, char>::value));
+    EXPECT_FALSE((details::is_iterator_pair_over<pair<string::iterator, string::iterator>,
+                                                 uint8_t>::value));
+    EXPECT_FALSE((details::is_iterator_pair_over<pair<char*, char*>, uint8_t>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<
+                 pair<vector<uint8_t>::iterator, vector<uint8_t>::iterator>, uint8_t>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<
+                 pair<vector<uint8_t>::const_iterator, vector<uint8_t>::iterator>,
+                 uint8_t>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<
+                 pair<vector<uint8_t>::iterator, vector<uint8_t>::const_iterator>,
+                 uint8_t>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<uint8_t*, uint8_t*>, uint8_t>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<const uint8_t*, uint8_t*>, uint8_t>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<uint8_t*, const uint8_t*>, uint8_t>::value));
+    EXPECT_FALSE((details::is_iterator_pair_over<
+                  pair<vector<uint8_t>::iterator, vector<uint8_t>::iterator>, char>::value));
+    EXPECT_FALSE((details::is_iterator_pair_over<pair<uint8_t*, const uint8_t*>, char>::value));
+}
+
+TEST(MakeEntryTest, Boolean) {
+    EXPECT_EQ("\xf4"s, details::makeItem(false)->toString());
+}
+
+TEST(MakeEntryTest, Integers) {
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<uint8_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<uint16_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<uint32_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<uint64_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<int8_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<int16_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<int32_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<int64_t>(0))->toString());
+    EXPECT_EQ("\x20"s, details::makeItem(static_cast<int8_t>(-1))->toString());
+    EXPECT_EQ("\x20"s, details::makeItem(static_cast<int16_t>(-1))->toString());
+    EXPECT_EQ("\x20"s, details::makeItem(static_cast<int32_t>(-1))->toString());
+    EXPECT_EQ("\x20"s, details::makeItem(static_cast<int64_t>(-1))->toString());
+
+    EXPECT_EQ("\x1b\xff\xff\xff\xff\xff\xff\xff\xff"s,
+              details::makeItem(static_cast<uint64_t>(std::numeric_limits<uint64_t>::max()))
+                      ->toString());
+}
+
+TEST(MakeEntryTest, StdStrings) {
+    string s1("hello");
+    const string s2("hello");
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s1)->toString());  // copy of string
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s,
+              details::makeItem(s2)->toString());  // copy of const string
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s,
+              details::makeItem(std::move(s1))->toString());  // move string
+    EXPECT_EQ(0U, s1.size());                                 // Prove string was moved, not copied.
+}
+
+TEST(MakeEntryTest, StdStringViews) {
+    string_view s1("hello");
+    const string_view s2("hello");
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s1)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s2)->toString());
+}
+
+TEST(MakeEntryTest, CStrings) {
+    char s1[] = "hello";
+    const char s2[] = "hello";
+    const char* s3 = "hello";
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s1)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s2)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s3)->toString());
+}
+
+TEST(MakeEntryTest, StringIteratorPairs) {
+    // Use iterators from string to prove that "real" iterators work
+    string s1 = "hello"s;
+    pair<string::iterator, string::iterator> p1 = make_pair(s1.begin(), s1.end());
+
+    const pair<string::iterator, string::iterator> p2 = p1;
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(p1)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(p2)->toString());
+
+    // Use char*s  as iterators
+    const char* s2 = "hello";
+    pair p3 = make_pair(s2, s2 + 5);
+    const pair p4 = p3;
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(p3)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(p4)->toString());
+}
+
+TEST(MakeEntryTest, ByteStrings) {
+    vector<uint8_t> v1 = {0x00, 0x01, 0x02};
+    const vector<uint8_t> v2 = {0x00, 0x01, 0x02};
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(v1)->toString());  // copy of vector
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(v2)->toString());  // copy of const vector
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(std::move(v1))->toString());  // move vector
+    EXPECT_EQ(0U, v1.size());  // Prove vector was moved, not copied.
+}
+
+TEST(MakeEntryTest, ByteStringIteratorPairs) {
+    using vec = vector<uint8_t>;
+    using iter = vec::iterator;
+    vec v1 = {0x00, 0x01, 0x02};
+    pair<iter, iter> p1 = make_pair(v1.begin(), v1.end());
+    const pair<iter, iter> p2 = make_pair(v1.begin(), v1.end());
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p1)->toString());
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p2)->toString());
+
+    // Use uint8_t*s as iterators
+    uint8_t v2[] = {0x00, 0x01, 0x02};
+    uint8_t* v3 = v2;
+    pair<uint8_t*, uint8_t*> p3 = make_pair(v2, v2 + 3);
+    const pair<uint8_t*, uint8_t*> p4 = make_pair(v2, v2 + 3);
+    pair<uint8_t*, uint8_t*> p5 = make_pair(v3, v3 + 3);
+    const pair<uint8_t*, uint8_t*> p6 = make_pair(v3, v3 + 3);
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p3)->toString());
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p4)->toString());
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p5)->toString());
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p6)->toString());
+}
+
+TEST(MakeEntryTest, ByteStringBuffers) {
+    uint8_t v1[] = {0x00, 0x01, 0x02};
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(make_pair(v1, 3))->toString());
+}
+
+TEST(MakeEntryTest, ItemPointer) {
+    Uint* p1 = new Uint(0);
+    EXPECT_EQ("\x00"s, details::makeItem(p1)->toString());
+    EXPECT_EQ("\x60"s, details::makeItem(new Tstr(string()))->toString());
+}
+
+TEST(MakeEntryTest, ItemReference) {
+    Tstr str("hello"s);
+    Tstr& strRef = str;
+    const Tstr& strConstRef = str;
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(str)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(strRef)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(strConstRef)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(std::move(str))->toString());
+    EXPECT_EQ("\x60"s, details::makeItem(str)->toString());  // Prove that it moved
+
+    EXPECT_EQ("\x00"s, details::makeItem(Uint(0))->toString());
+
+    EXPECT_EQ("\x43\x00\x01\x02"s,
+              details::makeItem(Bstr(vector<uint8_t>{0x00, 0x01, 0x02}))->toString());
+
+    EXPECT_EQ("\x80"s, details::makeItem(Array())->toString());
+    EXPECT_EQ("\xa0"s, details::makeItem(Map())->toString());
+}
+
+TEST(CompoundValueTest, ArrayOfInts) {
+    EXPECT_EQ("\x80"s, Array().toString());
+    Array(Uint(0)).toString();
+
+    EXPECT_EQ("\x81\x00"s, Array(Uint(0U)).toString());
+    EXPECT_EQ("\x82\x00\x01"s, Array(Uint(0), Uint(1)).toString());
+    EXPECT_EQ("\x83\x00\x01\x38\x62"s, Array(Uint(0), Uint(1), Nint(-99)).toString());
+
+    EXPECT_EQ("\x81\x00"s, Array(0).toString());
+    EXPECT_EQ("\x82\x00\x01"s, Array(0, 1).toString());
+    EXPECT_EQ("\x83\x00\x01\x38\x62"s, Array(0, 1, -99).toString());
+}
+
+TEST(CompoundValueTest, MapOfInts) {
+    EXPECT_EQ("\xA0"s, Map().toString());
+    EXPECT_EQ("\xA1\x00\x01"s, Map(Uint(0), Uint(1)).toString());
+    // Maps with an odd number of arguments will fail to compile.  Uncomment the next lines to test.
+    // EXPECT_EQ("\xA1\x00"s, Map(Int(0)).toString());
+    // EXPECT_EQ("\xA1\x00\x01\x02"s, Map(Int(0), Int(1), Int(2)).toString());
+}
+
+TEST(CompoundValueTest, MixedArray) {
+    vector<uint8_t> vec = {3, 2, 1};
+    EXPECT_EQ("\x84\x01\x20\x43\x03\x02\x01\x65\x68\x65\x6C\x6C\x6F"s,
+              Array(Uint(1), Nint(-1), Bstr(vec), Tstr("hello")).toString());
+
+    EXPECT_EQ("\x84\x01\x20\x43\x03\x02\x01\x65\x68\x65\x6C\x6C\x6F"s,
+              Array(1, -1, vec, "hello").toString());
+}
+
+TEST(CompoundValueTest, MixedMap) {
+    vector<uint8_t> vec = {3, 2, 1};
+    EXPECT_EQ("\xA2\x01\x20\x43\x03\x02\x01\x65\x68\x65\x6C\x6C\x6F"s,
+              Map(Uint(1), Nint(-1), Bstr(vec), Tstr("hello")).toString());
+
+    EXPECT_EQ("\xA2\x01\x20\x43\x03\x02\x01\x65\x68\x65\x6C\x6C\x6F"s,
+              Map(1, -1, vec, "hello").toString());
+}
+
+TEST(CompoundValueTest, NestedStructures) {
+    vector<uint8_t> vec = {3, 2, 1};
+
+    string expectedEncoding =
+            "\xA2\x66\x4F\x75\x74\x65\x72\x31\x82\xA2\x66\x49\x6E\x6E\x65\x72\x31\x18\x63\x66\x49"
+            "\x6E"
+            "\x6E\x65\x72\x32\x43\x03\x02\x01\x63\x66\x6F\x6F\x66\x4F\x75\x74\x65\x72\x32\x0A"s;
+
+    // Do it with explicitly-created Items
+    EXPECT_EQ(expectedEncoding,
+              Map(Tstr("Outer1"),
+                  Array(  //
+                          Map(Tstr("Inner1"), Uint(99), Tstr("Inner2"), Bstr(vec)), Tstr("foo")),
+                  Tstr("Outer2"),  //
+                  Uint(10))
+                      .toString());
+    EXPECT_EQ(3U, vec.size());
+
+    // Now just use convertible types
+    EXPECT_EQ(expectedEncoding, Map("Outer1",
+                                    Array(Map("Inner1", 99,  //
+                                              "Inner2", vec),
+                                          "foo"),
+                                    "Outer2", 10)
+                                        .toString());
+    EXPECT_EQ(3U, vec.size());
+
+    // Finally, do it with the .add() method.  This is slightly less efficient, but has the
+    // advantage you can build a structure up incrementally, or somewhat fluently if you like.
+    // First, fluently.
+    EXPECT_EQ(expectedEncoding, Map().add("Outer1", Array().add(Map()  //
+                                                                        .add("Inner1", 99)
+                                                                        .add("Inner2", vec))
+                                                            .add("foo"))
+                                        .add("Outer2", 10)
+                                        .toString());
+    EXPECT_EQ(3U, vec.size());
+
+    // Next, more incrementally
+    Array arr;
+    arr.add(Map()  //
+                    .add("Inner1", 99)
+                    .add("Inner2", vec))
+            .add("foo");
+    EXPECT_EQ(3U, vec.size());
+
+    Map m;
+    m.add("Outer1", std::move(arr));  // Moving is necessary; Map and Array cannot be copied.
+    m.add("Outer2", 10);
+    auto s = m.toString();
+    EXPECT_EQ(expectedEncoding, s);
+}
+
+TEST(EncodingMethodsTest, AllVariants) {
+    Map map;
+    map.add("key1", Array().add(Map()  //
+                                        .add("key_a", 9999999)
+                                        .add("key_b", std::vector<uint8_t>{0x01, 0x02, 0x03})
+                                        .add("key_c", std::numeric_limits<uint64_t>::max())
+                                        .add("key_d", std::numeric_limits<int16_t>::min()))
+                            .add("foo"))
+            .add("key2", true);
+
+    std::vector<uint8_t> buf;
+    buf.resize(map.encodedSize());
+
+    EXPECT_EQ(buf.data() + buf.size(), map.encode(buf.data(), buf.data() + buf.size()));
+
+    EXPECT_EQ(buf, map.encode());
+
+    std::vector<uint8_t> buf2;
+    map.encode(std::back_inserter(buf2));
+    EXPECT_EQ(buf, buf2);
+
+    auto iter = buf.begin();
+    map.encode([&](uint8_t c) { EXPECT_EQ(c, *iter++); });
+}
+
+TEST(EncodingMethodsTest, UintWithTooShortBuf) {
+    Uint val(100000);
+    vector<uint8_t> buf(val.encodedSize() - 1);
+    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
+}
+
+TEST(EncodingMethodsTest, TstrWithTooShortBuf) {
+    Tstr val("01234567890123456789012345"s);
+    vector<uint8_t> buf(1);
+    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
+
+    buf.resize(val.encodedSize() - 1);
+    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
+}
+
+TEST(EncodingMethodsTest, BstrWithTooShortBuf) {
+    Bstr val("01234567890123456789012345"s);
+    vector<uint8_t> buf(1);
+    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
+
+    buf.resize(val.encodedSize() - 1);
+    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
+}
+
+TEST(EncodingMethodsTest, ArrayWithTooShortBuf) {
+    Array val("a", 5, -100);
+
+    std::vector<uint8_t> buf(val.encodedSize() - 1);
+    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
+}
+
+TEST(EncodingMethodsTest, MapWithTooShortBuf) {
+    Map map;
+    map.add("key1", Array().add(Map()  //
+                                        .add("key_a", 99)
+                                        .add("key_b", std::vector<uint8_t>{0x01, 0x02, 0x03}))
+                            .add("foo"))
+            .add("key2", true);
+
+    std::vector<uint8_t> buf(map.encodedSize() - 1);
+    EXPECT_EQ(nullptr, map.encode(buf.data(), buf.data() + buf.size()));
+}
+
+TEST(EqualityTest, Uint) {
+    Uint val(99);
+    EXPECT_EQ(val, Uint(99));
+
+    EXPECT_NE(val, Uint(98));
+    EXPECT_NE(val, Nint(-1));
+    EXPECT_NE(val, Tstr("99"));
+    EXPECT_NE(val, Bstr("99"));
+    EXPECT_NE(val, Bool(false));
+    EXPECT_NE(val, Array(99, 1));
+    EXPECT_NE(val, Map(99, 1));
+}
+
+TEST(EqualityTest, Nint) {
+    Nint val(-1);
+    EXPECT_EQ(val, Nint(-1));
+
+    EXPECT_NE(val, Uint(99));
+    EXPECT_NE(val, Nint(-4));
+    EXPECT_NE(val, Tstr("99"));
+    EXPECT_NE(val, Bstr("99"));
+    EXPECT_NE(val, Bool(false));
+    EXPECT_NE(val, Array(99));
+    EXPECT_NE(val, Map(99, 1));
+}
+
+TEST(EqualityTest, Tstr) {
+    Tstr val("99");
+    EXPECT_EQ(val, Tstr("99"));
+
+    EXPECT_NE(val, Uint(99));
+    EXPECT_NE(val, Nint(-1));
+    EXPECT_NE(val, Nint(-4));
+    EXPECT_NE(val, Tstr("98"));
+    EXPECT_NE(val, Bstr("99"));
+    EXPECT_NE(val, Bool(false));
+    EXPECT_NE(val, Array(99, 1));
+    EXPECT_NE(val, Map(99, 1));
+}
+
+TEST(EqualityTest, Bstr) {
+    Bstr val("99");
+    EXPECT_EQ(val, Bstr("99"));
+
+    EXPECT_NE(val, Uint(99));
+    EXPECT_NE(val, Nint(-1));
+    EXPECT_NE(val, Nint(-4));
+    EXPECT_NE(val, Tstr("99"));
+    EXPECT_NE(val, Bstr("98"));
+    EXPECT_NE(val, Bool(false));
+    EXPECT_NE(val, Array(99, 1));
+    EXPECT_NE(val, Map(99, 1));
+}
+
+TEST(EqualityTest, Bool) {
+    Bool val(false);
+    EXPECT_EQ(val, Bool(false));
+
+    EXPECT_NE(val, Uint(99));
+    EXPECT_NE(val, Nint(-1));
+    EXPECT_NE(val, Nint(-4));
+    EXPECT_NE(val, Tstr("99"));
+    EXPECT_NE(val, Bstr("98"));
+    EXPECT_NE(val, Bool(true));
+    EXPECT_NE(val, Array(99, 1));
+    EXPECT_NE(val, Map(99, 1));
+}
+
+TEST(EqualityTest, Array) {
+    Array val(99, 1);
+    EXPECT_EQ(val, Array(99, 1));
+
+    EXPECT_NE(val, Uint(99));
+    EXPECT_NE(val, Nint(-1));
+    EXPECT_NE(val, Nint(-4));
+    EXPECT_NE(val, Tstr("99"));
+    EXPECT_NE(val, Bstr("98"));
+    EXPECT_NE(val, Bool(true));
+    EXPECT_NE(val, Array(99, 2));
+    EXPECT_NE(val, Array(98, 1));
+    EXPECT_NE(val, Array(99, 1, 2));
+    EXPECT_NE(val, Map(99, 1));
+}
+
+TEST(EqualityTest, Map) {
+    Map val(99, 1);
+    EXPECT_EQ(val, Map(99, 1));
+
+    EXPECT_NE(val, Uint(99));
+    EXPECT_NE(val, Nint(-1));
+    EXPECT_NE(val, Nint(-4));
+    EXPECT_NE(val, Tstr("99"));
+    EXPECT_NE(val, Bstr("98"));
+    EXPECT_NE(val, Bool(true));
+    EXPECT_NE(val, Array(99, 1));
+    EXPECT_NE(val, Map(99, 2));
+    EXPECT_NE(val, Map(99, 1, 99, 2));
+}
+
+TEST(ConvertTest, Uint) {
+    unique_ptr<Item> item = details::makeItem(10);
+
+    EXPECT_EQ(UINT, item->type());
+    EXPECT_NE(nullptr, item->asInt());
+    EXPECT_NE(nullptr, item->asUint());
+    EXPECT_EQ(nullptr, item->asNint());
+    EXPECT_EQ(nullptr, item->asTstr());
+    EXPECT_EQ(nullptr, item->asBstr());
+    EXPECT_EQ(nullptr, item->asSimple());
+    EXPECT_EQ(nullptr, item->asMap());
+    EXPECT_EQ(nullptr, item->asArray());
+
+    EXPECT_EQ(10, item->asInt()->value());
+    EXPECT_EQ(10, item->asUint()->value());
+}
+
+TEST(ConvertTest, Nint) {
+    unique_ptr<Item> item = details::makeItem(-10);
+
+    EXPECT_EQ(NINT, item->type());
+    EXPECT_NE(nullptr, item->asInt());
+    EXPECT_EQ(nullptr, item->asUint());
+    EXPECT_NE(nullptr, item->asNint());
+    EXPECT_EQ(nullptr, item->asTstr());
+    EXPECT_EQ(nullptr, item->asBstr());
+    EXPECT_EQ(nullptr, item->asSimple());
+    EXPECT_EQ(nullptr, item->asMap());
+    EXPECT_EQ(nullptr, item->asArray());
+
+    EXPECT_EQ(-10, item->asInt()->value());
+    EXPECT_EQ(-10, item->asNint()->value());
+}
+
+TEST(ConvertTest, Tstr) {
+    unique_ptr<Item> item = details::makeItem("hello");
+
+    EXPECT_EQ(TSTR, item->type());
+    EXPECT_EQ(nullptr, item->asInt());
+    EXPECT_EQ(nullptr, item->asUint());
+    EXPECT_EQ(nullptr, item->asNint());
+    EXPECT_NE(nullptr, item->asTstr());
+    EXPECT_EQ(nullptr, item->asBstr());
+    EXPECT_EQ(nullptr, item->asSimple());
+    EXPECT_EQ(nullptr, item->asMap());
+    EXPECT_EQ(nullptr, item->asArray());
+
+    EXPECT_EQ("hello"s, item->asTstr()->value());
+}
+
+TEST(ConvertTest, Bstr) {
+    vector<uint8_t> vec{0x23, 0x24, 0x22};
+    unique_ptr<Item> item = details::makeItem(vec);
+
+    EXPECT_EQ(BSTR, item->type());
+    EXPECT_EQ(nullptr, item->asInt());
+    EXPECT_EQ(nullptr, item->asUint());
+    EXPECT_EQ(nullptr, item->asNint());
+    EXPECT_EQ(nullptr, item->asTstr());
+    EXPECT_NE(nullptr, item->asBstr());
+    EXPECT_EQ(nullptr, item->asSimple());
+    EXPECT_EQ(nullptr, item->asMap());
+    EXPECT_EQ(nullptr, item->asArray());
+
+    EXPECT_EQ(vec, item->asBstr()->value());
+}
+
+TEST(ConvertTest, Bool) {
+    unique_ptr<Item> item = details::makeItem(false);
+
+    EXPECT_EQ(SIMPLE, item->type());
+    EXPECT_EQ(nullptr, item->asInt());
+    EXPECT_EQ(nullptr, item->asUint());
+    EXPECT_EQ(nullptr, item->asNint());
+    EXPECT_EQ(nullptr, item->asTstr());
+    EXPECT_EQ(nullptr, item->asBstr());
+    EXPECT_NE(nullptr, item->asSimple());
+    EXPECT_EQ(nullptr, item->asMap());
+    EXPECT_EQ(nullptr, item->asArray());
+
+    EXPECT_EQ(BOOLEAN, item->asSimple()->simpleType());
+    EXPECT_NE(nullptr, item->asSimple()->asBool());
+
+    EXPECT_FALSE(item->asSimple()->asBool()->value());
+}
+
+TEST(ConvertTest, Map) {
+    unique_ptr<Item> item(new Map);
+
+    EXPECT_EQ(MAP, item->type());
+    EXPECT_EQ(nullptr, item->asInt());
+    EXPECT_EQ(nullptr, item->asUint());
+    EXPECT_EQ(nullptr, item->asNint());
+    EXPECT_EQ(nullptr, item->asTstr());
+    EXPECT_EQ(nullptr, item->asBstr());
+    EXPECT_EQ(nullptr, item->asSimple());
+    EXPECT_NE(nullptr, item->asMap());
+    EXPECT_EQ(nullptr, item->asArray());
+
+    EXPECT_EQ(0U, item->asMap()->size());
+}
+
+TEST(ConvertTest, Array) {
+    unique_ptr<Item> item(new Array);
+
+    EXPECT_EQ(ARRAY, item->type());
+    EXPECT_EQ(nullptr, item->asInt());
+    EXPECT_EQ(nullptr, item->asUint());
+    EXPECT_EQ(nullptr, item->asNint());
+    EXPECT_EQ(nullptr, item->asTstr());
+    EXPECT_EQ(nullptr, item->asBstr());
+    EXPECT_EQ(nullptr, item->asSimple());
+    EXPECT_EQ(nullptr, item->asMap());
+    EXPECT_NE(nullptr, item->asArray());
+
+    EXPECT_EQ(0U, item->asArray()->size());
+}
+
+class MockParseClient : public ParseClient {
+  public:
+    MOCK_METHOD4(item, ParseClient*(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
+                                    const uint8_t* valueBegin, const uint8_t* end));
+    MOCK_METHOD4(itemEnd, ParseClient*(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
+                                       const uint8_t* valueBegin, const uint8_t* end));
+    MOCK_METHOD2(error, void(const uint8_t* position, const std::string& errorMessage));
+};
+
+MATCHER_P(IsType, value, std::string("Type ") + (negation ? "doesn't match" : "matches")) {
+    return arg->type() == value;
+}
+
+MATCHER_P(MatchesItem, value, "") {
+    return arg && *arg == value;
+}
+
+MATCHER_P(IsArrayOfSize, value, "") {
+    return arg->type() == ARRAY && arg->asArray()->size() == value;
+}
+
+MATCHER_P(IsMapOfSize, value, "") {
+    return arg->type() == MAP && arg->asMap()->size() == value;
+}
+
+TEST(StreamParseTest, Uint) {
+    MockParseClient mpc;
+
+    Uint val(100);
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encEnd, encEnd)).WillOnce(Return(&mpc));
+    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, error(_, _)).Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Nint) {
+    MockParseClient mpc;
+
+    Nint val(-10);
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encEnd, encEnd)).WillOnce(Return(&mpc));
+
+    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, error(_, _)).Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Bool) {
+    MockParseClient mpc;
+
+    Bool val(true);
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encEnd, encEnd)).WillOnce(Return(&mpc));
+    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, error(_, _)).Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Tstr) {
+    MockParseClient mpc;
+
+    Tstr val("Hello");
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encBegin + 1, encEnd)).WillOnce(Return(&mpc));
+    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, error(_, _)).Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Bstr) {
+    MockParseClient mpc;
+
+    Bstr val("Hello");
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encBegin + 1, encEnd)).WillOnce(Return(&mpc));
+    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, error(_, _)).Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Array) {
+    MockParseClient mpc;
+
+    Array val("Hello", 4, Array(-9, "Goodbye"), std::numeric_limits<uint64_t>::max());
+    ASSERT_NE(val[2]->asArray(), nullptr);
+    const Array& interior = *(val[2]->asArray());
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    {
+        InSequence s;
+        const uint8_t* pos = encBegin;
+        EXPECT_CALL(mpc, item(IsArrayOfSize(val.size()), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[0])), pos, pos + 1, pos + 6))
+                .WillOnce(Return(&mpc));
+        pos += 6;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[1])), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        const uint8_t* innerArrayBegin = pos;
+        EXPECT_CALL(mpc, item(IsArrayOfSize(interior.size()), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*interior[0])), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*interior[1])), pos, pos + 1, pos + 8))
+                .WillOnce(Return(&mpc));
+        pos += 8;
+        EXPECT_CALL(mpc, itemEnd(IsArrayOfSize(interior.size()), innerArrayBegin,
+                                 innerArrayBegin + 1, pos))
+                .WillOnce(Return(&mpc));
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[3])), pos, pos + 9, pos + 9))
+                .WillOnce(Return(&mpc));
+        EXPECT_CALL(mpc, itemEnd(IsArrayOfSize(val.size()), encBegin, encBegin + 1, encEnd))
+                .WillOnce(Return(&mpc));
+    }
+
+    EXPECT_CALL(mpc, error(_, _))  //
+            .Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Map) {
+    MockParseClient mpc;
+
+    Map val("Hello", 4, Array(-9, "Goodbye"), std::numeric_limits<uint64_t>::max());
+    ASSERT_NE(val[1].first->asArray(), nullptr);
+    const Array& interior = *(val[1].first->asArray());
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    {
+        InSequence s;
+        const uint8_t* pos = encBegin;
+        EXPECT_CALL(mpc, item(_, pos, pos + 1, pos + 1)).WillOnce(Return(&mpc));
+        ++pos;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[0].first)), pos, pos + 1, pos + 6))
+                .WillOnce(Return(&mpc));
+        pos += 6;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[0].second)), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        const uint8_t* innerArrayBegin = pos;
+        EXPECT_CALL(mpc, item(IsArrayOfSize(interior.size()), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*interior[0])), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*interior[1])), pos, pos + 1, pos + 8))
+                .WillOnce(Return(&mpc));
+        pos += 8;
+        EXPECT_CALL(mpc, itemEnd(IsArrayOfSize(interior.size()), innerArrayBegin,
+                                 innerArrayBegin + 1, pos))
+                .WillOnce(Return(&mpc));
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[1].second)), pos, pos + 9, pos + 9))
+                .WillOnce(Return(&mpc));
+        EXPECT_CALL(mpc, itemEnd(IsMapOfSize(val.size()), encBegin, encBegin + 1, encEnd))
+                .WillOnce(Return(&mpc));
+    }
+
+    EXPECT_CALL(mpc, error(_, _))  //
+            .Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Semantic) {
+    MockParseClient mpc;
+
+    vector<uint8_t> encoded;
+    auto iter = back_inserter(encoded);
+    encodeHeader(SEMANTIC, 0, iter);
+    Uint(999).encode(iter);
+
+    EXPECT_CALL(mpc, item(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, error(encoded.data(), "Semantic tags not supported"));
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(FullParserTest, Uint) {
+    Uint val(10);
+
+    auto [item, pos, message] = parse(val.encode());
+    EXPECT_THAT(item, MatchesItem(val));
+}
+
+TEST(FullParserTest, Nint) {
+    Nint val(-10);
+
+    auto [item, pos, message] = parse(val.encode());
+    EXPECT_THAT(item, MatchesItem(val));
+
+    vector<uint8_t> minNint = {0x3B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+    std::tie(item, pos, message) = parse(minNint);
+    EXPECT_THAT(item, NotNull());
+    EXPECT_EQ(item->asNint()->value(), std::numeric_limits<int64_t>::min());
+}
+
+TEST(FullParserTest, NintOutOfRange) {
+    vector<uint8_t> outOfRangeNint = {0x3B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+    auto [item, pos, message] = parse(outOfRangeNint);
+    EXPECT_THAT(item, IsNull());
+    EXPECT_EQ(pos, outOfRangeNint.data());
+    EXPECT_EQ(message, "NINT values that don't fit in int64_t are not supported.");
+}
+
+TEST(FullParserTest, Tstr) {
+    Tstr val("Hello");
+
+    auto [item, pos, message] = parse(val.encode());
+    EXPECT_THAT(item, MatchesItem(val));
+}
+
+TEST(FullParserTest, Bstr) {
+    Bstr val("\x00\x01\0x02"s);
+
+    auto [item, pos, message] = parse(val.encode());
+    EXPECT_THAT(item, MatchesItem(val));
+}
+
+TEST(FullParserTest, Array) {
+    Array val("hello", -4, 3);
+
+    auto encoded = val.encode();
+    auto [item, pos, message] = parse(encoded);
+    EXPECT_THAT(item, MatchesItem(ByRef(val)));
+    EXPECT_EQ(pos, encoded.data() + encoded.size());
+    EXPECT_EQ("", message);
+
+    // We've already checked it all, but walk it just for fun.
+    ASSERT_NE(nullptr, item->asArray());
+    const Array& arr = *(item->asArray());
+    ASSERT_EQ(arr[0]->type(), TSTR);
+    EXPECT_EQ(arr[0]->asTstr()->value(), "hello");
+}
+
+TEST(FullParserTest, Map) {
+    Map val("hello", -4, 3, Bstr("hi"));
+
+    auto [item, pos, message] = parse(val.encode());
+    EXPECT_THAT(item, MatchesItem(ByRef(val)));
+}
+
+TEST(FullParserTest, Complex) {
+    vector<uint8_t> vec = {0x01, 0x02, 0x08, 0x03};
+    Map val("Outer1",
+            Array(Map("Inner1", 99,  //
+                      "Inner2", vec),
+                  "foo"),
+            "Outer2", 10);
+
+    std::unique_ptr<Item> item;
+    const uint8_t* pos;
+    std::string message;
+    std::tie(item, pos, message) = parse(val.encode());
+    EXPECT_THAT(item, MatchesItem(ByRef(val)));
+}
+
+TEST(FullParserTest, IncompleteUint) {
+    Uint val(1000);
+
+    auto encoding = val.encode();
+    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 1);
+    EXPECT_EQ(nullptr, item.get());
+    EXPECT_EQ(encoding.data(), pos);
+    EXPECT_EQ("Need 2 byte(s) for length field, have 1.", message);
+}
+
+TEST(FullParserTest, IncompleteString) {
+    Tstr val("hello");
+
+    auto encoding = val.encode();
+    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 2);
+    EXPECT_EQ(nullptr, item.get());
+    EXPECT_EQ(encoding.data(), pos);
+    EXPECT_EQ("Need 5 byte(s) for text string, have 3.", message);
+}
+
+TEST(FullParserTest, ArrayWithInsufficientEntries) {
+    Array val(1, 2, 3, 4);
+
+    auto encoding = val.encode();
+    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 1);
+    EXPECT_EQ(nullptr, item.get());
+    EXPECT_EQ(encoding.data(), pos);
+    EXPECT_EQ("Not enough entries for array.", message);
+}
+
+TEST(FullParserTest, ArrayWithTruncatedEntry) {
+    Array val(1, 2, 3, 400000);
+
+    auto encoding = val.encode();
+    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 1);
+    EXPECT_EQ(nullptr, item.get());
+    EXPECT_EQ(encoding.data() + encoding.size() - 5, pos);
+    EXPECT_EQ("Need 4 byte(s) for length field, have 3.", message);
+}
+
+TEST(FullParserTest, MapWithTruncatedEntry) {
+    Map val(1, 2, 300000, 4);
+
+    auto encoding = val.encode();
+    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 2);
+    EXPECT_EQ(nullptr, item.get());
+    EXPECT_EQ(encoding.data() + 3, pos);
+    EXPECT_EQ("Need 4 byte(s) for length field, have 3.", message);
+}
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
