2 * Copyright 2018-2020 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>
19 DEFINE_STACK_OF(OSSL_CMP_ITAV
)
20 DEFINE_STACK_OF(ASN1_UTF8STRING
)
22 /* the context for the CMP mock server */
25 X509
*certOut
; /* certificate to be returned in cp/ip/kup msg */
26 STACK_OF(X509
) *chainOut
; /* chain of certOut to add to extraCerts field */
27 STACK_OF(X509
) *caPubsOut
; /* certs to return in caPubs field of ip msg */
28 OSSL_CMP_PKISI
*statusOut
; /* status for ip/cp/kup/rp msg unless polling */
29 int sendError
; /* send error response also on valid requests */
30 OSSL_CMP_MSG
*certReq
; /* ir/cr/p10cr/kur remembered while polling */
31 int certReqId
; /* id of last ir/cr/kur, used for polling */
32 int pollCount
; /* number of polls before actual cert response */
33 int checkAfterTime
; /* time the client should wait between polling */
37 static void mock_srv_ctx_free(mock_srv_ctx
*ctx
)
42 OSSL_CMP_PKISI_free(ctx
->statusOut
);
43 X509_free(ctx
->certOut
);
44 sk_X509_pop_free(ctx
->chainOut
, X509_free
);
45 sk_X509_pop_free(ctx
->caPubsOut
, X509_free
);
46 OSSL_CMP_MSG_free(ctx
->certReq
);
50 static mock_srv_ctx
*mock_srv_ctx_new(void)
52 mock_srv_ctx
*ctx
= OPENSSL_zalloc(sizeof(mock_srv_ctx
));
57 if ((ctx
->statusOut
= OSSL_CMP_PKISI_new()) == NULL
)
62 /* all other elements are initialized to 0 or NULL, respectively */
65 mock_srv_ctx_free(ctx
);
69 int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX
*srv_ctx
, X509
*cert
)
71 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
74 CMPerr(0, CMP_R_NULL_ARGUMENT
);
77 if (cert
== NULL
|| X509_up_ref(cert
)) {
78 X509_free(ctx
->certOut
);
85 int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX
*srv_ctx
,
86 STACK_OF(X509
) *chain
)
88 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
89 STACK_OF(X509
) *chain_copy
= NULL
;
92 CMPerr(0, CMP_R_NULL_ARGUMENT
);
95 if (chain
!= NULL
&& (chain_copy
= X509_chain_up_ref(chain
)) == NULL
)
97 sk_X509_pop_free(ctx
->chainOut
, X509_free
);
98 ctx
->chainOut
= chain_copy
;
102 int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX
*srv_ctx
,
103 STACK_OF(X509
) *caPubs
)
105 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
106 STACK_OF(X509
) *caPubs_copy
= NULL
;
109 CMPerr(0, CMP_R_NULL_ARGUMENT
);
112 if (caPubs
!= NULL
&& (caPubs_copy
= X509_chain_up_ref(caPubs
)) == NULL
)
114 sk_X509_pop_free(ctx
->caPubsOut
, X509_free
);
115 ctx
->caPubsOut
= caPubs_copy
;
119 int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX
*srv_ctx
, int status
,
120 int fail_info
, const char *text
)
122 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
126 CMPerr(0, CMP_R_NULL_ARGUMENT
);
129 if ((si
= OSSL_CMP_STATUSINFO_new(status
, fail_info
, text
)) == NULL
)
131 OSSL_CMP_PKISI_free(ctx
->statusOut
);
136 int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX
*srv_ctx
, int val
)
138 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
141 CMPerr(0, CMP_R_NULL_ARGUMENT
);
144 ctx
->sendError
= val
!= 0;
148 int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX
*srv_ctx
, int count
)
150 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
153 CMPerr(0, CMP_R_NULL_ARGUMENT
);
157 CMPerr(0, CMP_R_INVALID_ARGS
);
160 ctx
->pollCount
= count
;
164 int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX
*srv_ctx
, int sec
)
166 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
169 CMPerr(0, CMP_R_NULL_ARGUMENT
);
172 ctx
->checkAfterTime
= sec
;
176 static OSSL_CMP_PKISI
*process_cert_request(OSSL_CMP_SRV_CTX
*srv_ctx
,
177 const OSSL_CMP_MSG
*cert_req
,
179 const OSSL_CRMF_MSG
*crm
,
180 const X509_REQ
*p10cr
,
182 STACK_OF(X509
) **chainOut
,
183 STACK_OF(X509
) **caPubs
)
185 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
186 OSSL_CMP_PKISI
*si
= NULL
;
188 if (ctx
== NULL
|| cert_req
== NULL
189 || certOut
== NULL
|| chainOut
== NULL
|| caPubs
== NULL
) {
190 CMPerr(0, CMP_R_NULL_ARGUMENT
);
193 if (ctx
->sendError
) {
194 CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE
);
201 ctx
->certReqId
= certReqId
;
202 if (ctx
->pollCount
> 0) {
204 OSSL_CMP_MSG_free(ctx
->certReq
);
205 if ((ctx
->certReq
= OSSL_CMP_MSG_dup(cert_req
)) == NULL
)
207 return OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting
, 0, NULL
);
209 if (ctx
->certOut
!= NULL
210 && (*certOut
= X509_dup(ctx
->certOut
)) == NULL
)
211 /* TODO better return a cert produced from data in request template */
213 if (ctx
->chainOut
!= NULL
214 && (*chainOut
= X509_chain_up_ref(ctx
->chainOut
)) == NULL
)
216 if (ctx
->caPubsOut
!= NULL
217 && (*caPubs
= X509_chain_up_ref(ctx
->caPubsOut
)) == NULL
)
219 if (ctx
->statusOut
!= NULL
220 && (si
= OSSL_CMP_PKISI_dup(ctx
->statusOut
)) == NULL
)
227 sk_X509_pop_free(*chainOut
, X509_free
);
229 sk_X509_pop_free(*caPubs
, X509_free
);
234 static OSSL_CMP_PKISI
*process_rr(OSSL_CMP_SRV_CTX
*srv_ctx
,
235 const OSSL_CMP_MSG
*rr
,
236 const X509_NAME
*issuer
,
237 const ASN1_INTEGER
*serial
)
239 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
241 if (ctx
== NULL
|| rr
== NULL
|| issuer
== NULL
|| serial
== NULL
) {
242 CMPerr(0, CMP_R_NULL_ARGUMENT
);
245 if (ctx
->sendError
|| ctx
->certOut
== NULL
) {
246 CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE
);
250 /* accept revocation only for the certificate we sent in ir/cr/kur */
251 if (X509_NAME_cmp(issuer
, X509_get_issuer_name(ctx
->certOut
)) != 0
252 || ASN1_INTEGER_cmp(serial
,
253 X509_get0_serialNumber(ctx
->certOut
)) != 0) {
254 CMPerr(0, CMP_R_REQUEST_NOT_ACCEPTED
);
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 CMPerr(0, CMP_R_NULL_ARGUMENT
);
271 if (ctx
->sendError
) {
272 CMPerr(0, 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 CMPerr(0, 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 /* TODO could use sk_ASN1_UTF8STRING2text() if exported */
315 BIO_printf(bio_err
, "errorDetails: ");
316 for (i
= 0; i
< sk_ASN1_UTF8STRING_num(errorDetails
); i
++) {
318 BIO_printf(bio_err
, ", ");
319 BIO_printf(bio_err
, "\"");
320 ASN1_STRING_print(bio_err
,
321 sk_ASN1_UTF8STRING_value(errorDetails
, i
));
322 BIO_printf(bio_err
, "\"");
324 BIO_printf(bio_err
, "\n");
328 static int process_certConf(OSSL_CMP_SRV_CTX
*srv_ctx
,
329 const OSSL_CMP_MSG
*certConf
, int certReqId
,
330 const ASN1_OCTET_STRING
*certHash
,
331 const OSSL_CMP_PKISI
*si
)
333 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
334 ASN1_OCTET_STRING
*digest
;
336 if (ctx
== NULL
|| certConf
== NULL
|| certHash
== NULL
) {
337 CMPerr(0, CMP_R_NULL_ARGUMENT
);
340 if (ctx
->sendError
|| ctx
->certOut
== NULL
) {
341 CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE
);
345 if (certReqId
!= ctx
->certReqId
) {
346 /* in case of error, invalid reqId -1 */
347 CMPerr(0, CMP_R_BAD_REQUEST_ID
);
351 if ((digest
= X509_digest_sig(ctx
->certOut
)) == NULL
)
353 if (ASN1_OCTET_STRING_cmp(certHash
, digest
) != 0) {
354 ASN1_OCTET_STRING_free(digest
);
355 CMPerr(0, CMP_R_CERTHASH_UNMATCHED
);
358 ASN1_OCTET_STRING_free(digest
);
362 static int process_pollReq(OSSL_CMP_SRV_CTX
*srv_ctx
,
363 const OSSL_CMP_MSG
*pollReq
, int certReqId
,
364 OSSL_CMP_MSG
**certReq
, int64_t *check_after
)
366 mock_srv_ctx
*ctx
= OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
);
368 if (ctx
== NULL
|| pollReq
== NULL
369 || certReq
== NULL
|| check_after
== NULL
) {
370 CMPerr(0, CMP_R_NULL_ARGUMENT
);
373 if (ctx
->sendError
|| ctx
->certReq
== NULL
) {
375 CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE
);
379 if (ctx
->pollCount
== 0) {
380 *certReq
= ctx
->certReq
;
386 *check_after
= ctx
->checkAfterTime
;
391 OSSL_CMP_SRV_CTX
*ossl_cmp_mock_srv_new(OPENSSL_CTX
*libctx
, const char *propq
)
393 OSSL_CMP_SRV_CTX
*srv_ctx
= OSSL_CMP_SRV_CTX_new(libctx
, propq
);
394 mock_srv_ctx
*ctx
= mock_srv_ctx_new();
396 if (srv_ctx
!= NULL
&& ctx
!= NULL
397 && OSSL_CMP_SRV_CTX_init(srv_ctx
, ctx
, process_cert_request
,
398 process_rr
, process_genm
, process_error
,
399 process_certConf
, process_pollReq
))
402 mock_srv_ctx_free(ctx
);
403 OSSL_CMP_SRV_CTX_free(srv_ctx
);
407 void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX
*srv_ctx
)
410 mock_srv_ctx_free(OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx
));
411 OSSL_CMP_SRV_CTX_free(srv_ctx
);