1 /*
2  * Copyright 2011-2013 Red Hat, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; version 2 of the License.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Author(s): Peter Jones <pjones@redhat.com>
18  */
19 #ifndef CMS_COMMON_H
20 #define CMS_COMMON_H 1
21 
22 #include <errno.h>
23 #include <cert.h>
24 #include <secpkcs7.h>
25 #include <signal.h>
26 #include <stdarg.h>
27 #include <syslog.h>
28 #include <time.h>
29 #include <unistd.h>
30 
31 #define save_port_err(x)				\
32 	({						\
33 		int __saved_errno = PORT_GetError();	\
34 		x;					\
35 		PORT_SetError(__saved_errno);		\
36 	})
37 
38 #define cmserr(rv, cms, fmt, args...) ({					\
39 		(cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ": %s",	\
40 			__FILE__, __func__, __LINE__, ## args,		\
41 			PORT_ErrorToString(PORT_GetError()));		\
42 		exit(rv);						\
43 	})
44 #define cmsreterr(rv, cms, fmt, args...) ({				\
45 		(cms)->log((cms), LOG_ERR, "%s:%s:%d: " fmt ": %s",	\
46 			__FILE__, __func__, __LINE__, ## args,		\
47 			PORT_ErrorToString(PORT_GetError()));		\
48 		return rv;						\
49 	})
50 
51 
52 struct digest {
53 	PK11Context *pk11ctx;
54 	SECItem *pe_digest;
55 };
56 
57 struct cms_context;
58 
59 typedef int (*cms_common_logger)(struct cms_context *, int priority,
60 		char *fmt, ...)
61 	__attribute__ ((format (printf, 3, 4)));
62 
63 typedef struct cms_context {
64 	PRArenaPool *arena;
65 	void *privkey;
66 
67 	char *tokenname;
68 	char *certname;
69 	CERTCertificate *cert;
70 	PK11PasswordFunc func;
71 	void *pwdata;
72 
73 	struct digest *digests;
74 	int selected_digest;
75 
76 	SECItem newsig;
77 
78 	SECItem *ci_digest;
79 
80 	SECItem *raw_signed_attrs;
81 	SECItem *raw_signature;
82 
83 	int num_signatures;
84 	SECItem **signatures;
85 
86 	int authbuf_len;
87 	void *authbuf;
88 
89 	cms_common_logger log;
90 	void *log_priv;
91 } cms_context;
92 
93 typedef enum {
94 	SpcLinkYouHaveFuckedThisUp = 0,
95 	SpcLinkTypeUrl = 1,
96 	SpcLinkTypeFile = 2,
97 } SpcLinkType;
98 
99 typedef struct {
100 	SpcLinkType type;
101 	union {
102 		SECItem url;
103 		SECItem file;
104 	};
105 } SpcLink;
106 extern SEC_ASN1Template SpcLinkTemplate[];
107 
108 extern int cms_context_alloc(cms_context **ctxp);
109 extern int cms_context_init(cms_context *ctx);
110 extern void cms_context_fini(cms_context *ctx);
111 
112 extern void teardown_digests(cms_context *ctx);
113 
114 extern int generate_octet_string(cms_context *ctx, SECItem *encoded,
115 				SECItem *original);
116 extern int generate_object_id(cms_context *ctx, SECItem *encoded,
117 				SECOidTag tag);
118 extern int generate_empty_sequence(cms_context *ctx, SECItem *encoded);
119 extern int generate_time(cms_context *ctx, SECItem *encoded, time_t when);
120 extern int generate_integer(cms_context *cms, SECItem *der, unsigned long integer);
121 extern int generate_string(cms_context *cms, SECItem *der, char *str);
122 extern int wrap_in_set(cms_context *cms, SECItem *der, SECItem **items);
123 extern int wrap_in_seq(cms_context *cms, SECItem *der,
124 			SECItem *items, int num_items);
125 extern int make_context_specific(cms_context *cms, int ctxt, SECItem *encoded,
126 			SECItem *original);
127 extern int generate_validity(cms_context *cms, SECItem *der, time_t start,
128 				time_t end);
129 extern int generate_common_name(cms_context *cms, SECItem *der, char *cn);
130 extern int generate_auth_info(cms_context *cms, SECItem *der, char *url);
131 extern int generate_algorithm_id(cms_context *ctx, SECAlgorithmID *idp,
132 				SECOidTag tag);
133 extern int generate_spc_link(cms_context *cms, SpcLink *slp,
134 				SpcLinkType link_type, void *link_data,
135 				size_t link_data_size);
136 
137 extern int generate_spc_string(cms_context *cms, SECItem *ssp, char *str,
138 				int len);
139 
140 extern int generate_digest(cms_context *cms, Pe *pe, int padded);
141 extern int generate_signature(cms_context *ctx);
142 extern int unlock_nss_token(cms_context *ctx);
143 extern int find_certificate(cms_context *ctx, int needs_private_key);
144 extern int generate_keys(cms_context *cms, PK11SlotInfo *slot,
145 		SECKEYPrivateKey **privkey, SECKEYPublicKey **pubkey);
146 extern int is_issuer_of(CERTCertificate *c0, CERTCertificate *c1);
147 
148 extern int find_named_certificate(cms_context *cms, char *name,
149 				CERTCertificate **cert);
150 extern int find_slot_for_token(cms_context *cms, PK11SlotInfo **slot);
151 
152 extern SECOidTag digest_get_digest_oid(cms_context *cms);
153 extern SECOidTag digest_get_encryption_oid(cms_context *cms);
154 extern SECOidTag digest_get_signature_oid(cms_context *cms);
155 extern int digest_get_digest_size(cms_context *cms);
156 extern void cms_set_pw_callback(cms_context *cms, PK11PasswordFunc func);
157 extern void cms_set_pw_data(cms_context *cms, void *pwdata);
158 
159 extern int set_digest_parameters(cms_context *ctx, char *name);
160 
161 typedef struct {
162 	enum {
163 		PW_NONE = 0,
164 		PW_FROMFILE = 1,
165 		PW_PLAINTEXT = 2,
166 		PW_EXTERNAL = 3
167 	} source;
168 	char *data;
169 } secuPWData;
170 
171 #endif /* CMS_COMMON_H */
172