pk7_asn1.c revision 160814
1109998Smarkm/* pk7_asn.c */ 2109998Smarkm/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 3109998Smarkm * project 2000. 4109998Smarkm */ 5109998Smarkm/* ==================================================================== 6109998Smarkm * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 7109998Smarkm * 8109998Smarkm * Redistribution and use in source and binary forms, with or without 9109998Smarkm * modification, are permitted provided that the following conditions 10109998Smarkm * are met: 11109998Smarkm * 12109998Smarkm * 1. Redistributions of source code must retain the above copyright 13109998Smarkm * notice, this list of conditions and the following disclaimer. 14109998Smarkm * 15109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 16109998Smarkm * notice, this list of conditions and the following disclaimer in 17109998Smarkm * the documentation and/or other materials provided with the 18109998Smarkm * distribution. 19109998Smarkm * 20109998Smarkm * 3. All advertising materials mentioning features or use of this 21109998Smarkm * software must display the following acknowledgment: 22109998Smarkm * "This product includes software developed by the OpenSSL Project 23109998Smarkm * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24109998Smarkm * 25109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26109998Smarkm * endorse or promote products derived from this software without 27109998Smarkm * prior written permission. For written permission, please contact 28109998Smarkm * licensing@OpenSSL.org. 29109998Smarkm * 30109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 31109998Smarkm * nor may "OpenSSL" appear in their names without prior written 32109998Smarkm * permission of the OpenSSL Project. 33109998Smarkm * 34109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 35109998Smarkm * acknowledgment: 36109998Smarkm * "This product includes software developed by the OpenSSL Project 37109998Smarkm * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38109998Smarkm * 39109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 51109998Smarkm * ==================================================================== 52109998Smarkm * 53109998Smarkm * This product includes cryptographic software written by Eric Young 54109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 55109998Smarkm * Hudson (tjh@cryptsoft.com). 56109998Smarkm * 57109998Smarkm */ 58109998Smarkm 59109998Smarkm#include <stdio.h> 60109998Smarkm#include "cryptlib.h" 61109998Smarkm#include <openssl/asn1t.h> 62109998Smarkm#include <openssl/pkcs7.h> 63109998Smarkm#include <openssl/x509.h> 64109998Smarkm 65109998Smarkm/* PKCS#7 ASN1 module */ 66109998Smarkm 67109998Smarkm/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */ 68109998Smarkm 69109998SmarkmASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0); 70109998Smarkm 71109998SmarkmASN1_ADB(PKCS7) = { 72160814Ssimon ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING_NDEF, 0)), 73160814Ssimon ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)), 74160814Ssimon ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)), 75160814Ssimon ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)), 76160814Ssimon ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)), 77160814Ssimon ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0)) 78109998Smarkm} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL); 79109998Smarkm 80160814SsimonASN1_NDEF_SEQUENCE(PKCS7) = { 81109998Smarkm ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT), 82109998Smarkm ASN1_ADB_OBJECT(PKCS7) 83160814Ssimon}ASN1_NDEF_SEQUENCE_END(PKCS7) 84109998Smarkm 85109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(PKCS7) 86160814SsimonIMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7) 87109998SmarkmIMPLEMENT_ASN1_DUP_FUNCTION(PKCS7) 88109998Smarkm 89160814SsimonASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = { 90109998Smarkm ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER), 91109998Smarkm ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR), 92109998Smarkm ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7), 93109998Smarkm ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0), 94109998Smarkm ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1), 95109998Smarkm ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO) 96160814Ssimon} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGNED) 97109998Smarkm 98109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED) 99109998Smarkm 100109998Smarkm/* Minor tweak to operation: free up EVP_PKEY */ 101109998Smarkmstatic int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 102109998Smarkm{ 103109998Smarkm if(operation == ASN1_OP_FREE_POST) { 104109998Smarkm PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval; 105109998Smarkm EVP_PKEY_free(si->pkey); 106109998Smarkm } 107109998Smarkm return 1; 108109998Smarkm} 109109998Smarkm 110109998SmarkmASN1_SEQUENCE_cb(PKCS7_SIGNER_INFO, si_cb) = { 111109998Smarkm ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER), 112109998Smarkm ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL), 113109998Smarkm ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR), 114109998Smarkm /* NB this should be a SET OF but we use a SEQUENCE OF so the 115109998Smarkm * original order * is retained when the structure is reencoded. 116109998Smarkm * Since the attributes are implicitly tagged this will not affect 117109998Smarkm * the encoding. 118109998Smarkm */ 119109998Smarkm ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0), 120109998Smarkm ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR), 121109998Smarkm ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING), 122109998Smarkm ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1) 123109998Smarkm} ASN1_SEQUENCE_END_cb(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO) 124109998Smarkm 125109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) 126109998Smarkm 127109998SmarkmASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = { 128109998Smarkm ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, issuer, X509_NAME), 129109998Smarkm ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, serial, ASN1_INTEGER) 130109998Smarkm} ASN1_SEQUENCE_END(PKCS7_ISSUER_AND_SERIAL) 131109998Smarkm 132109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) 133109998Smarkm 134160814SsimonASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = { 135109998Smarkm ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER), 136109998Smarkm ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO), 137109998Smarkm ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT) 138160814Ssimon} ASN1_NDEF_SEQUENCE_END(PKCS7_ENVELOPE) 139109998Smarkm 140109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE) 141109998Smarkm 142109998Smarkm/* Minor tweak to operation: free up X509 */ 143109998Smarkmstatic int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 144109998Smarkm{ 145109998Smarkm if(operation == ASN1_OP_FREE_POST) { 146109998Smarkm PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval; 147109998Smarkm X509_free(ri->cert); 148109998Smarkm } 149109998Smarkm return 1; 150109998Smarkm} 151109998Smarkm 152109998SmarkmASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = { 153109998Smarkm ASN1_SIMPLE(PKCS7_RECIP_INFO, version, ASN1_INTEGER), 154109998Smarkm ASN1_SIMPLE(PKCS7_RECIP_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL), 155109998Smarkm ASN1_SIMPLE(PKCS7_RECIP_INFO, key_enc_algor, X509_ALGOR), 156109998Smarkm ASN1_SIMPLE(PKCS7_RECIP_INFO, enc_key, ASN1_OCTET_STRING) 157109998Smarkm} ASN1_SEQUENCE_END_cb(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO) 158109998Smarkm 159109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) 160109998Smarkm 161160814SsimonASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = { 162109998Smarkm ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT), 163109998Smarkm ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR), 164109998Smarkm ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING, 0) 165160814Ssimon} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT) 166109998Smarkm 167109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) 168109998Smarkm 169160814SsimonASN1_NDEF_SEQUENCE(PKCS7_SIGN_ENVELOPE) = { 170109998Smarkm ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER), 171109998Smarkm ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO), 172109998Smarkm ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR), 173109998Smarkm ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, enc_data, PKCS7_ENC_CONTENT), 174109998Smarkm ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0), 175109998Smarkm ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1), 176109998Smarkm ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO) 177160814Ssimon} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGN_ENVELOPE) 178109998Smarkm 179109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) 180109998Smarkm 181160814SsimonASN1_NDEF_SEQUENCE(PKCS7_ENCRYPT) = { 182109998Smarkm ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER), 183109998Smarkm ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT) 184160814Ssimon} ASN1_NDEF_SEQUENCE_END(PKCS7_ENCRYPT) 185109998Smarkm 186109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT) 187109998Smarkm 188160814SsimonASN1_NDEF_SEQUENCE(PKCS7_DIGEST) = { 189109998Smarkm ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER), 190109998Smarkm ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR), 191109998Smarkm ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7), 192109998Smarkm ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING) 193160814Ssimon} ASN1_NDEF_SEQUENCE_END(PKCS7_DIGEST) 194109998Smarkm 195109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST) 196109998Smarkm 197109998Smarkm/* Specials for authenticated attributes */ 198109998Smarkm 199109998Smarkm/* When signing attributes we want to reorder them to match the sorted 200109998Smarkm * encoding. 201109998Smarkm */ 202109998Smarkm 203109998SmarkmASN1_ITEM_TEMPLATE(PKCS7_ATTR_SIGN) = 204109998Smarkm ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) 205109998SmarkmASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_SIGN) 206109998Smarkm 207109998Smarkm/* When verifying attributes we need to use the received order. So 208109998Smarkm * we use SEQUENCE OF and tag it to SET OF 209109998Smarkm */ 210109998Smarkm 211109998SmarkmASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) = 212109998Smarkm ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, 213109998Smarkm V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) 214109998SmarkmASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY) 215