Skip to content

Commit bd94d2f

Browse files
committed
wip ocsp any hash
1 parent 27611fa commit bd94d2f

4 files changed

Lines changed: 125 additions & 17 deletions

File tree

scripts/ocsp-responder-openssl-interop.test

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -338,26 +338,29 @@ echo
338338

339339
echo "=== Negative tests: unsupported features ==="
340340

341-
# Test 1: Non-SHA-1 hash algorithms (should fail with OCSP error)
341+
# Test 1: Non-SHA-1 hash algorithms (should be supported)
342342
tests_run=$((tests_run+1))
343-
printf " TEST %2d: %-55s " "$tests_run" "SHA-256 hash (should return OCSP error)"
343+
printf " TEST %2d: %-55s " "$tests_run" "SHA-384 hash -> good"
344344

345345
output=$($OPENSSL ocsp \
346-
-sha256 \
346+
-sha384 \
347347
-issuer "$OCSP_DIR/intermediate1-ca-cert.pem" \
348348
-cert "$OCSP_DIR/server1-cert.pem" \
349349
-url "http://127.0.0.1:$port1/" \
350350
-noverify \
351351
-resp_text 2>&1)
352352
rc=$?
353353

354-
# Expect OCSP error response: internalerror (2)
355-
# OpenSSL shows "Responder Error: internalerror (2)"
356-
if echo "$output" | grep -q "Responder Error: internalerror"; then
357-
printf "PASSED (OCSP internalerror)\n"
354+
# Extract the cert status line
355+
status=$(echo "$output" | grep "Cert Status:" | head -1 | \
356+
sed 's/.*Cert Status: *//')
357+
358+
# Expect "good" status (feature should be supported)
359+
if [ "$status" = "good" ]; then
360+
printf "PASSED (status: %s)\n" "$status"
358361
tests_passed=$((tests_passed+1))
359362
else
360-
printf "FAILED (expected OCSP internalerror, got rc: %d)\n" "$rc"
363+
printf "FAILED (expected: good, got: %s, rc: %d)\n" "$status" "$rc"
361364
tests_failed=$((tests_failed+1))
362365
echo "--- openssl output ---"
363366
echo "$output"

src/ocsp.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,8 +2293,23 @@ int wc_OcspResponder_AddCA(OcspResponder* responder,
22932293

22942294
/* Extract necessary info from decoded cert */
22952295
XMEMCPY(ca->subject, decoded->subject, WC_ASN_NAME_MAX);
2296-
XMEMCPY(ca->issuerHash, decoded->subjectHash, KEYID_SIZE);
2297-
XMEMCPY(ca->issuerKeyHash, decoded->subjectKeyHash, KEYID_SIZE);
2296+
if (decoded->subjectRawForHash == NULL ||
2297+
decoded->subjectRawForHashLen <= 0) {
2298+
ret = BAD_FUNC_ARG;
2299+
goto out;
2300+
}
2301+
ret = AsnHashesHash(&ca->issuerHashes, decoded->subjectRawForHash,
2302+
(word32)decoded->subjectRawForHashLen);
2303+
if (ret != 0)
2304+
goto out;
2305+
if (decoded->publicKeyForHash == NULL || decoded->pubKeyForHashSize == 0) {
2306+
ret = BAD_FUNC_ARG;
2307+
goto out;
2308+
}
2309+
ret = AsnHashesHash(&ca->issuerKeyHash, decoded->publicKeyForHash,
2310+
decoded->pubKeyForHashSize);
2311+
if (ret != 0)
2312+
goto out;
22982313
keyOID = decoded->keyOID;
22992314

23002315
/* Store raw certificate DER if sendCerts is enabled */
@@ -2364,8 +2379,9 @@ static OcspResponderCa* FindCaByHashes(OcspResponder* responder,
23642379
OcspResponderCa* ca = responder->caList;
23652380

23662381
while (ca != NULL) {
2367-
if (XMEMCMP(ca->issuerHash, issuerHash, KEYID_SIZE) == 0 &&
2368-
XMEMCMP(ca->issuerKeyHash, issuerKeyHash, KEYID_SIZE) == 0) {
2382+
/* Compare SHA-1 hashes since that's what OCSP uses */
2383+
if (XMEMCMP(ca->issuerHashes.sha, issuerHash, KEYID_SIZE) == 0 &&
2384+
XMEMCMP(ca->issuerKeyHash.sha, issuerKeyHash, KEYID_SIZE) == 0) {
23692385
return ca;
23702386
}
23712387
ca = ca->next;
@@ -2581,11 +2597,11 @@ static int OcspResponse_WriteResponse(OcspResponder* responder, byte* response,
25812597

25822598
/* Only support sha-1 hashes for now */
25832599
entry.hashAlgoOID = SHAh;
2584-
XMEMCPY(entry.issuerHash, ca->issuerHash, KEYID_SIZE);
2585-
XMEMCPY(entry.issuerKeyHash, ca->issuerKeyHash, KEYID_SIZE);
2600+
XMEMCPY(entry.issuerHash, ca->issuerHashes.sha, KEYID_SIZE);
2601+
XMEMCPY(entry.issuerKeyHash, ca->issuerKeyHash.sha, KEYID_SIZE);
25862602

25872603
resp.responderIdType = OCSP_RESPONDER_ID_KEY;
2588-
XMEMCPY(resp.responderId.keyHash, ca->issuerKeyHash, KEYID_SIZE);
2604+
XMEMCPY(resp.responderId.keyHash, ca->issuerKeyHash.sha, KEYID_SIZE);
25892605

25902606
/* TODO allow user to set algo */
25912607
if (ca->keyType == RSAk) {

wolfcrypt/src/asn.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13068,6 +13068,11 @@ static int StoreKey(DecodedCert* cert, const byte* source, word32* srcIdx,
1306813068
cert->pubKeyStored = 1;
1306913069
cert->pubKeySize = (word32)length;
1307013070

13071+
#ifdef HAVE_OCSP_RESPONDER
13072+
cert->publicKeyForHash = cert->publicKey;
13073+
cert->pubKeyForHashSize = cert->pubKeySize;
13074+
#endif
13075+
1307113076
*srcIdx += (word32)length;
1307213077
}
1307313078
}
@@ -13698,6 +13703,10 @@ static int StoreRsaKey(DecodedCert* cert, const byte* source, word32* srcIdx,
1369813703
cert->sigCtx.CertAtt.pubkey_n_start =
1369913704
cert->sigCtx.CertAtt.pubkey_e_start = dataASN[RSACERTKEYASN_IDX_SEQ].offset;
1370013705
#endif
13706+
#ifdef HAVE_OCSP_RESPONDER
13707+
cert->publicKeyForHash = cert->publicKey;
13708+
cert->pubKeyForHashSize = cert->pubKeySize;
13709+
#endif
1370113710
#ifdef HAVE_OCSP
1370213711
/* Calculate the hash of the public key for OCSP. */
1370313712
ret = CalcHashId_ex(cert->publicKey, cert->pubKeySize,
@@ -13877,6 +13886,13 @@ static int StoreEccKey(DecodedCert* cert, const byte* source, word32* srcIdx,
1387713886
+ 1;
1387813887
#endif
1387913888

13889+
#ifdef HAVE_OCSP_RESPONDER
13890+
cert->publicKeyForHash =
13891+
dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.data;
13892+
cert->pubKeyForHashSize =
13893+
dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.length;
13894+
#endif
13895+
1388013896
#ifdef HAVE_OCSP
1388113897
if (ret == 0) {
1388213898
/* Calculate the hash of the subject public key for OCSP. */
@@ -16042,6 +16058,13 @@ static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType,
1604216058
ret = ASN_PARSE_E;
1604316059
}
1604416060

16061+
#ifdef HAVE_OCSP_RESPONDER
16062+
if (ret == 0 && nameType == ASN_SUBJECT) {
16063+
cert->subjectRawForHash = input + srcIdx;
16064+
cert->subjectRawForHashLen = maxIdx - srcIdx;
16065+
}
16066+
#endif
16067+
1604516068
CALLOC_ASNGETDATA(dataASN, rdnASN_Length, ret, cert->heap);
1604616069

1604716070
#ifdef WOLFSSL_X509_NAME_AVAILABLE
@@ -45596,6 +45619,40 @@ int wc_VerifyX509Acert(const byte* acert, word32 acertSz,
4559645619

4559745620
#endif /* WOLFSSL_ACERT && WOLFSSL_ASN_TEMPLATE */
4559845621

45622+
int AsnHashesHash(AsnHashes* hashes, const byte* data, word32 dataSz)
45623+
{
45624+
int ret = 0;
45625+
45626+
if (hashes == NULL || data == NULL)
45627+
ret = BAD_FUNC_ARG;
45628+
#if !defined(NO_MD5)
45629+
if (ret == 0)
45630+
ret = wc_Md5Hash(data, dataSz, hashes->md5);
45631+
#endif
45632+
#if !defined(NO_SHA)
45633+
if (ret == 0)
45634+
ret = wc_ShaHash(data, dataSz, hashes->sha);
45635+
#endif
45636+
#ifndef NO_SHA256
45637+
if (ret == 0)
45638+
ret = wc_Sha256Hash(data, dataSz, hashes->sha256);
45639+
#endif
45640+
#ifdef WOLFSSL_SHA384
45641+
if (ret == 0)
45642+
ret = wc_Sha384Hash(data, dataSz, hashes->sha384);
45643+
#endif
45644+
#ifdef WOLFSSL_SHA512
45645+
if (ret == 0)
45646+
ret = wc_Sha512Hash(data, dataSz, hashes->sha512);
45647+
#endif
45648+
#ifdef WOLFSSL_SM3
45649+
if (ret == 0)
45650+
ret = wc_Sm3Hash(data, dataSz, hashes->sm3);
45651+
#endif
45652+
45653+
return ret;
45654+
}
45655+
4559945656
#ifdef WOLFSSL_SEP
4560045657

4560145658

wolfssl/wolfcrypt/asn.h

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,6 +1728,10 @@ typedef int (*wc_UnknownExtCallbackEx)(const word16* oid, word32 oidSz,
17281728
struct DecodedCert {
17291729
const byte* publicKey;
17301730
word32 pubKeySize;
1731+
#ifdef HAVE_OCSP_RESPONDER
1732+
const byte* publicKeyForHash;
1733+
word32 pubKeyForHashSize;
1734+
#endif
17311735
int pubKeyStored;
17321736
word32 certBegin; /* offset to start of cert */
17331737
word32 sigIndex; /* offset to start of signature */
@@ -1848,6 +1852,10 @@ struct DecodedCert {
18481852
const byte* issuerRaw; /* pointer to issuer inside source */
18491853
int issuerRawLen;
18501854
#endif
1855+
#ifdef HAVE_OCSP_RESPONDER
1856+
const byte* subjectRawForHash; /* pointer to subject including tags */
1857+
int subjectRawForHashLen;
1858+
#endif
18511859
#if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
18521860
const byte* subjectRaw; /* pointer to subject inside source */
18531861
int subjectRawLen;
@@ -2865,6 +2873,30 @@ struct OcspResponderCertStatus {
28652873
OcspResponderCertStatus* next;
28662874
};
28672875

2876+
/* hashes type for asn */
2877+
typedef struct AsnHashes {
2878+
#if !defined(NO_MD5)
2879+
byte md5[WC_MD5_DIGEST_SIZE];
2880+
#endif
2881+
#if !defined(NO_SHA)
2882+
byte sha[WC_SHA_DIGEST_SIZE];
2883+
#endif
2884+
#ifndef NO_SHA256
2885+
byte sha256[WC_SHA256_DIGEST_SIZE];
2886+
#endif
2887+
#ifdef WOLFSSL_SHA384
2888+
byte sha384[WC_SHA384_DIGEST_SIZE];
2889+
#endif
2890+
#ifdef WOLFSSL_SHA512
2891+
byte sha512[WC_SHA512_DIGEST_SIZE];
2892+
#endif
2893+
#ifdef WOLFSSL_SM3
2894+
byte sm3[WC_SM3_DIGEST_SIZE];
2895+
#endif
2896+
} AsnHashes;
2897+
2898+
WOLFSSL_LOCAL int AsnHashesHash(AsnHashes* hashes, const byte* data, word32 dataSz);
2899+
28682900
/* CA entry with its certificates and key */
28692901
typedef struct OcspResponderCa OcspResponderCa;
28702902
struct OcspResponderCa {
@@ -2880,8 +2912,8 @@ struct OcspResponderCa {
28802912
} key; /* CA private key for signing */
28812913
enum Key_Sum keyType; /* Type of key */
28822914

2883-
byte issuerHash[KEYID_SIZE]; /* Hash of CA's subject DN */
2884-
byte issuerKeyHash[KEYID_SIZE]; /* Hash of CA's public key */
2915+
AsnHashes issuerHashes; /* Hashes of CA's subject DN */
2916+
AsnHashes issuerKeyHash; /* Hashes of CA's public key */
28852917

28862918
byte* certDer; /* Raw DER certificate (if sendCerts enabled) */
28872919
word32 certDerSz; /* Size of certificate DER */

0 commit comments

Comments
 (0)