Include the EKU extension in bssl server's self-signed certs.

macOS requires an explicit EKU extension. This fixes connection failing
with ERR_CERT_INVALID in Chrome (when the built-in verifier isn't
enabled).
https://support.apple.com/en-us/HT210176

Change-Id: Ida23391107fe0168a854c1f4ea3ac52db670e7e8
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51525
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/tool/server.cc b/tool/server.cc
index 18b692d..ebecee0 100644
--- a/tool/server.cc
+++ b/tool/server.cc
@@ -132,21 +132,37 @@
 
 static bssl::UniquePtr<X509> MakeSelfSignedCert(EVP_PKEY *evp_pkey,
                                                 const int valid_days) {
+  uint64_t serial;
   bssl::UniquePtr<X509> x509(X509_new());
-  uint32_t serial;
-  RAND_bytes(reinterpret_cast<uint8_t*>(&serial), sizeof(serial));
-  ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), serial >> 1);
-  X509_gmtime_adj(X509_get_notBefore(x509.get()), 0);
-  X509_gmtime_adj(X509_get_notAfter(x509.get()), 60 * 60 * 24 * valid_days);
+  if (!x509 ||  //
+      !X509_set_version(x509.get(), X509_VERSION_3) ||
+      !RAND_bytes(reinterpret_cast<uint8_t *>(&serial), sizeof(serial)) ||
+      !ASN1_INTEGER_set_uint64(X509_get_serialNumber(x509.get()), serial) ||
+      !X509_gmtime_adj(X509_get_notBefore(x509.get()), 0) ||
+      !X509_gmtime_adj(X509_get_notAfter(x509.get()),
+                       60 * 60 * 24 * valid_days)) {
+    return nullptr;
+  }
 
-  X509_NAME* subject = X509_get_subject_name(x509.get());
-  X509_NAME_add_entry_by_txt(subject, "C", MBSTRING_ASC,
-                             reinterpret_cast<const uint8_t *>("US"), -1, -1,
-                             0);
-  X509_NAME_add_entry_by_txt(subject, "O", MBSTRING_ASC,
-                             reinterpret_cast<const uint8_t *>("BoringSSL"), -1,
-                             -1, 0);
-  X509_set_issuer_name(x509.get(), subject);
+  X509_NAME *subject = X509_get_subject_name(x509.get());
+  if (!X509_NAME_add_entry_by_txt(subject, "C", MBSTRING_ASC,
+                                  reinterpret_cast<const uint8_t *>("US"), -1,
+                                  -1, 0) ||
+      !X509_NAME_add_entry_by_txt(
+          subject, "O", MBSTRING_ASC,
+          reinterpret_cast<const uint8_t *>("BoringSSL"), -1, -1, 0) ||
+      !X509_set_issuer_name(x509.get(), subject)) {
+    return nullptr;
+  }
+
+  // macOS requires an explicit EKU extension.
+  bssl::UniquePtr<STACK_OF(ASN1_OBJECT)> ekus(sk_ASN1_OBJECT_new_null());
+  if (!ekus ||
+      !sk_ASN1_OBJECT_push(ekus.get(), OBJ_nid2obj(NID_server_auth)) ||
+      !X509_add1_ext_i2d(x509.get(), NID_ext_key_usage, ekus.get(), /*crit=*/1,
+                         /*flags=*/0)) {
+    return nullptr;
+  }
 
   if (!X509_set_pubkey(x509.get(), evp_pkey)) {
     fprintf(stderr, "Failed to set public key.\n");