2 * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright Siemens AG 2018-2020
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or atf
8 * https://www.openssl.org/source/license.html
12 #include "cmp_mock_srv.h"
14 #include <openssl/cmp.h>
15 #include <openssl/err.h>
16 #include <openssl/cmperr.h>
18 /* the context for the CMP mock server */
21 X509
*certOut
; /* certificate to be returned in cp/ip/kup msg */
22 STACK_OF(X509
) *chainOut
; /* chain of certOut to add to extraCerts field */
23 STACK_OF(X509
) *caPubsOut
; /* certs to return in caPubs field of ip msg */
24 OSSL_CMP_PKISI
*statusOut
; /* status for ip/cp/kup/rp msg unless polling */
25 int sendError
; /* send error response also on valid requests */
26 OSSL_CMP_MSG
*certReq
; /* ir/cr/p10cr/kur remembered while polling */
27 int certReqId
; /* id of last ir/cr/kur, used for polling */
28 int pollCount
; /* number of polls before actual cert response */
29 int checkAfterTime
; /* time the client should wait between polling */
33 static void mock_srv_ctx_free(mock_srv_ctx
*ctx
)
38 OSSL_CMP_PKISI_free(ctx
->statusOut
);
39 X509_free(ctx
->certOut
);
40 sk_X509_pop_free(ctx
->chainOut
, X509_free
);
41 sk_X509_pop_free(ctx
->caPubsOut
, X509_free
);
42 OSSL_CMP_MSG_free(ctx
->certReq
);
46 static mock_srv_ctx
*mock_srv_ctx_new(void)
48 mock_srv_ctx
*ctx
= OPENSSL_zalloc(sizeof(mock_srv_ctx
));
53 if ((ctx
->statusOut
= OSSL_CMP_PKISI_new()) == NULL
)
58 /* all other elements are initialized to 0 or NULL, respectively */
61 mock_srv_ctx_free(ctx
);
65 int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX
*srv_ctx
, X509
*cert
)
67 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
70 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
73 if (cert
== NULL
|| X509_up_ref(cert
)) {
74 X509_free(ctx
->certOut
);
81 int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX
*srv_ctx
,
82 STACK_OF(X509
) *chain
)
84 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
85 STACK_OF(X509
) *chain_copy
= NULL
;
88 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
91 if (chain
!= NULL
&& (chain_copy
= X509_chain_up_ref(chain
)) == NULL
)
93 sk_X509_pop_free(ctx
->chainOut
, X509_free
);
94 ctx
->chainOut
= chain_copy
;
98 int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX
*srv_ctx
,
99 STACK_OF(X509
) *caPubs
)
101 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
102 STACK_OF(X509
) *caPubs_copy
= NULL
;
105 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
108 if (caPubs
!= NULL
&& (caPubs_copy
= X509_chain_up_ref(caPubs
)) == NULL
)
110 sk_X509_pop_free(ctx
->caPubsOut
, X509_free
);
111 ctx
->caPubsOut
= caPubs_copy
;
115 int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX
*srv_ctx
, int status
,
116 int fail_info
, const char *text
)
118 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
122 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
125 if ((si
= OSSL_CMP_STATUSINFO_new(status
, fail_info
, text
)) == NULL
)
127 OSSL_CMP_PKISI_free(ctx
->statusOut
);
132 int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX
*srv_ctx
, int val
)
134 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
137 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
140 ctx
->sendError
= val
!= 0;
144 int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX
*srv_ctx
, int count
)
146 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
149 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
153 ERR_raise(ERR_LIB_CMP
, CMP_R_INVALID_ARGS
);
156 ctx
->pollCount
= count
;
160 int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX
*srv_ctx
, int sec
)
162 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
165 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
168 ctx
->checkAfterTime
= sec
;
172 static OSSL_CMP_PKISI
*process_cert_request(OSSL_CMP_SRV_CTX
*srv_ctx
,
173 const OSSL_CMP_MSG
*cert_req
,
175 const OSSL_CRMF_MSG
*crm
,
176 const X509_REQ
*p10cr
,
178 STACK_OF(X509
) **chainOut
,
179 STACK_OF(X509
) **caPubs
)
181 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
182 OSSL_CMP_PKISI
*si
= NULL
;
184 if (ctx
== NULL
|| cert_req
== NULL
185 || certOut
== NULL
|| chainOut
== NULL
|| caPubs
== NULL
) {
186 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
189 if (ctx
->sendError
) {
190 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_PROCESSING_MESSAGE
);
197 ctx
->certReqId
= certReqId
;
198 if (ctx
->pollCount
> 0) {
200 OSSL_CMP_MSG_free(ctx
->certReq
);
201 if ((ctx
->certReq
= OSSL_CMP_MSG_dup(cert_req
)) == NULL
)
203 return OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting
, 0, NULL
);
205 if (ctx
->certOut
!= NULL
206 && (*certOut
= X509_dup(ctx
->certOut
)) == NULL
)
208 if (ctx
->chainOut
!= NULL
209 && (*chainOut
= X509_chain_up_ref(ctx
->chainOut
)) == NULL
)
211 if (ctx
->caPubsOut
!= NULL
212 && (*caPubs
= X509_chain_up_ref(ctx
->caPubsOut
)) == NULL
)
214 if (ctx
->statusOut
!= NULL
215 && (si
= OSSL_CMP_PKISI_dup(ctx
->statusOut
)) == NULL
)
222 sk_X509_pop_free(*chainOut
, X509_free
);
224 sk_X509_pop_free(*caPubs
, X509_free
);
229 static OSSL_CMP_PKISI
*process_rr(OSSL_CMP_SRV_CTX
*srv_ctx
,
230 const OSSL_CMP_MSG
*rr
,
231 const X509_NAME
*issuer
,
232 const ASN1_INTEGER
*serial
)
234 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
236 if (ctx
== NULL
|| rr
== NULL
) {
237 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
240 if (ctx
->sendError
|| ctx
->certOut
== NULL
) {
241 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_PROCESSING_MESSAGE
);
245 /* Allow any RR derived from CSR, which may include subject and serial */
246 if (issuer
== NULL
|| serial
== NULL
)
247 return OSSL_CMP_PKISI_dup(ctx
->statusOut
);
249 /* accept revocation only for the certificate we sent in ir/cr/kur */
250 if (X509_NAME_cmp(issuer
, X509_get_issuer_name(ctx
->certOut
)) != 0
251 || ASN1_INTEGER_cmp(serial
,
252 X509_get0_serialNumber(ctx
->certOut
)) != 0) {
253 ERR_raise_data(ERR_LIB_CMP
, CMP_R_REQUEST_NOT_ACCEPTED
,
254 "wrong certificate to revoke");
257 return OSSL_CMP_PKISI_dup(ctx
->statusOut
);
260 static int process_genm(OSSL_CMP_SRV_CTX
*srv_ctx
,
261 const OSSL_CMP_MSG
*genm
,
262 const STACK_OF(OSSL_CMP_ITAV
) *in
,
263 STACK_OF(OSSL_CMP_ITAV
) **out
)
265 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
267 if (ctx
== NULL
|| genm
== NULL
|| in
== NULL
|| out
== NULL
) {
268 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
271 if (ctx
->sendError
) {
272 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_PROCESSING_MESSAGE
);
276 *out
= sk_OSSL_CMP_ITAV_deep_copy(in
, OSSL_CMP_ITAV_dup
,
281 static void process_error(OSSL_CMP_SRV_CTX
*srv_ctx
, const OSSL_CMP_MSG
*error
,
282 const OSSL_CMP_PKISI
*statusInfo
,
283 const ASN1_INTEGER
*errorCode
,
284 const OSSL_CMP_PKIFREETEXT
*errorDetails
)
286 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
287 char buf
[OSSL_CMP_PKISI_BUFLEN
];
291 if (ctx
== NULL
|| error
== NULL
) {
292 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
296 BIO_printf(bio_err
, "mock server received error:\n");
298 if (statusInfo
== NULL
) {
299 BIO_printf(bio_err
, "pkiStatusInfo absent\n");
301 sibuf
= OSSL_CMP_snprint_PKIStatusInfo(statusInfo
, buf
, sizeof(buf
));
302 BIO_printf(bio_err
, "pkiStatusInfo: %s\n",
303 sibuf
!= NULL
? sibuf
: "<invalid>");
306 if (errorCode
== NULL
)
307 BIO_printf(bio_err
, "errorCode absent\n");
309 BIO_printf(bio_err
, "errorCode: %ld\n", ASN1_INTEGER_get(errorCode
));
311 if (sk_ASN1_UTF8STRING_num(errorDetails
) <= 0) {
312 BIO_printf(bio_err
, "errorDetails absent\n");
314 BIO_printf(bio_err
, "errorDetails: ");
315 for (i
= 0; i
< sk_ASN1_UTF8STRING_num(errorDetails
); i
++) {
317 BIO_printf(bio_err
, ", ");
318 BIO_printf(bio_err
, "\"");
319 ASN1_STRING_print(bio_err
,
320 sk_ASN1_UTF8STRING_value(errorDetails
, i
));
321 BIO_printf(bio_err
, "\"");
323 BIO_printf(bio_err
, "\n");
327 static int process_certConf(OSSL_CMP_SRV_CTX
*srv_ctx
,
328 const OSSL_CMP_MSG
*certConf
, int certReqId
,
329 const ASN1_OCTET_STRING
*certHash
,
330 const OSSL_CMP_PKISI
*si
)
332 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
333 ASN1_OCTET_STRING
*digest
;
335 if (ctx
== NULL
|| certConf
== NULL
|| certHash
== NULL
) {
336 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
339 if (ctx
->sendError
|| ctx
->certOut
== NULL
) {
340 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_PROCESSING_MESSAGE
);
344 if (certReqId
!= ctx
->certReqId
) {
345 /* in case of error, invalid reqId -1 */
346 ERR_raise(ERR_LIB_CMP
, CMP_R_BAD_REQUEST_ID
);
350 if ((digest
= X509_digest_sig(ctx
->certOut
)) == NULL
)
352 if (ASN1_OCTET_STRING_cmp(certHash
, digest
) != 0) {
353 ASN1_OCTET_STRING_free(digest
);
354 ERR_raise(ERR_LIB_CMP
, CMP_R_CERTHASH_UNMATCHED
);
357 ASN1_OCTET_STRING_free(digest
);
361 static int process_pollReq(OSSL_CMP_SRV_CTX
*srv_ctx
,
362 const OSSL_CMP_MSG
*pollReq
, int certReqId
,
363 OSSL_CMP_MSG
**certReq
, int64_t *check_after
)
365 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
367 if (ctx
== NULL
|| pollReq
== NULL
368 || certReq
== NULL
|| check_after
== NULL
) {
369 ERR_raise(ERR_LIB_CMP
, CMP_R_NULL_ARGUMENT
);
372 if (ctx
->sendError
|| ctx
->certReq
== NULL
) {
374 ERR_raise(ERR_LIB_CMP
, CMP_R_ERROR_PROCESSING_MESSAGE
);
378 if (ctx
->pollCount
== 0) {
379 *certReq
= ctx
->certReq
;
385 *check_after
= ctx
->checkAfterTime
;
390 OSSL_CMP_SRV_CTX
*ossl_cmp_mock_srv_new(OSSL_LIB_CTX
*libctx
, const char *propq
)
392 OSSL_CMP_SRV_CTX
*srv_ctx
= OSSL_CMP_SRV_CTX_new(libctx
, propq
);
393 mock_srv_ctx
*ctx
= mock_srv_ctx_new();
395 if (srv_ctx
!= NULL
&& ctx
!= NULL
396 && OSSL_CMP_SRV_CTX_init(srv_ctx
, ctx
, process_cert_request
,
397 process_rr
, process_genm
, process_error
,
398 process_certConf
, process_pollReq
))
401 mock_srv_ctx_free(ctx
);
402 OSSL_CMP_SRV_CTX_free(srv_ctx
);
406 void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX
*srv_ctx
)
409 mock_srv_ctx_free(OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
));
410 OSSL_CMP_SRV_CTX_free(srv_ctx
);