summaryrefslogtreecommitdiff
path: root/chromium/device/fido/p256_public_key.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/device/fido/p256_public_key.cc')
-rw-r--r--chromium/device/fido/p256_public_key.cc66
1 files changed, 38 insertions, 28 deletions
diff --git a/chromium/device/fido/p256_public_key.cc b/chromium/device/fido/p256_public_key.cc
index 2bc521cb226..a6e0a7ffef9 100644
--- a/chromium/device/fido/p256_public_key.cc
+++ b/chromium/device/fido/p256_public_key.cc
@@ -8,6 +8,7 @@
#include "components/cbor/writer.h"
#include "components/device_event_log/device_event_log.h"
+#include "device/fido/cbor_extract.h"
#include "device/fido/fido_constants.h"
#include "device/fido/public_key.h"
#include "third_party/boringssl/src/include/openssl/bn.h"
@@ -17,6 +18,11 @@
#include "third_party/boringssl/src/include/openssl/mem.h"
#include "third_party/boringssl/src/include/openssl/obj.h"
+using device::cbor_extract::IntKey;
+using device::cbor_extract::Is;
+using device::cbor_extract::StepOrByte;
+using device::cbor_extract::Stop;
+
namespace device {
// kFieldElementLength is the size of a P-256 field element. The field is
@@ -72,39 +78,43 @@ std::unique_ptr<PublicKey> P256PublicKey::ExtractFromCOSEKey(
int32_t algorithm,
base::span<const uint8_t> cbor_bytes,
const cbor::Value::MapValue& map) {
- cbor::Value::MapValue::const_iterator it =
- map.find(cbor::Value(static_cast<int64_t>(CoseKeyKey::kKty)));
- if (it == map.end() || !it->second.is_integer() ||
- it->second.GetInteger() != static_cast<int64_t>(CoseKeyTypes::kEC2)) {
- return nullptr;
- }
-
- it = map.find(cbor::Value(static_cast<int64_t>(CoseKeyKey::kEllipticCurve)));
- if (it == map.end() || !it->second.is_integer() ||
- it->second.GetInteger() != static_cast<int64_t>(CoseCurves::kP256)) {
- return nullptr;
- }
-
- cbor::Value::MapValue::const_iterator it_x =
- map.find(cbor::Value(static_cast<int64_t>(CoseKeyKey::kEllipticX)));
- cbor::Value::MapValue::const_iterator it_y =
- map.find(cbor::Value(static_cast<int64_t>(CoseKeyKey::kEllipticY)));
- if (it_x == map.end() || !it_x->second.is_bytestring() || it_y == map.end() ||
- !it_y->second.is_bytestring()) {
+ struct COSEKey {
+ const int64_t* kty;
+ const int64_t* crv;
+ const std::vector<uint8_t>* x;
+ const std::vector<uint8_t>* y;
+ } cose_key;
+
+ static constexpr cbor_extract::StepOrByte<COSEKey> kSteps[] = {
+ // clang-format off
+ ELEMENT(Is::kRequired, COSEKey, kty),
+ IntKey<COSEKey>(static_cast<int>(CoseKeyKey::kKty)),
+
+ ELEMENT(Is::kRequired, COSEKey, crv),
+ IntKey<COSEKey>(static_cast<int>(CoseKeyKey::kEllipticCurve)),
+
+ ELEMENT(Is::kRequired, COSEKey, x),
+ IntKey<COSEKey>(static_cast<int>(CoseKeyKey::kEllipticX)),
+
+ ELEMENT(Is::kRequired, COSEKey, y),
+ IntKey<COSEKey>(static_cast<int>(CoseKeyKey::kEllipticY)),
+
+ Stop<COSEKey>(),
+ // clang-format on
+ };
+
+ if (!cbor_extract::Extract<COSEKey>(&cose_key, kSteps, map) ||
+ *cose_key.kty != static_cast<int64_t>(CoseKeyTypes::kEC2) ||
+ *cose_key.crv != static_cast<int64_t>(CoseCurves::kP256) ||
+ cose_key.x->size() != kFieldElementLength ||
+ cose_key.y->size() != kFieldElementLength) {
return nullptr;
}
- const std::vector<uint8_t>& x(it_x->second.GetBytestring());
- const std::vector<uint8_t>& y(it_y->second.GetBytestring());
-
- if (x.size() != kFieldElementLength || y.size() != kFieldElementLength) {
- FIDO_LOG(ERROR) << "Incorrect length for P-256 COSE key coordinates";
- }
-
bssl::UniquePtr<BIGNUM> x_bn(BN_new());
bssl::UniquePtr<BIGNUM> y_bn(BN_new());
- if (!BN_bin2bn(x.data(), x.size(), x_bn.get()) ||
- !BN_bin2bn(y.data(), y.size(), y_bn.get())) {
+ if (!BN_bin2bn(cose_key.x->data(), cose_key.x->size(), x_bn.get()) ||
+ !BN_bin2bn(cose_key.y->data(), cose_key.y->size(), y_bn.get())) {
return nullptr;
}