Add APIs to manually fill in signatures for CRLs.

This adds CRL analogs to some X509 functions added in
https://boringssl-review.googlesource.com/c/boringssl/+/43784. I missed
that we need to support this for CRLs too.

Change-Id: Id64952a1b2d33bcd057a96c80aadd97a3c3d9fb5
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/47525
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/x509/x509cset.c b/crypto/x509/x509cset.c
index cc27acb..ae93499 100644
--- a/crypto/x509/x509cset.c
+++ b/crypto/x509/x509cset.c
@@ -250,3 +250,34 @@
 {
     return i2d_X509_CRL_INFO(crl->crl, outp);
 }
+
+int X509_CRL_set1_signature_algo(X509_CRL *crl, const X509_ALGOR *algo)
+{
+    /* TODO(davidben): Const-correct generated ASN.1 dup functions.
+     * Alternatively, when the types are hidden and we can embed required fields
+     * directly in structs, import |X509_ALGOR_copy| from upstream. */
+    X509_ALGOR *copy1 = X509_ALGOR_dup((X509_ALGOR *)algo);
+    X509_ALGOR *copy2 = X509_ALGOR_dup((X509_ALGOR *)algo);
+    if (copy1 == NULL || copy2 == NULL) {
+        X509_ALGOR_free(copy1);
+        X509_ALGOR_free(copy2);
+        return 0;
+    }
+
+    X509_ALGOR_free(crl->sig_alg);
+    crl->sig_alg = copy1;
+    X509_ALGOR_free(crl->crl->sig_alg);
+    crl->crl->sig_alg = copy2;
+    return 1;
+}
+
+int X509_CRL_set1_signature_value(X509_CRL *crl, const uint8_t *sig,
+                                  size_t sig_len)
+{
+    if (!ASN1_STRING_set(crl->signature, sig, sig_len)) {
+      return 0;
+    }
+    crl->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+    crl->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+    return 1;
+}
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 3e1435b..b70ae52 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -1350,6 +1350,25 @@
 // instead.
 OPENSSL_EXPORT int i2d_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp);
 
+// X509_CRL_set1_signature_algo sets |crl|'s signature algorithm to |algo| and
+// returns one on success or zero on error. It updates both the signature field
+// of the TBSCertList structure, and the signatureAlgorithm field of the CRL.
+OPENSSL_EXPORT int X509_CRL_set1_signature_algo(X509_CRL *crl,
+                                                const X509_ALGOR *algo);
+
+// X509_CRL_set1_signature_value sets |crl|'s signature to a copy of the
+// |sig_len| bytes pointed by |sig|. It returns one on success and zero on
+// error.
+//
+// Due to a specification error, X.509 CRLs store signatures in ASN.1 BIT
+// STRINGs, but signature algorithms return byte strings rather than bit
+// strings. This function creates a BIT STRING containing a whole number of
+// bytes, with the bit order matching the DER encoding. This matches the
+// encoding used by all X.509 signature algorithms.
+OPENSSL_EXPORT int X509_CRL_set1_signature_value(X509_CRL *crl,
+                                                 const uint8_t *sig,
+                                                 size_t sig_len);
+
 // X509_REVOKED_get0_serialNumber returns the serial number of the certificate
 // revoked by |revoked|.
 OPENSSL_EXPORT const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(