summaryrefslogtreecommitdiff
path: root/other/sslmim/dca.cc
diff options
context:
space:
mode:
authorRoot THC2026-02-24 12:42:47 +0000
committerRoot THC2026-02-24 12:42:47 +0000
commitc9cbeced5b3f2bdd7407e29c0811e65954132540 (patch)
treeaefc355416b561111819de159ccbd86c3004cf88 /other/sslmim/dca.cc
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'other/sslmim/dca.cc')
-rw-r--r--other/sslmim/dca.cc234
1 files changed, 234 insertions, 0 deletions
diff --git a/other/sslmim/dca.cc b/other/sslmim/dca.cc
new file mode 100644
index 0000000..9b42f0e
--- /dev/null
+++ b/other/sslmim/dca.cc
@@ -0,0 +1,234 @@
1/*
2 * Copyright (C) 2001 Sebastian Krahmer.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Sebastian Krahmer.
16 * 4. The name Sebastian Krahmer may not be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32#include "session.h"
33#include "misc.h"
34#include <stdio.h>
35#include <string.h>
36#include <sys/types.h>
37#include <unistd.h>
38#include <openssl/ssl.h>
39#include <openssl/bio.h>
40#include <openssl/asn1.h>
41
42using namespace NS_Misc;
43
44extern bool use_subject_for_issuer;
45
46namespace NS_DCA {
47
48#ifndef MBSTRING_ASC
49#warning "You use outdated openssl lib."
50#define MBSTRING_ASC (0x1000|1)
51#endif
52
53// Note that 'subject' can be actually an issuer too.
54// both, subject and issuer change is done by that function
55char *change_name(X509_NAME *subject, char *peer_subject, bool ca_team)
56{
57 struct {
58 char C[256], ST[256], L[256], O[256], OU[256],
59 CN[256], Email[256];
60 } sub;
61 int len = 0;
62
63 memset(&sub, 0, sizeof(sub));
64 char *s = peer_subject;
65
66 // begin ugly parsing ...
67 if (strstr(s, "/C=")) {
68 s = strstr(s, "/C=") + 3;
69 len = strchr(s, '/') ? strchr(s, '/') - s : strlen(s);
70 memcpy(sub.C, s, len < 256 ? len : 255);
71 s += len;
72 }
73 if (strstr(s, "/ST=")) {
74 s = strstr(s, "/ST=") + 4;
75 len = strchr(s, '/') ? strchr(s, '/') - s : strlen(s);
76 memcpy(sub.ST, s, len < 256 ? len : 255);
77 s += len;
78 }
79
80 if (strstr(s, "/L=")) {
81 s = strstr(s, "/L=") + 3;
82 len = strchr(s, '/') ? strchr(s, '/') - s : strlen(s);
83 memcpy(sub.L, s, len < 256 ? len : 255);
84 s += len;
85 }
86
87 if (strstr(s, "/O=")) {
88 s = strstr(s, "/O=") + 3;
89 len = strchr(s, '/') ? strchr(s, '/') - s : strlen(s);
90 memcpy(sub.O, s, len < 256 ? len : 255);
91 s += len;
92 }
93
94 if (strstr(s, "/OU=")) {
95 s = strstr(s, "/OU=") + 4;
96 len = strchr(s, '/') ? strchr(s, '/') - s : strlen(s);
97 memcpy(sub.OU, s, len < 256 ? len : 255);
98 s += len;
99 }
100
101 if (strstr(s, "/CN=")) {
102 s = strstr(s, "/CN=") + 4;
103 len = strchr(s, '/') ? strchr(s, '/') - s : strlen(s);
104 memcpy(sub.CN, s, len < 256 ? len : 255);
105 s += len;
106 }
107
108 if (strstr(s, "/Email=")) {
109 s = strstr(s, "/Email=") + 7;
110 len = strchr(s, '/') ? strchr(s, '/') - s : strlen(s);
111 memcpy(sub.Email, s, len < 256 ? len : 255);
112 s += len;
113 }
114
115 if (sub.C[0])
116 X509_NAME_add_entry_by_txt(subject,"C",
117 MBSTRING_ASC, (unsigned char*)sub.C, -1, -1, -1);
118
119 if (sub.ST[0])
120 X509_NAME_add_entry_by_txt(subject,"ST",
121 MBSTRING_ASC, (unsigned char*)sub.ST, -1, -1, -1);
122
123 if (sub.L[0])
124 X509_NAME_add_entry_by_txt(subject,"L",
125 MBSTRING_ASC, (unsigned char*)sub.L, -1, -1, -1);
126
127 if (sub.O[0])
128 X509_NAME_add_entry_by_txt(subject,"O",
129 MBSTRING_ASC, (unsigned char*)sub.O, -1, -1, -1);
130
131 if (ca_team) {
132 char fake[1024];
133 memset(fake, 0, sizeof(fake));
134 snprintf(fake, sizeof(fake), "%s ", sub.OU);
135 X509_NAME_add_entry_by_txt(subject,"OU",
136 MBSTRING_ASC, (unsigned char*)fake, //"CA-Team",
137 -1, -1, -1);
138 } else {
139 X509_NAME_add_entry_by_txt(subject,"OU",
140 MBSTRING_ASC, (unsigned char*)sub.OU,
141 -1, -1, -1);
142 }
143
144 if (sub.CN[0])
145 X509_NAME_add_entry_by_txt(subject,"CN",
146 MBSTRING_ASC, (unsigned char*)sub.CN, -1, -1, -1);
147
148 if (sub.Email[0])
149 X509_NAME_add_entry_by_txt(subject,"Email",
150 MBSTRING_ASC, (unsigned char*)sub.Email, -1, -1, -1);
151
152 return strdup(sub.CN);
153}
154
155
156// Do the somewhat tricky dynamic certificate assembly
157// which puts "apropriate" subject and public key into
158// X509 cert.
159int do_dca(CSession *client, SSession *server)
160{
161 char l[1024];
162
163 X509 *peer_cert = SSL_get_peer_certificate(client->ssl());
164
165 if (!peer_cert) {
166 log("Nuts, no server-certificate");
167 return 0;
168 }
169
170 char *peer_subject = X509_NAME_oneline(
171 X509_get_subject_name(peer_cert), NULL, 0);
172 char *peer_issuer = X509_NAME_oneline(
173 X509_get_issuer_name(peer_cert), NULL, 0);
174
175 log(peer_subject);
176 log(peer_issuer);
177
178 // name of algo which is used by server
179 // (WE are client, and so 'client' is connection
180 // to real server
181 const char *algo = SSL_get_cipher(client->ssl());
182
183 snprintf(l, sizeof(l), "Using cipher %s", algo);
184 log(l);
185
186 // what we loaded with load_keys()
187 X509 *our_cert = SSL_get_certificate(server->ssl());
188
189 X509_NAME *subject = X509_get_subject_name(our_cert);
190 X509_NAME *issuer = X509_get_issuer_name(our_cert);
191
192 // built our cert w/ subject of orig server
193 char *name = change_name(subject, peer_subject, 0);
194 X509_set_subject_name(our_cert, subject);
195
196 // if we must 'touch' issuer, we will adopt the
197 // the subject for the issuer, so that i.e. veri-signed
198 // cert's become self-signed :)
199 if (use_subject_for_issuer)
200 change_name(issuer, peer_subject, 1);
201 else
202 change_name(issuer, peer_issuer, 1);
203
204 X509_set_issuer_name(our_cert, issuer);
205
206 // finally, set serialnumber
207 ASN1_INTEGER *serial = X509_get_serialNumber(peer_cert);
208
209
210 if (serial)
211 X509_set_serialNumber(our_cert, serial);
212 else
213 log("Nuts, no serialnumber!");
214
215 if (name) {
216 // save fake-cert
217 char save_cert[1024];
218 snprintf(save_cert, sizeof(save_cert), "./cert_of_%s.%d",
219 name, getpid());
220
221 FILE *f = fopen(save_cert, "w+");
222 if (!f)
223 return 0;
224 BIO *bio = BIO_new_fp(f, 0);
225 PEM_write_bio_X509(bio, our_cert);
226 BIO_flush(bio);
227 fclose(f);
228 free(name);
229 }
230 return 0;
231}
232
233}; // namespace NS_DCA
234