Import of old SSLeay release: SSLeay 0.8.1b
[oweals/openssl.git] / crypto / pkcs7 / verify.c
1 #include <stdio.h>
2 #include "asn1.h"
3 #include "bio.h"
4 #include "x509.h"
5 #include "pem.h"
6
7 int verify_callback(int ok, X509_STORE_CTX *ctx);
8
9 BIO *bio_err=NULL;
10
11 main(argc,argv)
12 int argc;
13 char *argv[];
14         {
15         X509 *x509,*x;
16         PKCS7 *p7;
17         PKCS7_SIGNED *s;
18         PKCS7_SIGNER_INFO *si;
19         PKCS7_ISSUER_AND_SERIAL *ias;
20         X509_STORE_CTX cert_ctx;
21         X509_STORE *cert_store=NULL;
22         X509_LOOKUP *lookup=NULL;
23         BIO *data,*detached=NULL,*p7bio=NULL;
24         char buf[1024*4];
25         unsigned char *p,*pp;
26         int i,j,printit=0;
27         STACK *sk;
28
29         bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
30         EVP_add_digest(EVP_md2());
31         EVP_add_digest(EVP_md5());
32         EVP_add_digest(EVP_sha1());
33         EVP_add_digest(EVP_mdc2());
34
35         data=BIO_new(BIO_s_file());
36 again:
37         pp=NULL;
38         while (argc > 1)
39                 {
40                 argc--;
41                 argv++;
42                 if (strcmp(argv[0],"-p") == 0)
43                         {
44                         printit=1;
45                         }
46                 else if ((strcmp(argv[0],"-d") == 0) && (argc >= 2))
47                         {
48                         detached=BIO_new(BIO_s_file());
49                         if (!BIO_read_filename(detached,argv[1]))
50                                 goto err;
51                         argc--;
52                         argv++;
53                         }
54                 else
55                         {
56                         pp=argv[0];
57                         if (!BIO_read_filename(data,argv[0]))
58                                 goto err;
59                         }
60                 }
61
62         if (pp == NULL)
63                 BIO_set_fp(data,stdin,BIO_NOCLOSE);
64
65
66         /* Load the PKCS7 object from a file */
67         if ((p7=PEM_read_bio_PKCS7(data,NULL,NULL)) == NULL) goto err;
68
69         /* This stuff is being setup for certificate verification.
70          * When using SSL, it could be replaced with a 
71          * cert_stre=SSL_CTX_get_cert_store(ssl_ctx); */
72         cert_store=X509_STORE_new();
73         X509_STORE_set_default_paths(cert_store);
74         X509_STORE_load_locations(cert_store,NULL,"../../certs");
75         X509_STORE_set_verify_cb_func(cert_store,verify_callback);
76
77         ERR_clear_errors();
78
79         /* We need to process the data */
80         if (PKCS7_get_detached(p7))
81                 {
82                 if (detached == NULL)
83                         {
84                         printf("no data to verify the signature on\n");
85                         exit(1);
86                         }
87                 else
88                         p7bio=PKCS7_dataInit(p7,detached);
89                 }
90         else
91                 {
92                 p7bio=PKCS7_dataInit(p7,NULL);
93                 }
94
95         /* We now have to 'read' from p7bio to calculate digests etc. */
96         for (;;)
97                 {
98                 i=BIO_read(p7bio,buf,sizeof(buf));
99                 /* print it? */
100                 if (i <= 0) break;
101                 }
102
103         /* We can now verify signatures */
104         sk=PKCS7_get_signer_info(p7);
105         if (sk == NULL)
106                 {
107                 printf("there are no signatures on this data\n");
108                 exit(1);
109                 }
110
111         /* Ok, first we need to, for each subject entry, see if we can verify */
112         for (i=0; i<sk_num(sk); i++)
113                 {
114                 si=(PKCS7_SIGNER_INFO *)sk_value(sk,i);
115                 i=PKCS7_dataVerify(cert_store,&cert_ctx,p7bio,p7,si);
116                 if (i <= 0)
117                         goto err;
118                 }
119
120         X509_STORE_free(cert_store);
121
122         printf("done\n");
123         exit(0);
124 err:
125         ERR_load_crypto_strings();
126         ERR_print_errors_fp(stderr);
127         exit(1);
128         }
129
130 /* should be X509 * but we can just have them as char *. */
131 int verify_callback(ok, ctx)
132 int ok;
133 X509_STORE_CTX *ctx;
134         {
135         char buf[256];
136         X509 *err_cert;
137         int err,depth;
138
139         err_cert=X509_STORE_CTX_get_current_cert(ctx);
140         err=    X509_STORE_CTX_get_error(ctx);
141         depth=  X509_STORE_CTX_get_error_depth(ctx);
142
143         X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
144         BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
145         if (!ok)
146                 {
147                 BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
148                         X509_verify_cert_error_string(err));
149                 if (depth < 6)
150                         {
151                         ok=1;
152                         X509_STORE_CTX_set_error(ctx,X509_V_OK);
153                         }
154                 else
155                         {
156                         ok=0;
157                         X509_STORE_CTX_set_error(ctx,X509_V_ERR_CERT_CHAIN_TOO_LONG);
158                         }
159                 }
160         switch (ctx->error)
161                 {
162         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
163                 X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
164                 BIO_printf(bio_err,"issuer= %s\n",buf);
165                 break;
166         case X509_V_ERR_CERT_NOT_YET_VALID:
167         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
168                 BIO_printf(bio_err,"notBefore=");
169                 ASN1_UTCTIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
170                 BIO_printf(bio_err,"\n");
171                 break;
172         case X509_V_ERR_CERT_HAS_EXPIRED:
173         case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
174                 BIO_printf(bio_err,"notAfter=");
175                 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
176                 BIO_printf(bio_err,"\n");
177                 break;
178                 }
179         BIO_printf(bio_err,"verify return:%d\n",ok);
180         return(ok);
181         }