/src/opensc/openpace/src/cvc_lookup.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2010-2012 Frank Morgner |
3 | | * |
4 | | * This file is part of OpenPACE. |
5 | | * |
6 | | * OpenPACE is free software: you can redistribute it and/or modify it under |
7 | | * the terms of the GNU General Public License as published by the Free |
8 | | * Software Foundation, either version 3 of the License, or (at your option) |
9 | | * any later version. |
10 | | * |
11 | | * OpenPACE is distributed in the hope that it will be useful, but WITHOUT ANY |
12 | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
13 | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
14 | | * details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License along with |
17 | | * OpenPACE. If not, see <http://www.gnu.org/licenses/>. |
18 | | * |
19 | | * Additional permission under GNU GPL version 3 section 7 |
20 | | * |
21 | | * If you modify this Program, or any covered work, by linking or combining it |
22 | | * with OpenSSL (or a modified version of that library), containing |
23 | | * parts covered by the terms of OpenSSL's license, the licensors of |
24 | | * this Program grant you additional permission to convey the resulting work. |
25 | | * Corresponding Source for a non-source form of such a combination shall include |
26 | | * the source code for the parts of OpenSSL used as well as that of the |
27 | | * covered work. |
28 | | * |
29 | | * If you modify this Program, or any covered work, by linking or combining it |
30 | | * with OpenSC (or a modified version of that library), containing |
31 | | * parts covered by the terms of OpenSC's license, the licensors of |
32 | | * this Program grant you additional permission to convey the resulting work. |
33 | | * Corresponding Source for a non-source form of such a combination shall include |
34 | | * the source code for the parts of OpenSC used as well as that of the |
35 | | * covered work. |
36 | | */ |
37 | | |
38 | | /** |
39 | | * @file cvc_lookup.c |
40 | | * @brief |
41 | | * |
42 | | * @author Frank Morgner <frankmorgner@gmail.com> |
43 | | */ |
44 | | |
45 | | #ifdef HAVE_CONFIG_H |
46 | | #include "config.h" |
47 | | #endif |
48 | | |
49 | | #include "eac_err.h" |
50 | | #include "eac_util.h" |
51 | | #include <eac/cv_cert.h> |
52 | | #include <eac/eac.h> |
53 | | #include <openssl/bio.h> |
54 | | #include <openssl/err.h> |
55 | | |
56 | | #ifndef PATH_MAX |
57 | | #define PATH_MAX 1024 /* # chars in a path name including nul */ |
58 | | #endif |
59 | | |
60 | | /** @brief Directory for \c EAC_get_default_cvca_lookup() */ |
61 | | static char cvc_default_dir[PATH_MAX]; |
62 | | |
63 | | void EAC_set_cvc_default_dir(const char *default_dir) |
64 | 124 | { |
65 | 124 | if (default_dir) { |
66 | 124 | strncpy(cvc_default_dir, default_dir, (sizeof cvc_default_dir) - 1); |
67 | 124 | cvc_default_dir[(sizeof cvc_default_dir) - 1] = '\0'; |
68 | 124 | } |
69 | 124 | } |
70 | | |
71 | | static int CVC_find_chr_in_file(const unsigned char *chr, size_t chr_len, |
72 | | const char *file, CVC_CERT **cv_certificate) |
73 | 0 | { |
74 | 0 | BIO *in = NULL; |
75 | 0 | CVC_CERT *cvc; |
76 | 0 | int ok = 0; |
77 | |
|
78 | 0 | if (!chr) |
79 | 0 | goto err; |
80 | | |
81 | 0 | in = BIO_new(BIO_s_file()); |
82 | 0 | if (!in || !BIO_read_filename(in, file)) |
83 | 0 | goto err; |
84 | | |
85 | 0 | while (1) { |
86 | 0 | if (!d2i_CVC_CERT_bio(in, cv_certificate)) { |
87 | 0 | ERR_clear_error(); |
88 | 0 | break; |
89 | 0 | } |
90 | 0 | cvc = *cv_certificate; |
91 | 0 | if (cvc && cvc->body && cvc->body->certificate_holder_reference |
92 | 0 | && ASN1_STRING_length(cvc->body->certificate_holder_reference) == chr_len |
93 | 0 | && 0 == memcmp(ASN1_STRING_get0_data(cvc->body->certificate_holder_reference), |
94 | 0 | chr, chr_len)) { |
95 | 0 | ok = 1; |
96 | 0 | break; |
97 | 0 | } |
98 | 0 | } |
99 | |
|
100 | 0 | err: |
101 | 0 | if(in) |
102 | 0 | BIO_free(in); |
103 | |
|
104 | 0 | return ok; |
105 | 0 | } |
106 | | |
107 | | static int CVC_find_chr_in_directory(const unsigned char *chr, size_t chr_len, |
108 | | const char *dir, CVC_CERT **cv_certificate) |
109 | 0 | { |
110 | 0 | int ok = 0, r; |
111 | 0 | char path[1024]; |
112 | |
|
113 | 0 | if (!is_chr(chr, chr_len)) |
114 | 0 | goto err; |
115 | | |
116 | 0 | if(strlen(dir)+1+chr_len+5 > sizeof path) |
117 | 0 | goto err; |
118 | | |
119 | 0 | r = BIO_snprintf(path, sizeof path, "%s/%s", dir, chr); |
120 | 0 | if (r <= 0) |
121 | 0 | goto err; |
122 | | |
123 | 0 | if(!CVC_find_chr_in_file(chr, chr_len, path, cv_certificate)) |
124 | 0 | goto err; |
125 | | |
126 | 0 | ok = 1; |
127 | |
|
128 | 0 | err: |
129 | 0 | return ok; |
130 | 0 | } |
131 | | |
132 | | CVC_CERT *CVC_default_lookup(const unsigned char *chr, size_t chr_len) |
133 | 0 | { |
134 | 0 | CVC_CERT *cvc = NULL; |
135 | |
|
136 | 0 | if (!CVC_find_chr_in_directory(chr, chr_len, cvc_default_dir, &cvc)) { |
137 | 0 | CVC_CERT_free(cvc); |
138 | 0 | cvc = NULL; |
139 | 0 | } |
140 | |
|
141 | 0 | return cvc; |
142 | 0 | } |
143 | | |
144 | | CVC_lookup_cvca_cert EAC_get_default_cvca_lookup(void) |
145 | 0 | { |
146 | 0 | return CVC_default_lookup; |
147 | 0 | } |
148 | | |
149 | | int EAC_CTX_set_cvca_lookup(EAC_CTX *ctx, CVC_lookup_cvca_cert lookup_cvca_cert) |
150 | 0 | { |
151 | 0 | int ok = 0; |
152 | |
|
153 | 0 | check (ctx && ctx->ta_ctx, "Invalid EAC context"); |
154 | 0 | ctx->ta_ctx->lookup_cvca_cert = lookup_cvca_cert; |
155 | 0 | ok = 1; |
156 | |
|
157 | 0 | err: |
158 | 0 | return ok; |
159 | 0 | } |
160 | | |
161 | | int EAC_CTX_get_cvca_lookup(const EAC_CTX *ctx, CVC_lookup_cvca_cert *lookup_cvca_cert) |
162 | 0 | { |
163 | 0 | int ok = 0; |
164 | |
|
165 | 0 | check (lookup_cvca_cert && ctx && ctx->ta_ctx, "Invalid parameters"); |
166 | 0 | *lookup_cvca_cert = ctx->ta_ctx->lookup_cvca_cert; |
167 | 0 | ok = 1; |
168 | |
|
169 | 0 | err: |
170 | 0 | return ok; |
171 | 0 | } |