Check for empty vectors in RKP COSE code

The std::vector::data accessor returns nullptr if the vector is empty.
We were not checking for empty vectors in some spots, and were thus
passing nullptr to Boring crypto. Boring does not generally check for
null pointers on inputs, so we end up segfaulting.

Work around this by explicitly checking for empty buffers in places
where the return value from std::vector::data is passed to Boring.

Test: atest RemoteProvisionerUnitTests
Change-Id: I92c203196a904c1ee95c6de4b0a7962ac0d9292d
diff --git a/cppcose/cppcose.cpp b/cppcose/cppcose.cpp
index a40b440..e17f273 100644
--- a/cppcose/cppcose.cpp
+++ b/cppcose/cppcose.cpp
@@ -55,6 +55,10 @@
 
 ErrMsgOr<bytevec> generateCoseMac0Mac(const bytevec& macKey, const bytevec& externalAad,
                                       const bytevec& payload) {
+    if (macKey.empty()) {
+        return "Empty MAC key";
+    }
+
     auto macStructure = cppbor::Array()
                             .add("MAC0")
                             .add(cppbor::Map().add(ALGORITHM, HMAC_256).canonicalize().encode())
@@ -170,10 +174,9 @@
     const cppbor::Bstr* protectedParams = coseSign1->get(kCoseSign1ProtectedParams)->asBstr();
     const cppbor::Map* unprotectedParams = coseSign1->get(kCoseSign1UnprotectedParams)->asMap();
     const cppbor::Bstr* payload = coseSign1->get(kCoseSign1Payload)->asBstr();
-    const cppbor::Bstr* signature = coseSign1->get(kCoseSign1Signature)->asBstr();
 
-    if (!protectedParams || !unprotectedParams || !payload || !signature) {
-        return "Invalid COSE_Sign1";
+    if (!protectedParams || !unprotectedParams || !payload) {
+        return "Missing input parameters";
     }
 
     auto [parsedProtParams, _, errMsg] = cppbor::parse(protectedParams);
@@ -190,9 +193,16 @@
     }
 
     if (!ignoreSignature) {
+        const cppbor::Bstr* signature = coseSign1->get(kCoseSign1Signature)->asBstr();
+        if (!signature || signature->value().empty()) {
+            return "Missing signature input";
+        }
+
         bool selfSigned = signingCoseKey.empty();
         auto key = CoseKey::parseEd25519(selfSigned ? payload->value() : signingCoseKey);
-        if (!key) return "Bad signing key: " + key.moveMessage();
+        if (!key || key->getBstrValue(CoseKey::PUBKEY_X)->empty()) {
+            return "Bad signing key: " + key.moveMessage();
+        }
 
         bytevec signatureInput =
             cppbor::Array().add("Signature1").add(*protectedParams).add(aad).add(*payload).encode();
@@ -356,6 +366,10 @@
 
 ErrMsgOr<bytevec> x25519_HKDF_DeriveKey(const bytevec& pubKeyA, const bytevec& privKeyA,
                                         const bytevec& pubKeyB, bool senderIsA) {
+    if (privKeyA.empty() || pubKeyA.empty() || pubKeyB.empty()) {
+        return "Missing input key parameters";
+    }
+
     bytevec rawSharedKey(X25519_SHARED_KEY_LEN);
     if (!::X25519(rawSharedKey.data(), privKeyA.data(), pubKeyB.data())) {
         return "ECDH operation failed";