Use accessors for certificates and RSA keys.

The upstream RSA APIs are annoyingly tedious, but ah well. Note
X509_set1_signature_algo sets both copies of the signature algorithm.
This also fixes an EVP_PKEY leak in some error paths.

Test: mm
Change-Id: Ifa6f130e9d7dce328c649aa241057dbe5c0e5e66
diff --git a/keystore2/src/crypto/certificate_utils.cpp b/keystore2/src/crypto/certificate_utils.cpp
index 31c7fb4..d0508c8 100644
--- a/keystore2/src/crypto/certificate_utils.cpp
+++ b/keystore2/src/crypto/certificate_utils.cpp
@@ -19,6 +19,7 @@
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/mem.h>
+#include <openssl/ossl_typ.h>
 #include <openssl/x509v3.h>
 
 #include <functional>
@@ -512,10 +513,7 @@
     return ASN1_STRING_Ptr(algo_str);
 }
 
-CertUtilsError makeAndSetAlgo(X509_ALGOR* algo_field, Algo algo, Padding padding, Digest digest) {
-    if (algo_field == nullptr) {
-        return CertUtilsError::UnexpectedNullPointer;
-    }
+std::variant<CertUtilsError, X509_ALGOR_Ptr> makeAlgo(Algo algo, Padding padding, Digest digest) {
     ASN1_STRING_Ptr param;
     int param_type = V_ASN1_UNDEF;
     int nid = 0;
@@ -584,23 +582,29 @@
         return CertUtilsError::InvalidArgument;
     }
 
-    if (!X509_ALGOR_set0(algo_field, OBJ_nid2obj(nid), param_type, param.get())) {
+    X509_ALGOR_Ptr result(X509_ALGOR_new());
+    if (!result) {
+        return CertUtilsError::MemoryAllocation;
+    }
+    if (!X509_ALGOR_set0(result.get(), OBJ_nid2obj(nid), param_type, param.get())) {
         return CertUtilsError::Encoding;
     }
     // The X509 struct took ownership.
     param.release();
-    return CertUtilsError::Ok;
+    return result;
 }
 
 // This function allows for signing a
 CertUtilsError signCertWith(X509* certificate,
                             std::function<std::vector<uint8_t>(const uint8_t*, size_t)> sign,
                             Algo algo, Padding padding, Digest digest) {
-    if (auto error = makeAndSetAlgo(certificate->sig_alg, algo, padding, digest)) {
-        return error;
+    auto algo_objV = makeAlgo(algo, padding, digest);
+    if (auto error = std::get_if<CertUtilsError>(&algo_objV)) {
+        return *error;
     }
-    if (auto error = makeAndSetAlgo(certificate->cert_info->signature, algo, padding, digest)) {
-        return error;
+    auto& algo_obj = std::get<X509_ALGOR_Ptr>(algo_objV);
+    if (!X509_set1_signature_algo(certificate, algo_obj.get())) {
+        return CertUtilsError::BoringSsl;
     }
 
     uint8_t* cert_buf = nullptr;
@@ -615,13 +619,10 @@
         return CertUtilsError::SignatureFailed;
     }
 
-    if (!ASN1_STRING_set(certificate->signature, signature.data(), signature.size())) {
+    if (!X509_set1_signature_value(certificate, signature.data(), signature.size())) {
         return CertUtilsError::BoringSsl;
     }
 
-    certificate->signature->flags &= ~(0x07);
-    certificate->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-
     return CertUtilsError::Ok;
 }