xref: /openssl/demos/cms/cms_ver.c (revision 9257a89b)
1 /*
2  * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 /* Simple S/MIME verification example */
11 #include <openssl/pem.h>
12 #include <openssl/cms.h>
13 #include <openssl/err.h>
14 
15 /*
16  * print any signingTime attributes.
17  * signingTime is when each party purportedly signed the message.
18  */
print_signingTime(CMS_ContentInfo * cms)19 static void print_signingTime(CMS_ContentInfo *cms)
20 {
21     STACK_OF(CMS_SignerInfo) *sis;
22     CMS_SignerInfo *si;
23     X509_ATTRIBUTE *attr;
24     ASN1_TYPE *t;
25     ASN1_UTCTIME *utctime;
26     ASN1_GENERALIZEDTIME *gtime;
27     BIO *b;
28     int i, loc;
29 
30     b = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT);
31     sis = CMS_get0_SignerInfos(cms);
32     for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) {
33         si = sk_CMS_SignerInfo_value(sis, i);
34         loc = CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1);
35         attr = CMS_signed_get_attr(si, loc);
36         t = X509_ATTRIBUTE_get0_type(attr, 0);
37         if (t == NULL)
38             continue;
39         switch (t->type) {
40         case V_ASN1_UTCTIME:
41             utctime = t->value.utctime;
42             ASN1_UTCTIME_print(b, utctime);
43             break;
44         case V_ASN1_GENERALIZEDTIME:
45             gtime = t->value.generalizedtime;
46             ASN1_GENERALIZEDTIME_print(b, gtime);
47             break;
48         default:
49             fprintf(stderr, "unrecognized signingTime type\n");
50             break;
51         }
52         BIO_printf(b, ": signingTime from SignerInfo %i\n", i);
53     }
54     BIO_free(b);
55     return;
56 }
57 
main(int argc,char ** argv)58 int main(int argc, char **argv)
59 {
60     BIO *in = NULL, *out = NULL, *tbio = NULL, *cont = NULL;
61     X509_STORE *st = NULL;
62     X509 *cacert = NULL;
63     CMS_ContentInfo *cms = NULL;
64     int ret = EXIT_FAILURE;
65 
66     OpenSSL_add_all_algorithms();
67     ERR_load_crypto_strings();
68 
69     /* Set up trusted CA certificate store */
70 
71     st = X509_STORE_new();
72     if (st == NULL)
73         goto err;
74 
75     /* Read in CA certificate */
76     tbio = BIO_new_file("cacert.pem", "r");
77 
78     if (tbio == NULL)
79         goto err;
80 
81     cacert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
82 
83     if (cacert == NULL)
84         goto err;
85 
86     if (!X509_STORE_add_cert(st, cacert))
87         goto err;
88 
89     /* Open message being verified */
90 
91     in = BIO_new_file("smout.txt", "r");
92 
93     if (in == NULL)
94         goto err;
95 
96     /* parse message */
97     cms = SMIME_read_CMS(in, &cont);
98 
99     if (cms == NULL)
100         goto err;
101 
102     print_signingTime(cms);
103 
104     /* File to output verified content to */
105     out = BIO_new_file("smver.txt", "w");
106     if (out == NULL)
107         goto err;
108 
109     if (!CMS_verify(cms, NULL, st, cont, out, 0)) {
110         fprintf(stderr, "Verification Failure\n");
111         goto err;
112     }
113 
114     printf("Verification Successful\n");
115 
116     ret = EXIT_SUCCESS;
117 
118  err:
119     if (ret != EXIT_SUCCESS) {
120         fprintf(stderr, "Error Verifying Data\n");
121         ERR_print_errors_fp(stderr);
122     }
123 
124     X509_STORE_free(st);
125     CMS_ContentInfo_free(cms);
126     X509_free(cacert);
127     BIO_free(in);
128     BIO_free(out);
129     BIO_free(tbio);
130     return ret;
131 }
132