ASoC: Intel: Skylake: Add deep buffer support
[sfrench/cifs-2.6.git] / crypto / asymmetric_keys / pkcs7_parser.c
1 /* PKCS#7 parser
2  *
3  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public Licence
8  * as published by the Free Software Foundation; either version
9  * 2 of the Licence, or (at your option) any later version.
10  */
11
12 #define pr_fmt(fmt) "PKCS7: "fmt
13 #include <linux/kernel.h>
14 #include <linux/export.h>
15 #include <linux/slab.h>
16 #include <linux/err.h>
17 #include <linux/oid_registry.h>
18 #include <crypto/public_key.h>
19 #include "pkcs7_parser.h"
20 #include "pkcs7-asn1.h"
21
22 struct pkcs7_parse_context {
23         struct pkcs7_message    *msg;           /* Message being constructed */
24         struct pkcs7_signed_info *sinfo;        /* SignedInfo being constructed */
25         struct pkcs7_signed_info **ppsinfo;
26         struct x509_certificate *certs;         /* Certificate cache */
27         struct x509_certificate **ppcerts;
28         unsigned long   data;                   /* Start of data */
29         enum OID        last_oid;               /* Last OID encountered */
30         unsigned        x509_index;
31         unsigned        sinfo_index;
32         const void      *raw_serial;
33         unsigned        raw_serial_size;
34         unsigned        raw_issuer_size;
35         const void      *raw_issuer;
36         const void      *raw_skid;
37         unsigned        raw_skid_size;
38         bool            expect_skid;
39 };
40
41 /*
42  * Free a signed information block.
43  */
44 static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
45 {
46         if (sinfo) {
47                 public_key_signature_free(sinfo->sig);
48                 kfree(sinfo);
49         }
50 }
51
52 /**
53  * pkcs7_free_message - Free a PKCS#7 message
54  * @pkcs7: The PKCS#7 message to free
55  */
56 void pkcs7_free_message(struct pkcs7_message *pkcs7)
57 {
58         struct x509_certificate *cert;
59         struct pkcs7_signed_info *sinfo;
60
61         if (pkcs7) {
62                 while (pkcs7->certs) {
63                         cert = pkcs7->certs;
64                         pkcs7->certs = cert->next;
65                         x509_free_certificate(cert);
66                 }
67                 while (pkcs7->crl) {
68                         cert = pkcs7->crl;
69                         pkcs7->crl = cert->next;
70                         x509_free_certificate(cert);
71                 }
72                 while (pkcs7->signed_infos) {
73                         sinfo = pkcs7->signed_infos;
74                         pkcs7->signed_infos = sinfo->next;
75                         pkcs7_free_signed_info(sinfo);
76                 }
77                 kfree(pkcs7);
78         }
79 }
80 EXPORT_SYMBOL_GPL(pkcs7_free_message);
81
82 /*
83  * Check authenticatedAttributes are provided or not provided consistently.
84  */
85 static int pkcs7_check_authattrs(struct pkcs7_message *msg)
86 {
87         struct pkcs7_signed_info *sinfo;
88         bool want = false;
89
90         sinfo = msg->signed_infos;
91         if (sinfo->authattrs) {
92                 want = true;
93                 msg->have_authattrs = true;
94         }
95
96         for (sinfo = sinfo->next; sinfo; sinfo = sinfo->next)
97                 if (!!sinfo->authattrs != want)
98                         goto inconsistent;
99         return 0;
100
101 inconsistent:
102         pr_warn("Inconsistently supplied authAttrs\n");
103         return -EINVAL;
104 }
105
106 /**
107  * pkcs7_parse_message - Parse a PKCS#7 message
108  * @data: The raw binary ASN.1 encoded message to be parsed
109  * @datalen: The size of the encoded message
110  */
111 struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
112 {
113         struct pkcs7_parse_context *ctx;
114         struct pkcs7_message *msg = ERR_PTR(-ENOMEM);
115         int ret;
116
117         ctx = kzalloc(sizeof(struct pkcs7_parse_context), GFP_KERNEL);
118         if (!ctx)
119                 goto out_no_ctx;
120         ctx->msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL);
121         if (!ctx->msg)
122                 goto out_no_msg;
123         ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
124         if (!ctx->sinfo)
125                 goto out_no_sinfo;
126         ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
127                                   GFP_KERNEL);
128         if (!ctx->sinfo->sig)
129                 goto out_no_sig;
130
131         ctx->data = (unsigned long)data;
132         ctx->ppcerts = &ctx->certs;
133         ctx->ppsinfo = &ctx->msg->signed_infos;
134
135         /* Attempt to decode the signature */
136         ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen);
137         if (ret < 0) {
138                 msg = ERR_PTR(ret);
139                 goto out;
140         }
141
142         ret = pkcs7_check_authattrs(ctx->msg);
143         if (ret < 0)
144                 goto out;
145
146         msg = ctx->msg;
147         ctx->msg = NULL;
148
149 out:
150         while (ctx->certs) {
151                 struct x509_certificate *cert = ctx->certs;
152                 ctx->certs = cert->next;
153                 x509_free_certificate(cert);
154         }
155 out_no_sig:
156         pkcs7_free_signed_info(ctx->sinfo);
157 out_no_sinfo:
158         pkcs7_free_message(ctx->msg);
159 out_no_msg:
160         kfree(ctx);
161 out_no_ctx:
162         return msg;
163 }
164 EXPORT_SYMBOL_GPL(pkcs7_parse_message);
165
166 /**
167  * pkcs7_get_content_data - Get access to the PKCS#7 content
168  * @pkcs7: The preparsed PKCS#7 message to access
169  * @_data: Place to return a pointer to the data
170  * @_data_len: Place to return the data length
171  * @_headerlen: Size of ASN.1 header not included in _data
172  *
173  * Get access to the data content of the PKCS#7 message.  The size of the
174  * header of the ASN.1 object that contains it is also provided and can be used
175  * to adjust *_data and *_data_len to get the entire object.
176  *
177  * Returns -ENODATA if the data object was missing from the message.
178  */
179 int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
180                            const void **_data, size_t *_data_len,
181                            size_t *_headerlen)
182 {
183         if (!pkcs7->data)
184                 return -ENODATA;
185
186         *_data = pkcs7->data;
187         *_data_len = pkcs7->data_len;
188         if (_headerlen)
189                 *_headerlen = pkcs7->data_hdrlen;
190         return 0;
191 }
192 EXPORT_SYMBOL_GPL(pkcs7_get_content_data);
193
194 /*
195  * Note an OID when we find one for later processing when we know how
196  * to interpret it.
197  */
198 int pkcs7_note_OID(void *context, size_t hdrlen,
199                    unsigned char tag,
200                    const void *value, size_t vlen)
201 {
202         struct pkcs7_parse_context *ctx = context;
203
204         ctx->last_oid = look_up_OID(value, vlen);
205         if (ctx->last_oid == OID__NR) {
206                 char buffer[50];
207                 sprint_oid(value, vlen, buffer, sizeof(buffer));
208                 printk("PKCS7: Unknown OID: [%lu] %s\n",
209                        (unsigned long)value - ctx->data, buffer);
210         }
211         return 0;
212 }
213
214 /*
215  * Note the digest algorithm for the signature.
216  */
217 int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
218                                unsigned char tag,
219                                const void *value, size_t vlen)
220 {
221         struct pkcs7_parse_context *ctx = context;
222
223         switch (ctx->last_oid) {
224         case OID_md4:
225                 ctx->sinfo->sig->hash_algo = "md4";
226                 break;
227         case OID_md5:
228                 ctx->sinfo->sig->hash_algo = "md5";
229                 break;
230         case OID_sha1:
231                 ctx->sinfo->sig->hash_algo = "sha1";
232                 break;
233         case OID_sha256:
234                 ctx->sinfo->sig->hash_algo = "sha256";
235                 break;
236         case OID_sha384:
237                 ctx->sinfo->sig->hash_algo = "sha384";
238                 break;
239         case OID_sha512:
240                 ctx->sinfo->sig->hash_algo = "sha512";
241                 break;
242         case OID_sha224:
243                 ctx->sinfo->sig->hash_algo = "sha224";
244                 break;
245         default:
246                 printk("Unsupported digest algo: %u\n", ctx->last_oid);
247                 return -ENOPKG;
248         }
249         return 0;
250 }
251
252 /*
253  * Note the public key algorithm for the signature.
254  */
255 int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
256                              unsigned char tag,
257                              const void *value, size_t vlen)
258 {
259         struct pkcs7_parse_context *ctx = context;
260
261         switch (ctx->last_oid) {
262         case OID_rsaEncryption:
263                 ctx->sinfo->sig->pkey_algo = "rsa";
264                 break;
265         default:
266                 printk("Unsupported pkey algo: %u\n", ctx->last_oid);
267                 return -ENOPKG;
268         }
269         return 0;
270 }
271
272 /*
273  * We only support signed data [RFC2315 sec 9].
274  */
275 int pkcs7_check_content_type(void *context, size_t hdrlen,
276                              unsigned char tag,
277                              const void *value, size_t vlen)
278 {
279         struct pkcs7_parse_context *ctx = context;
280
281         if (ctx->last_oid != OID_signed_data) {
282                 pr_warn("Only support pkcs7_signedData type\n");
283                 return -EINVAL;
284         }
285
286         return 0;
287 }
288
289 /*
290  * Note the SignedData version
291  */
292 int pkcs7_note_signeddata_version(void *context, size_t hdrlen,
293                                   unsigned char tag,
294                                   const void *value, size_t vlen)
295 {
296         struct pkcs7_parse_context *ctx = context;
297         unsigned version;
298
299         if (vlen != 1)
300                 goto unsupported;
301
302         ctx->msg->version = version = *(const u8 *)value;
303         switch (version) {
304         case 1:
305                 /* PKCS#7 SignedData [RFC2315 sec 9.1]
306                  * CMS ver 1 SignedData [RFC5652 sec 5.1]
307                  */
308                 break;
309         case 3:
310                 /* CMS ver 3 SignedData [RFC2315 sec 5.1] */
311                 break;
312         default:
313                 goto unsupported;
314         }
315
316         return 0;
317
318 unsupported:
319         pr_warn("Unsupported SignedData version\n");
320         return -EINVAL;
321 }
322
323 /*
324  * Note the SignerInfo version
325  */
326 int pkcs7_note_signerinfo_version(void *context, size_t hdrlen,
327                                   unsigned char tag,
328                                   const void *value, size_t vlen)
329 {
330         struct pkcs7_parse_context *ctx = context;
331         unsigned version;
332
333         if (vlen != 1)
334                 goto unsupported;
335
336         version = *(const u8 *)value;
337         switch (version) {
338         case 1:
339                 /* PKCS#7 SignerInfo [RFC2315 sec 9.2]
340                  * CMS ver 1 SignerInfo [RFC5652 sec 5.3]
341                  */
342                 if (ctx->msg->version != 1)
343                         goto version_mismatch;
344                 ctx->expect_skid = false;
345                 break;
346         case 3:
347                 /* CMS ver 3 SignerInfo [RFC2315 sec 5.3] */
348                 if (ctx->msg->version == 1)
349                         goto version_mismatch;
350                 ctx->expect_skid = true;
351                 break;
352         default:
353                 goto unsupported;
354         }
355
356         return 0;
357
358 unsupported:
359         pr_warn("Unsupported SignerInfo version\n");
360         return -EINVAL;
361 version_mismatch:
362         pr_warn("SignedData-SignerInfo version mismatch\n");
363         return -EBADMSG;
364 }
365
366 /*
367  * Extract a certificate and store it in the context.
368  */
369 int pkcs7_extract_cert(void *context, size_t hdrlen,
370                        unsigned char tag,
371                        const void *value, size_t vlen)
372 {
373         struct pkcs7_parse_context *ctx = context;
374         struct x509_certificate *x509;
375
376         if (tag != ((ASN1_UNIV << 6) | ASN1_CONS_BIT | ASN1_SEQ)) {
377                 pr_debug("Cert began with tag %02x at %lu\n",
378                          tag, (unsigned long)ctx - ctx->data);
379                 return -EBADMSG;
380         }
381
382         /* We have to correct for the header so that the X.509 parser can start
383          * from the beginning.  Note that since X.509 stipulates DER, there
384          * probably shouldn't be an EOC trailer - but it is in PKCS#7 (which
385          * stipulates BER).
386          */
387         value -= hdrlen;
388         vlen += hdrlen;
389
390         if (((u8*)value)[1] == 0x80)
391                 vlen += 2; /* Indefinite length - there should be an EOC */
392
393         x509 = x509_cert_parse(value, vlen);
394         if (IS_ERR(x509))
395                 return PTR_ERR(x509);
396
397         x509->index = ++ctx->x509_index;
398         pr_debug("Got cert %u for %s\n", x509->index, x509->subject);
399         pr_debug("- fingerprint %*phN\n", x509->id->len, x509->id->data);
400
401         *ctx->ppcerts = x509;
402         ctx->ppcerts = &x509->next;
403         return 0;
404 }
405
406 /*
407  * Save the certificate list
408  */
409 int pkcs7_note_certificate_list(void *context, size_t hdrlen,
410                                 unsigned char tag,
411                                 const void *value, size_t vlen)
412 {
413         struct pkcs7_parse_context *ctx = context;
414
415         pr_devel("Got cert list (%02x)\n", tag);
416
417         *ctx->ppcerts = ctx->msg->certs;
418         ctx->msg->certs = ctx->certs;
419         ctx->certs = NULL;
420         ctx->ppcerts = &ctx->certs;
421         return 0;
422 }
423
424 /*
425  * Note the content type.
426  */
427 int pkcs7_note_content(void *context, size_t hdrlen,
428                        unsigned char tag,
429                        const void *value, size_t vlen)
430 {
431         struct pkcs7_parse_context *ctx = context;
432
433         if (ctx->last_oid != OID_data &&
434             ctx->last_oid != OID_msIndirectData) {
435                 pr_warn("Unsupported data type %d\n", ctx->last_oid);
436                 return -EINVAL;
437         }
438
439         ctx->msg->data_type = ctx->last_oid;
440         return 0;
441 }
442
443 /*
444  * Extract the data from the message and store that and its content type OID in
445  * the context.
446  */
447 int pkcs7_note_data(void *context, size_t hdrlen,
448                     unsigned char tag,
449                     const void *value, size_t vlen)
450 {
451         struct pkcs7_parse_context *ctx = context;
452
453         pr_debug("Got data\n");
454
455         ctx->msg->data = value;
456         ctx->msg->data_len = vlen;
457         ctx->msg->data_hdrlen = hdrlen;
458         return 0;
459 }
460
461 /*
462  * Parse authenticated attributes.
463  */
464 int pkcs7_sig_note_authenticated_attr(void *context, size_t hdrlen,
465                                       unsigned char tag,
466                                       const void *value, size_t vlen)
467 {
468         struct pkcs7_parse_context *ctx = context;
469         struct pkcs7_signed_info *sinfo = ctx->sinfo;
470         enum OID content_type;
471
472         pr_devel("AuthAttr: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value);
473
474         switch (ctx->last_oid) {
475         case OID_contentType:
476                 if (__test_and_set_bit(sinfo_has_content_type, &sinfo->aa_set))
477                         goto repeated;
478                 content_type = look_up_OID(value, vlen);
479                 if (content_type != ctx->msg->data_type) {
480                         pr_warn("Mismatch between global data type (%d) and sinfo %u (%d)\n",
481                                 ctx->msg->data_type, sinfo->index,
482                                 content_type);
483                         return -EBADMSG;
484                 }
485                 return 0;
486
487         case OID_signingTime:
488                 if (__test_and_set_bit(sinfo_has_signing_time, &sinfo->aa_set))
489                         goto repeated;
490                 /* Should we check that the signing time is consistent
491                  * with the signer's X.509 cert?
492                  */
493                 return x509_decode_time(&sinfo->signing_time,
494                                         hdrlen, tag, value, vlen);
495
496         case OID_messageDigest:
497                 if (__test_and_set_bit(sinfo_has_message_digest, &sinfo->aa_set))
498                         goto repeated;
499                 if (tag != ASN1_OTS)
500                         return -EBADMSG;
501                 sinfo->msgdigest = value;
502                 sinfo->msgdigest_len = vlen;
503                 return 0;
504
505         case OID_smimeCapabilites:
506                 if (__test_and_set_bit(sinfo_has_smime_caps, &sinfo->aa_set))
507                         goto repeated;
508                 if (ctx->msg->data_type != OID_msIndirectData) {
509                         pr_warn("S/MIME Caps only allowed with Authenticode\n");
510                         return -EKEYREJECTED;
511                 }
512                 return 0;
513
514                 /* Microsoft SpOpusInfo seems to be contain cont[0] 16-bit BE
515                  * char URLs and cont[1] 8-bit char URLs.
516                  *
517                  * Microsoft StatementType seems to contain a list of OIDs that
518                  * are also used as extendedKeyUsage types in X.509 certs.
519                  */
520         case OID_msSpOpusInfo:
521                 if (__test_and_set_bit(sinfo_has_ms_opus_info, &sinfo->aa_set))
522                         goto repeated;
523                 goto authenticode_check;
524         case OID_msStatementType:
525                 if (__test_and_set_bit(sinfo_has_ms_statement_type, &sinfo->aa_set))
526                         goto repeated;
527         authenticode_check:
528                 if (ctx->msg->data_type != OID_msIndirectData) {
529                         pr_warn("Authenticode AuthAttrs only allowed with Authenticode\n");
530                         return -EKEYREJECTED;
531                 }
532                 /* I'm not sure how to validate these */
533                 return 0;
534         default:
535                 return 0;
536         }
537
538 repeated:
539         /* We permit max one item per AuthenticatedAttribute and no repeats */
540         pr_warn("Repeated/multivalue AuthAttrs not permitted\n");
541         return -EKEYREJECTED;
542 }
543
544 /*
545  * Note the set of auth attributes for digestion purposes [RFC2315 sec 9.3]
546  */
547 int pkcs7_sig_note_set_of_authattrs(void *context, size_t hdrlen,
548                                     unsigned char tag,
549                                     const void *value, size_t vlen)
550 {
551         struct pkcs7_parse_context *ctx = context;
552         struct pkcs7_signed_info *sinfo = ctx->sinfo;
553
554         if (!test_bit(sinfo_has_content_type, &sinfo->aa_set) ||
555             !test_bit(sinfo_has_message_digest, &sinfo->aa_set)) {
556                 pr_warn("Missing required AuthAttr\n");
557                 return -EBADMSG;
558         }
559
560         if (ctx->msg->data_type != OID_msIndirectData &&
561             test_bit(sinfo_has_ms_opus_info, &sinfo->aa_set)) {
562                 pr_warn("Unexpected Authenticode AuthAttr\n");
563                 return -EBADMSG;
564         }
565
566         /* We need to switch the 'CONT 0' to a 'SET OF' when we digest */
567         sinfo->authattrs = value - (hdrlen - 1);
568         sinfo->authattrs_len = vlen + (hdrlen - 1);
569         return 0;
570 }
571
572 /*
573  * Note the issuing certificate serial number
574  */
575 int pkcs7_sig_note_serial(void *context, size_t hdrlen,
576                           unsigned char tag,
577                           const void *value, size_t vlen)
578 {
579         struct pkcs7_parse_context *ctx = context;
580         ctx->raw_serial = value;
581         ctx->raw_serial_size = vlen;
582         return 0;
583 }
584
585 /*
586  * Note the issuer's name
587  */
588 int pkcs7_sig_note_issuer(void *context, size_t hdrlen,
589                           unsigned char tag,
590                           const void *value, size_t vlen)
591 {
592         struct pkcs7_parse_context *ctx = context;
593         ctx->raw_issuer = value;
594         ctx->raw_issuer_size = vlen;
595         return 0;
596 }
597
598 /*
599  * Note the issuing cert's subjectKeyIdentifier
600  */
601 int pkcs7_sig_note_skid(void *context, size_t hdrlen,
602                         unsigned char tag,
603                         const void *value, size_t vlen)
604 {
605         struct pkcs7_parse_context *ctx = context;
606
607         pr_devel("SKID: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value);
608
609         ctx->raw_skid = value;
610         ctx->raw_skid_size = vlen;
611         return 0;
612 }
613
614 /*
615  * Note the signature data
616  */
617 int pkcs7_sig_note_signature(void *context, size_t hdrlen,
618                              unsigned char tag,
619                              const void *value, size_t vlen)
620 {
621         struct pkcs7_parse_context *ctx = context;
622
623         ctx->sinfo->sig->s = kmemdup(value, vlen, GFP_KERNEL);
624         if (!ctx->sinfo->sig->s)
625                 return -ENOMEM;
626
627         ctx->sinfo->sig->s_size = vlen;
628         return 0;
629 }
630
631 /*
632  * Note a signature information block
633  */
634 int pkcs7_note_signed_info(void *context, size_t hdrlen,
635                            unsigned char tag,
636                            const void *value, size_t vlen)
637 {
638         struct pkcs7_parse_context *ctx = context;
639         struct pkcs7_signed_info *sinfo = ctx->sinfo;
640         struct asymmetric_key_id *kid;
641
642         if (ctx->msg->data_type == OID_msIndirectData && !sinfo->authattrs) {
643                 pr_warn("Authenticode requires AuthAttrs\n");
644                 return -EBADMSG;
645         }
646
647         /* Generate cert issuer + serial number key ID */
648         if (!ctx->expect_skid) {
649                 kid = asymmetric_key_generate_id(ctx->raw_serial,
650                                                  ctx->raw_serial_size,
651                                                  ctx->raw_issuer,
652                                                  ctx->raw_issuer_size);
653         } else {
654                 kid = asymmetric_key_generate_id(ctx->raw_skid,
655                                                  ctx->raw_skid_size,
656                                                  "", 0);
657         }
658         if (IS_ERR(kid))
659                 return PTR_ERR(kid);
660
661         pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data);
662
663         sinfo->sig->auth_ids[0] = kid;
664         sinfo->index = ++ctx->sinfo_index;
665         *ctx->ppsinfo = sinfo;
666         ctx->ppsinfo = &sinfo->next;
667         ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
668         if (!ctx->sinfo)
669                 return -ENOMEM;
670         ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
671                                   GFP_KERNEL);
672         if (!ctx->sinfo->sig)
673                 return -ENOMEM;
674         return 0;
675 }