summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Stokes <alanstokes@google.com>2021-07-06 10:30:07 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2021-07-06 10:30:07 +0000
commit8a47bfe7d95a23b788c3c193335b0ac3aba39bf4 (patch)
tree2db7990f23713c423959eb2e4ae7f07c046cf65f
parent378bfbe5b39ff07f630134ff5faaa7e92d3f1611 (diff)
parentb85739d830dbfc0898ab38eaa941ce23eb65d328 (diff)
downloadsecurity-8a47bfe7d95a23b788c3c193335b0ac3aba39bf4.tar.gz
Merge "Switch to RsaPublicKey."
-rw-r--r--ondevice-signing/CertUtils.cpp31
-rw-r--r--ondevice-signing/CertUtils.h3
-rw-r--r--ondevice-signing/FakeCompOs.cpp31
-rw-r--r--ondevice-signing/FakeCompOs.h3
-rw-r--r--ondevice-signing/odsign_main.cpp2
5 files changed, 64 insertions, 6 deletions
diff --git a/ondevice-signing/CertUtils.cpp b/ondevice-signing/CertUtils.cpp
index acc11e45..d2f19ce2 100644
--- a/ondevice-signing/CertUtils.cpp
+++ b/ondevice-signing/CertUtils.cpp
@@ -299,6 +299,37 @@ Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::string& path) {
return extractPublicKey(X509_get_pubkey(cert.value().get()));
}
+Result<std::vector<uint8_t>> extractRsaPublicKey(EVP_PKEY* pkey) {
+ RSA* rsa = EVP_PKEY_get0_RSA(pkey);
+ if (rsa == nullptr) {
+ return Error() << "The public key is not an RSA key";
+ }
+
+ uint8_t* out = nullptr;
+ int size = i2d_RSAPublicKey(rsa, &out);
+ if (size < 0 || !out) {
+ return Error() << "Failed to convert to RSAPublicKey";
+ }
+
+ bssl::UniquePtr<uint8_t> buffer(out);
+ std::vector<uint8_t> result(out, out + size);
+ return result;
+}
+
+Result<std::vector<uint8_t>> extractRsaPublicKeyFromX509(const std::vector<uint8_t>& derCert) {
+ auto derCertBytes = derCert.data();
+ bssl::UniquePtr<X509> decoded_cert(d2i_X509(nullptr, &derCertBytes, derCert.size()));
+ if (decoded_cert.get() == nullptr) {
+ return Error() << "Failed to decode X509 certificate.";
+ }
+ bssl::UniquePtr<EVP_PKEY> decoded_pkey(X509_get_pubkey(decoded_cert.get()));
+ if (decoded_pkey == nullptr) {
+ return Error() << "Failed to extract public key from x509 cert";
+ }
+
+ return extractRsaPublicKey(decoded_pkey.get());
+}
+
Result<CertInfo> verifyAndExtractCertInfoFromX509(const std::string& path,
const std::vector<uint8_t>& publicKey) {
auto public_key = toRsaPkey(publicKey);
diff --git a/ondevice-signing/CertUtils.h b/ondevice-signing/CertUtils.h
index 1fa5bbcd..fd6080d9 100644
--- a/ondevice-signing/CertUtils.h
+++ b/ondevice-signing/CertUtils.h
@@ -60,6 +60,9 @@ android::base::Result<std::vector<uint8_t>>
extractPublicKeyFromSubjectPublicKeyInfo(const std::vector<uint8_t>& subjectKeyInfo);
android::base::Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::string& path);
+android::base::Result<std::vector<uint8_t>>
+extractRsaPublicKeyFromX509(const std::vector<uint8_t>& x509);
+
android::base::Result<CertInfo>
verifyAndExtractCertInfoFromX509(const std::string& path, const std::vector<uint8_t>& publicKey);
diff --git a/ondevice-signing/FakeCompOs.cpp b/ondevice-signing/FakeCompOs.cpp
index 48eb01ab..637fe5c7 100644
--- a/ondevice-signing/FakeCompOs.cpp
+++ b/ondevice-signing/FakeCompOs.cpp
@@ -16,7 +16,6 @@
#include "FakeCompOs.h"
-#include "CertUtils.h"
#include "KeyConstants.h"
#include <android-base/file.h>
@@ -26,7 +25,10 @@
#include <binder/IServiceManager.h>
+#include <openssl/nid.h>
#include <openssl/rand.h>
+#include <openssl/rsa.h>
+#include <openssl/sha.h>
using android::String16;
@@ -210,6 +212,28 @@ Result<FakeCompOs::ByteVector> FakeCompOs::signData(const ByteVector& keyBlob,
return signature.value();
}
+Result<void> FakeCompOs::verifySignature(const ByteVector& message, const ByteVector& signature,
+ const ByteVector& rsaPublicKey) const {
+ auto derBytes = rsaPublicKey.data();
+ bssl::UniquePtr<RSA> rsaKey(d2i_RSAPublicKey(nullptr, &derBytes, rsaPublicKey.size()));
+ if (rsaKey.get() == nullptr) {
+ return Error() << "Failed to parse RsaPublicKey";
+ }
+ if (derBytes != rsaPublicKey.data() + rsaPublicKey.size()) {
+ return Error() << "Key has unexpected trailing data";
+ }
+
+ uint8_t hashBuf[SHA256_DIGEST_LENGTH];
+ SHA256(message.data(), message.size(), hashBuf);
+
+ bool success = RSA_verify(NID_sha256, hashBuf, sizeof(hashBuf), signature.data(),
+ signature.size(), rsaKey.get());
+ if (!success) {
+ return Error() << "Failed to verify signature";
+ }
+ return {};
+}
+
Result<void> FakeCompOs::loadAndVerifyKey(const ByteVector& keyBlob,
const ByteVector& publicKey) const {
// To verify the key is valid, we use it to sign some data, and then verify the signature using
@@ -225,8 +249,5 @@ Result<void> FakeCompOs::loadAndVerifyKey(const ByteVector& keyBlob,
return signature.error();
}
- std::string dataStr(data.begin(), data.end());
- std::string signatureStr(signature.value().begin(), signature.value().end());
-
- return verifySignature(dataStr, signatureStr, publicKey);
+ return verifySignature(data, signature.value(), publicKey);
}
diff --git a/ondevice-signing/FakeCompOs.h b/ondevice-signing/FakeCompOs.h
index 7d76938e..6c12c609 100644
--- a/ondevice-signing/FakeCompOs.h
+++ b/ondevice-signing/FakeCompOs.h
@@ -53,6 +53,9 @@ class FakeCompOs {
android::base::Result<ByteVector> signData(const ByteVector& keyBlob,
const ByteVector& data) const;
+ android::base::Result<void> verifySignature(const ByteVector& message,
+ const ByteVector& signature,
+ const ByteVector& rsaPublicKey) const;
KeyDescriptor mDescriptor;
android::sp<IKeystoreService> mService;
diff --git a/ondevice-signing/odsign_main.cpp b/ondevice-signing/odsign_main.cpp
index 55d8b1c5..b14a91e3 100644
--- a/ondevice-signing/odsign_main.cpp
+++ b/ondevice-signing/odsign_main.cpp
@@ -221,7 +221,7 @@ Result<std::vector<uint8_t>> verifyOrGenerateCompOsKey(const SigningKey& signing
if (!keyData.ok()) {
return Error() << "Failed to generate key: " << keyData.error();
}
- auto publicKeyStatus = extractPublicKeyFromX509(keyData.value().cert);
+ auto publicKeyStatus = extractRsaPublicKeyFromX509(keyData.value().cert);
if (!publicKeyStatus.ok()) {
return Error() << "Failed to extract CompOs public key" << publicKeyStatus.error();
}