Skip to content

Commit

Permalink
Add support for NETSCAPE_SPKI_print (#1624)
Browse files Browse the repository at this point in the history
Ruby consumes NETSCAPE_SPKI_print for debugging purposes.
This adds support for the symbol for easier integration.

By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 license and the ISC license.
  • Loading branch information
samuel40791765 authored Jun 14, 2024
1 parent 8075b54 commit e7e64f8
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
40 changes: 40 additions & 0 deletions crypto/x509/x509_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7583,3 +7583,43 @@ TEST(X509Test, PublicKeyCache) {
key2.reset(X509_PUBKEY_get(pub));
EXPECT_FALSE(key2);
}

TEST(X509Test, SPKIPrint) {
bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
ASSERT_TRUE(bio);
bssl::UniquePtr<NETSCAPE_SPKI> spki(NETSCAPE_SPKI_new());
ASSERT_TRUE(spki);

bssl::UniquePtr<EVP_PKEY> key = PrivateKeyFromPEM(kP256Key);
EXPECT_TRUE(NETSCAPE_SPKI_set_pubkey(spki.get(), key.get()));
EXPECT_TRUE(NETSCAPE_SPKI_sign(spki.get(), key.get(), EVP_sha256()));

std::string challenge = "challenge string";
ASSERT_TRUE(ASN1_STRING_set(spki.get()->spkac->challenge, challenge.data(),
challenge.size()));

EXPECT_TRUE(NETSCAPE_SPKI_print(bio.get(), spki.get()));

// The contents of the signature is printed last but it's randomized,
// so we only check the expected output before that.
static const char expected_certificate_string[] = R"(Netscape SPKI:
Public Key Algorithm: id-ecPublicKey
Public-Key: (P-256)
pub:
04:e6:2b:69:e2:bf:65:9f:97:be:2f:1e:0d:94:8a:
4c:d5:97:6b:b7:a9:1e:0d:46:fb:dd:a9:a9:1e:9d:
dc:ba:5a:01:e7:d6:97:a8:0a:18:f9:c3:c4:a3:1e:
56:e2:7c:83:48:db:16:1a:1c:f5:1d:7e:f1:94:2d:
4b:cf:72:22:c1
Challenge String: challenge string
Signature Algorithm: ecdsa-with-SHA256
)";

const uint8_t *data;
size_t data_len;
ASSERT_TRUE(BIO_mem_contents(bio.get(), &data, &data_len));
ASSERT_GT(data_len, strlen(expected_certificate_string));
std::string print(reinterpret_cast<const char *>(data),
strlen(expected_certificate_string));
EXPECT_EQ(print, expected_certificate_string);
}
45 changes: 45 additions & 0 deletions crypto/x509/x509spki.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/x509.h>
#include "internal.h"

int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) {
if ((x == NULL) || (x->spkac == NULL)) {
Expand Down Expand Up @@ -131,3 +132,47 @@ char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) {
OPENSSL_free(der_spki);
return b64_str;
}

int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki) {
if (out == NULL || spki == NULL || spki->spkac == NULL ||
spki->spkac->pubkey == NULL || spki->sig_algor == NULL ||
spki->sig_algor->algorithm == NULL || spki->signature == NULL ||
spki->signature->data == NULL) {
OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
BIO_printf(out, "Netscape SPKI:\n");

// Print out public key algorithm and contents.
ASN1_OBJECT *spkioid;
X509_PUBKEY_get0_param(&spkioid, NULL, NULL, NULL, spki->spkac->pubkey);
int spkioid_nid = OBJ_obj2nid(spkioid);
BIO_printf(out, " Public Key Algorithm: %s\n",
(spkioid_nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(spkioid_nid));
EVP_PKEY *pkey = X509_PUBKEY_get0(spki->spkac->pubkey);
if (pkey == NULL) {
BIO_printf(out, " Unable to load public key\n");
} else {
EVP_PKEY_print_public(out, pkey, 4, NULL);
}

ASN1_IA5STRING *chal = spki->spkac->challenge;
if (chal != NULL && chal->length != 0) {
BIO_printf(out, " Challenge String: %.*s\n", chal->length, chal->data);
}

// Print out signature algorithm and contents.
BIO_printf(out, " Signature Algorithm: %s",
(OBJ_obj2nid(spki->sig_algor->algorithm) == NID_undef)
? "UNKNOWN"
: OBJ_nid2ln(OBJ_obj2nid(spki->sig_algor->algorithm)));
for (int i = 0; i < spki->signature->length; i++) {
if ((i % 18) == 0) {
BIO_printf(out, "\n ");
}
BIO_printf(out, "%02x%s", (unsigned char)spki->signature->data[i],
((i + 1) == spki->signature->length) ? "" : ":");
}
BIO_write(out, "\n", 1);
return 1;
}
3 changes: 3 additions & 0 deletions include/openssl/x509.h
Original file line number Diff line number Diff line change
Expand Up @@ -2345,6 +2345,9 @@ OPENSSL_EXPORT NETSCAPE_SPKAC *d2i_NETSCAPE_SPKAC(NETSCAPE_SPKAC **out,
OPENSSL_EXPORT int i2d_NETSCAPE_SPKAC(const NETSCAPE_SPKAC *spkac,
uint8_t **outp);

// NETSCAPE_SPKI_print prints out the contents of |spki| to |out|.
OPENSSL_EXPORT int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);


// RSASSA-PSS Parameters.
//
Expand Down

0 comments on commit e7e64f8

Please sign in to comment.