Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add kem support #4

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b1f866a
cmp_local.h: add declaration for OSSL_CMP_KEMCIPHERTEXTINFO
rajeev-0 Jul 18, 2023
71b9b35
TODO! server_withkem.cnf, test_withserverkem.cnf: added for testing
rajeev-0 Aug 22, 2023
3974259
libcrypto.num: add CMP APIs
rajeev-0 Jul 20, 2023
5de3e13
server_kem.crt: add server cert with keyusage=keyEncipherment
rajeev-0 Aug 23, 2023
0a32ca5
test_credentials.csv: add test with kem cert
rajeev-0 Aug 23, 2023
19b5539
cmp_{asn.c, kem.c, local.h}: move ossl_cmp_kem_KemOtherInfo_new() fro…
rajeev-0 Sep 8, 2023
9545e41
cmp_mock_srv.c: add TODO for verifying client Kem certificate.
rajeev-0 Sep 8, 2023
181afc4
cmp_ctx.c: add TODO to generalize KEM default parameter
rajeev-0 Sep 8, 2023
191ed08
cmp_ctx.c: add helper function to set octet secret in ctx.
rajeev-0 Sep 8, 2023
367bcf5
cmp_{ctx.c,local.h}: remove ossl_cmp_ctx_get0_transactionID()
rajeev-0 Sep 8, 2023
b072001
cmp_{ctx.c, local.h}: update kem variable name
rajeev-0 Sep 8, 2023
77fd2df
cmp_client.c: update kem variable name
rajeev-0 Sep 8, 2023
43f7b08
cmp_kem.c: update kem variable name
rajeev-0 Sep 8, 2023
3b53f3b
cmp_protect.c: update kem variable name
rajeev-0 Sep 8, 2023
464079e
cmp_server.c: update kem variable name
rajeev-0 Sep 8, 2023
ba6dcd5
cmp_kem.c: fix return in case of error
rajeev-0 Sep 14, 2023
8f53865
cmp_kem.c: remove RSA kem code from cmp_kem.c
rajeev-0 Sep 22, 2023
58b8b0f
cmp_{kemrsa.c, local.h}: add rsa kem and kdf2 implementation
rajeev-0 Sep 22, 2023
0a56fe6
build.info: add file cmp_kemrsa.c
rajeev-0 Sep 22, 2023
a00cf23
cmp_kem.c: updated to support KEM from oqsprovider
rajeev-0 Jan 4, 2024
7587a73
kem_{RSA,kyber512}.{crt,key}: add RSA and kyber512 cert and key for K…
rajeev-0 Jan 5, 2024
43e4703
cmp_{util.c, local.h}: add function ossl_cmp_x509_algor_set0
rajeev-0 Jan 6, 2024
e090035
cmp_asn.c: fix memory leak
rajeev-0 Jan 6, 2024
8e9151d
cmp_kem.c: fix memory leak
rajeev-0 Jan 6, 2024
36505aa
cmp_kemrsa.c: fix memory leak
rajeev-0 Jan 6, 2024
4b14d3d
to be removed, cmp_kem.c:add debug message
rajeev-0 Jan 11, 2024
ed6fb45
kem_kyber1024.{crt, priv, pub}: add kyber1024 key and certificate for…
rajeev-0 Jan 11, 2024
28bc2b3
update structure as per updated RFC
rajeev-0 Mar 18, 2024
b219a7d
Update kem.crt certificate
rajeev-0 Mar 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions apps/lib/cmp_mock_srv.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,10 +391,31 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
return OSSL_CMP_PKISI_dup(ctx->statusOut);
}

static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid,
const OSSL_CMP_ITAV *req)
/* TODO: extend it to check for certificate with KEM key (PQ keys) */
static X509 *extracert_withKEM(STACK_OF(X509) *certs)
{
OSSL_CMP_ITAV *rsp;
int i;

if (certs == NULL)
return NULL;

for (i = 0; i < sk_X509_num(certs); i++) {
X509 *cert = sk_X509_value(certs, i);

if ((X509_get_key_usage(cert) & X509v3_KU_KEY_ENCIPHERMENT)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taking the key usage can easily go wrong - maybe for RSA keys there is not much better choice,
but at least add a TODO for other key types (such as PQ keys) that checking the key type (as far as makes sense) needs to be preferrred.

return cert;
}
}
return NULL;
}

static OSSL_CMP_ITAV *process_genm_itav(OSSL_CMP_SRV_CTX *srv_ctx,
int req_nid,
const OSSL_CMP_ITAV *req,
const OSSL_CMP_MSG *genm)
{
OSSL_CMP_ITAV *rsp = NULL;
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);

switch (req_nid) {
case NID_id_it_caCerts:
Expand All @@ -405,6 +426,18 @@ static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid,
ctx->newWithOld,
ctx->oldWithNew);
break;
case NID_id_it_KemCiphertextInfo:
if (OSSL_CMP_ITAV_get0_value(req) == NULL) {
X509 *kemcert;

/* TODO: add certificate path validation */
kemcert = extracert_withKEM(OSSL_CMP_MSG_get_extraCerts(genm));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to determine if the sender side uses a KEM cert this way can go wrong.
You should instead use OSSL_CMP_CTX_get0_validatedSrvCert() at least on the client side -
despite its original intention and documentation, I hope to works on the server side, too.
Then you can remove again the new genm parameter.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it is not the best way and also certificate validation need to be performed ( will add TODO).
In case of client side having KEM cert, first genm message is without protection with extracert, So it does not populate validatedSevCert.
In case of server having KEM cert, it is assumed client already have valid server cert (in this implementation).

if (kemcert == NULL)
break;
rsp = OSSL_CMP_SRV_kem_get_ss(srv_ctx, X509_get0_pubkey(kemcert));
break;
}
/* fall through */
default:
rsp = OSSL_CMP_ITAV_dup(req);
}
Expand Down Expand Up @@ -434,7 +467,7 @@ static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,

if ((*out = sk_OSSL_CMP_ITAV_new_reserve(NULL, 1)) == NULL)
return 0;
rsp = process_genm_itav(ctx, OBJ_obj2nid(obj), req);
rsp = process_genm_itav(srv_ctx, OBJ_obj2nid(obj), req, genm);
if (rsp != NULL && sk_OSSL_CMP_ITAV_push(*out, rsp))
return 1;
sk_OSSL_CMP_ITAV_free(*out);
Expand Down
2 changes: 1 addition & 1 deletion crypto/cmp/build.info
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ LIBS=../../libcrypto
$OPENSSLSRC=\
cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \
cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c \
cmp_server.c cmp_client.c cmp_genm.c
cmp_server.c cmp_client.c cmp_genm.c cmp_kem.c cmp_kemrsa.c

IF[{- !$disabled{'http'} -}]
$OPENSSLSRC=$OPENSSLSRC cmp_http.c
Expand Down
100 changes: 99 additions & 1 deletion crypto/cmp/cmp_asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,33 @@ ASN1_SEQUENCE(OSSL_CMP_CAKEYUPDANNCONTENT) = {
} ASN1_SEQUENCE_END(OSSL_CMP_CAKEYUPDANNCONTENT)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CAKEYUPDANNCONTENT)

ASN1_SEQUENCE(OSSL_CMP_RSAKEMPARAMETERS) = {
ASN1_SIMPLE(OSSL_CMP_RSAKEMPARAMETERS, KeyDerivationFunction, X509_ALGOR),
ASN1_SIMPLE(OSSL_CMP_RSAKEMPARAMETERS, KeyLength, ASN1_INTEGER)
} ASN1_SEQUENCE_END(OSSL_CMP_RSAKEMPARAMETERS)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_RSAKEMPARAMETERS)
Comment on lines +58 to +62
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think. this is entirely independent of CMP and should go into some more general OpenSSL source file.


ASN1_SEQUENCE(OSSL_CMP_KEMCIPHERTEXTINFO) = {
ASN1_SIMPLE(OSSL_CMP_KEMCIPHERTEXTINFO, kem, X509_ALGOR),
ASN1_SIMPLE(OSSL_CMP_KEMCIPHERTEXTINFO, ct, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(OSSL_CMP_KEMCIPHERTEXTINFO)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_KEMCIPHERTEXTINFO)

ASN1_SEQUENCE(OSSL_CMP_KEMOTHERINFO) = {
ASN1_SEQUENCE_OF(OSSL_CMP_KEMOTHERINFO, staticString, ASN1_UTF8STRING),
ASN1_SIMPLE(OSSL_CMP_KEMOTHERINFO, transactionID, ASN1_OCTET_STRING),
ASN1_EXP_OPT(OSSL_CMP_KEMOTHERINFO, kemContext, ASN1_OCTET_STRING, 0),
} ASN1_SEQUENCE_END(OSSL_CMP_KEMOTHERINFO)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_KEMOTHERINFO)

ASN1_SEQUENCE(OSSL_CMP_KEMBMPARAMETER) = {
ASN1_SIMPLE(OSSL_CMP_KEMBMPARAMETER, kdf, X509_ALGOR),
ASN1_EXP_OPT(OSSL_CMP_KEMBMPARAMETER, kemContext, ASN1_OCTET_STRING, 0),
ASN1_SIMPLE(OSSL_CMP_KEMBMPARAMETER, len, ASN1_INTEGER),
ASN1_SIMPLE(OSSL_CMP_KEMBMPARAMETER, mac, X509_ALGOR)
} ASN1_SEQUENCE_END(OSSL_CMP_KEMBMPARAMETER)
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_KEMBMPARAMETER)

ASN1_SEQUENCE(OSSL_CMP_ERRORMSGCONTENT) = {
ASN1_SIMPLE(OSSL_CMP_ERRORMSGCONTENT, pKIStatusInfo, OSSL_CMP_PKISI),
ASN1_OPT(OSSL_CMP_ERRORMSGCONTENT, errorCode, ASN1_INTEGER),
Expand Down Expand Up @@ -120,6 +147,9 @@ ASN1_ADB(OSSL_CMP_ITAV) = {
ADB_ENTRY(NID_id_it_certProfile,
ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, infoValue.certProfile,
ASN1_UTF8STRING)),
ADB_ENTRY(NID_id_it_KemCiphertextInfo,
ASN1_OPT(OSSL_CMP_ITAV, infoValue.KemCiphertextInfoValue,
OSSL_CMP_KEMCIPHERTEXTINFO)),
} ASN1_ADB_END(OSSL_CMP_ITAV, 0, infoType, 0,
&infotypeandvalue_default_tt, NULL);

Expand Down Expand Up @@ -223,6 +253,74 @@ int OSSL_CMP_ITAV_get0_certProfile(const OSSL_CMP_ITAV *itav,
return 1;
}

OSSL_CMP_ITAV *ossl_cmp_itav_new_KemCiphertext(X509_ALGOR *kem,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency, either move definitions of similar constructors such as ossl_cmp_kem_KemOtherInfo_new() (and any selector functions) from cmp_kem.c here (preferred) or move also this definition to cmp_kem.c.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved definition of ossl_cmp_kem_KemOtherInfo_new( ) to cmp_asn.c

unsigned char *in_ct,
int len)
{
OSSL_CMP_ITAV *itav = NULL;
OSSL_CMP_KEMCIPHERTEXTINFO *KemCtInfoValue;

if (kem == NULL || in_ct == NULL)
return NULL;

if ((KemCtInfoValue = OSSL_CMP_KEMCIPHERTEXTINFO_new()) == NULL
|| !ossl_cmp_x509_algor_set0(&KemCtInfoValue->kem, kem)
|| !ossl_cmp_asn1_octet_string_set1_bytes(&KemCtInfoValue->ct,
in_ct, len))
goto err;

if ((itav = OSSL_CMP_ITAV_new()) == NULL)
goto err;

itav->infoType = OBJ_nid2obj(NID_id_it_KemCiphertextInfo);
itav->infoValue.KemCiphertextInfoValue = KemCtInfoValue;

return itav;

err:
OSSL_CMP_KEMCIPHERTEXTINFO_free(KemCtInfoValue);
OSSL_CMP_ITAV_free(itav);
return NULL;
}

#define KEMCMP_STATICSTRING "CMP-KEM"
int ossl_cmp_kem_KemOtherInfo_new(OSSL_CMP_CTX *ctx,
unsigned char **out, int *len)
{
int ret = 0;
OSSL_CMP_KEMOTHERINFO *kemOtherInfo;

if (out == NULL || len == NULL)
return 0;

if ((kemOtherInfo = OSSL_CMP_KEMOTHERINFO_new()) == NULL)
return 0;

if (!ossl_cmp_sk_ASN1_UTF8STRING_push_str(kemOtherInfo->staticString,
KEMCMP_STATICSTRING, -1))
goto err;

kemOtherInfo->transactionID = ctx->transactionID;

#if 0
/*setting kemContext with ct for testing*/
if (ctx->kem_ct != NULL
&& !ossl_cmp_asn1_octet_string_set1(&kemOtherInfo->kemContext,
ctx->kem_ct))
goto err;
#endif
*out = NULL;
if ((*len = i2d_OSSL_CMP_KEMOTHERINFO(kemOtherInfo, out)) <= 0)
goto err;

ret = 1;

err:
kemOtherInfo->transactionID = NULL;
OSSL_CMP_KEMOTHERINFO_free(kemOtherInfo);
return ret;
}

OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts)
{
OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_new();
Expand Down Expand Up @@ -303,7 +401,7 @@ OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaKeyUpdate(const X509 *newWithNew,
itav->infoValue.rootCaKeyUpdate = upd;
return itav;

err:
err:
OSSL_CMP_ROOTCAKEYUPDATE_free(upd);
return NULL;
}
Expand Down
29 changes: 29 additions & 0 deletions crypto/cmp/cmp_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ static int unprotected_exception(const OSSL_CMP_CTX *ctx,
if (!ossl_assert(ctx != NULL && rep != NULL))
return -1;

/* unprotected response with cipher text */
if (rcvd_type == OSSL_CMP_PKIBODY_GENP
&& ctx->kem_status == KBM_SSK_USING_CLIENT_KEM_KEY
&& sk_OSSL_CMP_ITAV_num(rep->body->value.genm) == 1) {
OSSL_CMP_ITAV *req_itav = sk_OSSL_CMP_ITAV_value(rep->body->value.genm,
0);
ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(req_itav);

if (OBJ_obj2nid(obj) == NID_id_it_KemCiphertextInfo
&& OSSL_CMP_ITAV_get0_value(req_itav) != NULL)
return 1;
}

if (!ctx->unprotectedErrors)
return 0;

Expand Down Expand Up @@ -865,11 +878,20 @@ X509 *OSSL_CMP_exec_certreq(OSSL_CMP_CTX *ctx, int req_type,
int rid = is_p10 ? OSSL_CMP_CERTREQID_NONE : OSSL_CMP_CERTREQID;
int rep_type = is_p10 ? OSSL_CMP_PKIBODY_CP : req_type + 1;
X509 *result = NULL;
int kembasedmac;

if (ctx == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return NULL;
}
kembasedmac = ossl_cmp_kem_BasedMac_required(ctx);
if (kembasedmac == -1) {
goto err;
} else if (kembasedmac == 1
&& ctx->kem_status == KBM_SSK_USING_CLIENT_KEM_KEY) {
if (!OSSL_CMP_get_ssk(ctx))
goto err;
}

if (!initial_certreq(ctx, req_type, crm, &rep, rep_type))
goto err;
Expand Down Expand Up @@ -1045,6 +1067,13 @@ STACK_OF(OSSL_CMP_ITAV) *OSSL_CMP_exec_GENM_ses(OSSL_CMP_CTX *ctx)
/* received stack of itavs not to be freed with the genp */
genp->body->value.genp = NULL;

if (ctx->kem_status == KBM_SSK_USING_CLIENT_KEM_KEY
&& genp->header != NULL) {
ossl_cmp_ctx_set1_kem_senderNonce(ctx,
genp->header->senderNonce);
ossl_cmp_ctx_set1_kem_recipNonce(ctx,
genp->header->recipNonce);
}
err:
OSSL_CMP_MSG_free(genm);
OSSL_CMP_MSG_free(genp);
Expand Down
Loading
Loading