Annotation of embedaddon/strongswan/src/libstrongswan/plugins/pkcs7/pkcs7_encrypted_data.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2013 Tobias Brunner
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include "pkcs7_encrypted_data.h"
17:
18: #include <asn1/asn1.h>
19: #include <asn1/asn1_parser.h>
20: #include <asn1/oid.h>
21: #include <crypto/pkcs5.h>
22: #include <utils/debug.h>
23:
24: typedef struct private_pkcs7_encrypted_data_t private_pkcs7_encrypted_data_t;
25:
26: /**
27: * Private data of a PKCS#7 signed-data container.
28: */
29: struct private_pkcs7_encrypted_data_t {
30:
31: /**
32: * Implements pkcs7_t.
33: */
34: pkcs7_t public;
35:
36: /**
37: * Decrypted content
38: */
39: chunk_t content;
40:
41: /**
42: * Encrypted and encoded PKCS#7 encrypted-data
43: */
44: chunk_t encoding;
45: };
46:
47: /**
48: * Decrypt encrypted-data with available passwords
49: */
50: static bool decrypt(pkcs5_t *pkcs5, chunk_t data, chunk_t *decrypted)
51: {
52: enumerator_t *enumerator;
53: shared_key_t *shared;
54: bool success = FALSE;
55:
56: enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
57: SHARED_PRIVATE_KEY_PASS, NULL, NULL);
58: while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
59: {
60: if (pkcs5->decrypt(pkcs5, shared->get_key(shared), data, decrypted))
61: {
62: success = TRUE;
63: break;
64: }
65: }
66: enumerator->destroy(enumerator);
67: return success;
68: }
69:
70: /**
71: * ASN.1 definition of the PKCS#7 encrypted-data type
72: */
73: static const asn1Object_t encryptedDataObjects[] = {
74: { 0, "encryptedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
75: { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
76: { 1, "encryptedContentInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 2 */
77: { 2, "contentType", ASN1_OID, ASN1_BODY }, /* 3 */
78: { 2, "contentEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 4 */
79: { 2, "encryptedContent", ASN1_CONTEXT_S_0, ASN1_BODY }, /* 5 */
80: { 0, "exit", ASN1_EOC, ASN1_EXIT }
81: };
82: #define PKCS7_VERSION 1
83: #define PKCS7_CONTENT_TYPE 3
84: #define PKCS7_CONTENT_ENC_ALGORITHM 4
85: #define PKCS7_ENCRYPTED_CONTENT 5
86:
87: /**
88: * Parse and decrypt encrypted-data
89: */
90: static bool parse(private_pkcs7_encrypted_data_t *this, chunk_t content)
91: {
92: asn1_parser_t *parser;
93: chunk_t object;
94: int objectID, version;
95: bool success = FALSE;
96: chunk_t encrypted = chunk_empty;
97: pkcs5_t *pkcs5 = NULL;
98:
99: parser = asn1_parser_create(encryptedDataObjects, content);
100:
101: while (parser->iterate(parser, &objectID, &object))
102: {
103: int level = parser->get_level(parser);
104:
105: switch (objectID)
106: {
107: case PKCS7_VERSION:
108: version = object.len ? (int)*object.ptr : 0;
109: DBG2(DBG_LIB, " v%d", version);
110: if (version != 0)
111: {
112: DBG1(DBG_LIB, "encryptedData version is not 0");
113: goto end;
114: }
115: break;
116: case PKCS7_CONTENT_TYPE:
117: if (asn1_known_oid(object) != OID_PKCS7_DATA)
118: {
119: DBG1(DBG_LIB, "encrypted content not of type pkcs7 data");
120: goto end;
121: }
122: break;
123: case PKCS7_CONTENT_ENC_ALGORITHM:
124: pkcs5 = pkcs5_from_algorithmIdentifier(object, level + 1);
125: if (!pkcs5)
126: {
127: DBG1(DBG_LIB, "failed to detect PKCS#5 scheme");
128: goto end;
129: }
130: break;
131: case PKCS7_ENCRYPTED_CONTENT:
132: encrypted = object;
133: break;
134: }
135: }
136: success = parser->success(parser);
137:
138: end:
139: parser->destroy(parser);
140: success = success && decrypt(pkcs5, encrypted, &this->content);
141: DESTROY_IF(pkcs5);
142: return success;
143: }
144:
145: METHOD(container_t, get_type, container_type_t,
146: private_pkcs7_encrypted_data_t *this)
147: {
148: return CONTAINER_PKCS7_ENCRYPTED_DATA;
149: }
150:
151: METHOD(container_t, get_data, bool,
152: private_pkcs7_encrypted_data_t *this, chunk_t *data)
153: {
154: if (this->content.len)
155: {
156: *data = chunk_clone(this->content);
157: return TRUE;
158: }
159: return FALSE;
160: }
161:
162: METHOD(container_t, get_encoding, bool,
163: private_pkcs7_encrypted_data_t *this, chunk_t *data)
164: {
165: *data = chunk_clone(this->encoding);
166: return TRUE;
167: }
168:
169: METHOD(container_t, destroy, void,
170: private_pkcs7_encrypted_data_t *this)
171: {
172: free(this->content.ptr);
173: free(this->encoding.ptr);
174: free(this);
175: }
176:
177: /**
178: * Generic constructor
179: */
180: static private_pkcs7_encrypted_data_t* create_empty()
181: {
182: private_pkcs7_encrypted_data_t *this;
183:
184: INIT(this,
185: .public = {
186: .container = {
187: .get_type = _get_type,
188: .create_signature_enumerator = (void*)enumerator_create_empty,
189: .get_data = _get_data,
190: .get_encoding = _get_encoding,
191: .destroy = _destroy,
192: },
193: .create_cert_enumerator = (void*)enumerator_create_empty,
194: .get_attribute = (void*)return_false,
195: },
196: );
197:
198: return this;
199: }
200:
201: /**
202: * See header.
203: */
204: pkcs7_t *pkcs7_encrypted_data_load(chunk_t encoding, chunk_t content)
205: {
206: private_pkcs7_encrypted_data_t *this = create_empty();
207:
208: this->encoding = chunk_clone(encoding);
209: if (!parse(this, content))
210: {
211: destroy(this);
212: return NULL;
213: }
214:
215: return &this->public;
216: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>