Skip to content

Commit e7e64f8

Browse files
Add support for NETSCAPE_SPKI_print (aws#1624)
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.
1 parent 8075b54 commit e7e64f8

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

crypto/x509/x509_test.cc

+40
Original file line numberDiff line numberDiff line change
@@ -7583,3 +7583,43 @@ TEST(X509Test, PublicKeyCache) {
75837583
key2.reset(X509_PUBKEY_get(pub));
75847584
EXPECT_FALSE(key2);
75857585
}
7586+
7587+
TEST(X509Test, SPKIPrint) {
7588+
bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
7589+
ASSERT_TRUE(bio);
7590+
bssl::UniquePtr<NETSCAPE_SPKI> spki(NETSCAPE_SPKI_new());
7591+
ASSERT_TRUE(spki);
7592+
7593+
bssl::UniquePtr<EVP_PKEY> key = PrivateKeyFromPEM(kP256Key);
7594+
EXPECT_TRUE(NETSCAPE_SPKI_set_pubkey(spki.get(), key.get()));
7595+
EXPECT_TRUE(NETSCAPE_SPKI_sign(spki.get(), key.get(), EVP_sha256()));
7596+
7597+
std::string challenge = "challenge string";
7598+
ASSERT_TRUE(ASN1_STRING_set(spki.get()->spkac->challenge, challenge.data(),
7599+
challenge.size()));
7600+
7601+
EXPECT_TRUE(NETSCAPE_SPKI_print(bio.get(), spki.get()));
7602+
7603+
// The contents of the signature is printed last but it's randomized,
7604+
// so we only check the expected output before that.
7605+
static const char expected_certificate_string[] = R"(Netscape SPKI:
7606+
Public Key Algorithm: id-ecPublicKey
7607+
Public-Key: (P-256)
7608+
pub:
7609+
04:e6:2b:69:e2:bf:65:9f:97:be:2f:1e:0d:94:8a:
7610+
4c:d5:97:6b:b7:a9:1e:0d:46:fb:dd:a9:a9:1e:9d:
7611+
dc:ba:5a:01:e7:d6:97:a8:0a:18:f9:c3:c4:a3:1e:
7612+
56:e2:7c:83:48:db:16:1a:1c:f5:1d:7e:f1:94:2d:
7613+
4b:cf:72:22:c1
7614+
Challenge String: challenge string
7615+
Signature Algorithm: ecdsa-with-SHA256
7616+
)";
7617+
7618+
const uint8_t *data;
7619+
size_t data_len;
7620+
ASSERT_TRUE(BIO_mem_contents(bio.get(), &data, &data_len));
7621+
ASSERT_GT(data_len, strlen(expected_certificate_string));
7622+
std::string print(reinterpret_cast<const char *>(data),
7623+
strlen(expected_certificate_string));
7624+
EXPECT_EQ(print, expected_certificate_string);
7625+
}

crypto/x509/x509spki.c

+45
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include <openssl/err.h>
6161
#include <openssl/mem.h>
6262
#include <openssl/x509.h>
63+
#include "internal.h"
6364

6465
int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) {
6566
if ((x == NULL) || (x->spkac == NULL)) {
@@ -131,3 +132,47 @@ char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) {
131132
OPENSSL_free(der_spki);
132133
return b64_str;
133134
}
135+
136+
int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki) {
137+
if (out == NULL || spki == NULL || spki->spkac == NULL ||
138+
spki->spkac->pubkey == NULL || spki->sig_algor == NULL ||
139+
spki->sig_algor->algorithm == NULL || spki->signature == NULL ||
140+
spki->signature->data == NULL) {
141+
OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
142+
return 0;
143+
}
144+
BIO_printf(out, "Netscape SPKI:\n");
145+
146+
// Print out public key algorithm and contents.
147+
ASN1_OBJECT *spkioid;
148+
X509_PUBKEY_get0_param(&spkioid, NULL, NULL, NULL, spki->spkac->pubkey);
149+
int spkioid_nid = OBJ_obj2nid(spkioid);
150+
BIO_printf(out, " Public Key Algorithm: %s\n",
151+
(spkioid_nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(spkioid_nid));
152+
EVP_PKEY *pkey = X509_PUBKEY_get0(spki->spkac->pubkey);
153+
if (pkey == NULL) {
154+
BIO_printf(out, " Unable to load public key\n");
155+
} else {
156+
EVP_PKEY_print_public(out, pkey, 4, NULL);
157+
}
158+
159+
ASN1_IA5STRING *chal = spki->spkac->challenge;
160+
if (chal != NULL && chal->length != 0) {
161+
BIO_printf(out, " Challenge String: %.*s\n", chal->length, chal->data);
162+
}
163+
164+
// Print out signature algorithm and contents.
165+
BIO_printf(out, " Signature Algorithm: %s",
166+
(OBJ_obj2nid(spki->sig_algor->algorithm) == NID_undef)
167+
? "UNKNOWN"
168+
: OBJ_nid2ln(OBJ_obj2nid(spki->sig_algor->algorithm)));
169+
for (int i = 0; i < spki->signature->length; i++) {
170+
if ((i % 18) == 0) {
171+
BIO_printf(out, "\n ");
172+
}
173+
BIO_printf(out, "%02x%s", (unsigned char)spki->signature->data[i],
174+
((i + 1) == spki->signature->length) ? "" : ":");
175+
}
176+
BIO_write(out, "\n", 1);
177+
return 1;
178+
}

include/openssl/x509.h

+3
Original file line numberDiff line numberDiff line change
@@ -2345,6 +2345,9 @@ OPENSSL_EXPORT NETSCAPE_SPKAC *d2i_NETSCAPE_SPKAC(NETSCAPE_SPKAC **out,
23452345
OPENSSL_EXPORT int i2d_NETSCAPE_SPKAC(const NETSCAPE_SPKAC *spkac,
23462346
uint8_t **outp);
23472347

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

23492352
// RSASSA-PSS Parameters.
23502353
//

0 commit comments

Comments
 (0)