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 */ 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 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