]> git.pld-linux.org Git - packages/postfix.git/blob - postfix-ssl.patch
- two fixes in ipv6 patch:
[packages/postfix.git] / postfix-ssl.patch
1 diff -Nur snapshot-20010228-orig/Makefile.in snapshot-20010228/Makefile.in
2 --- snapshot-20010228-orig/Makefile.in  Wed Mar 21 13:26:27 2001
3 +++ snapshot-20010228/Makefile.in       Wed Mar 21 13:35:29 2001
4 @@ -6,7 +6,7 @@
5         src/lmtp src/trivial-rewrite src/qmgr src/smtp src/bounce src/pipe \
6         src/showq src/postalias src/postcat src/postconf src/postdrop \
7         src/postkick src/postlock src/postlog src/postmap src/postsuper \
8 -       src/nqmgr src/spawn src/flush src/virtual # proto man html
9 +       src/nqmgr src/spawn src/flush src/virtual src/tlsmgr # proto man html
10  
11  default: update
12  
13 diff -Nur snapshot-20010228-orig/conf/master.cf snapshot-20010228/conf/master.cf
14 --- snapshot-20010228-orig/conf/master.cf       Wed Mar 21 13:26:22 2001
15 +++ snapshot-20010228/conf/master.cf    Wed Mar 21 13:32:23 2001
16 @@ -68,10 +68,13 @@
17  #              (yes)   (yes)   (yes)   (never) (50)
18  # ==========================================================================
19  smtp     inet  n       -       n       -       -       smtpd
20 +#smtps     inet  n       -       y       -       -       smtpd -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes
21 +#submission inet n       -       y       -       -       smtpd -o smtpd_enforce_tls=yes -o smtpd_sasl_auth_enable=yes
22  pickup   fifo  n       n       n       60      1       pickup
23  cleanup          unix  -       -       n       -       0       cleanup
24  qmgr     fifo  n       -       n       300     1       qmgr
25  #qmgr    fifo  n       -       n       300     1       nqmgr
26 +tlsmgr   fifo  -       -       n       300     1       tlsmgr
27  rewrite          unix  -       -       n       -       -       trivial-rewrite
28  bounce   unix  -       -       n       -       0       bounce
29  defer    unix  -       -       n       -       0       bounce
30 diff -Nur snapshot-20010228-orig/conf/sample-smtp.cf snapshot-20010228/conf/sample-smtp.cf
31 --- snapshot-20010228-orig/conf/sample-smtp.cf  Wed Mar 21 13:26:23 2001
32 +++ snapshot-20010228/conf/sample-smtp.cf       Wed Mar 21 13:32:23 2001
33 @@ -145,6 +145,14 @@
34  #
35  smtp_helo_timeout = 300s
36  
37 +# The smtp_starttls_timeout parameter limits the time in seconds to write and
38 +# read operations during TLS start and stop handhake procedures.
39 +#
40 +# In case of problems the client does NOT try the next address on
41 +# the mail exchanger list.
42 +#
43 +# smtp_starttls_timeout = 300s
44 +
45  # The smtp_mail_timeout parameter specifies the SMTP client timeout
46  # for sending the SMTP MAIL FROM command, and for receiving the server
47  # response.
48 diff -Nur snapshot-20010228-orig/conf/sample-smtpd.cf snapshot-20010228/conf/sample-smtpd.cf
49 --- snapshot-20010228-orig/conf/sample-smtpd.cf Wed Mar 21 13:26:23 2001
50 +++ snapshot-20010228/conf/sample-smtpd.cf      Wed Mar 21 13:32:23 2001
51 @@ -73,6 +73,11 @@
52  # 
53  strict_rfc821_envelopes = no
54  
55 +# The smtpd_starttls_timeout parameter limits the time in seconds to write and
56 +# read operations during TLS start and stop handhake procedures.
57 +#
58 +# smtpd_starttls_timeout = 300s
59 +
60  #
61  # TARPIT CONTROLS
62  #
63 diff -Nur snapshot-20010228-orig/conf/sample-tls.cf snapshot-20010228/conf/sample-tls.cf
64 --- snapshot-20010228-orig/conf/sample-tls.cf   Thu Jan  1 01:00:00 1970
65 +++ snapshot-20010228/conf/sample-tls.cf        Wed Mar 21 13:32:23 2001
66 @@ -0,0 +1,483 @@
67 +# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
68 +# HERE JUST SERVES AS AN EXAMPLE.
69 +#
70 +# This file contains example settings of Postfix configuration
71 +# parameters that control the behaviour of the TLS extensions.
72 +#
73 +# We strictly seperate between server side TLS (smtpd_) and client side
74 +# TLS (smtp_), as for practical reasons we might choose differently.
75 +
76 +# Section with SMTPD specific settings
77 +
78 +# To use TLS we do need a certificate and a private key. Both must be in
79 +# "pem" format, the private key must not be encrypted, that does mean:
80 +# it must be accessable without password. Both parts (certificate and
81 +# private key) may be in the same file.
82 +#
83 +# Both RSA and DSA are certificates are supported. Typically you will only
84 +# have RSA certificates issued by a commercial CA, also the tools supplied
85 +# with OpenSSL will by default issue RSA certificates.
86 +# You can have both at the same time, in this case the cipher used decides,
87 +# which certificate is presented. For Netscape and OpenSSL clients without
88 +# special cipher choices, the RSA certificate is preferred.
89 +#
90 +# In order to check the certificates, the CA-certificate (in case of a
91 +# certificate chain, all CA-certificates) must be available.
92 +# You should add these certificates to the server certificate, the server
93 +# certificate first, then the issuing CA(s).
94 +#
95 +# Example: the certificate for "server.dom.ain" was issued by "intermediate CA"
96 +# which itself has a certificate of "root CA". Create the server.pem file by
97 +# 'cat server_cert.pem intemediate_CA.pem root_CA.pem > server.pem'
98 +#
99 +# If you want to accept certificates issued by these CAs yourself, you can
100 +# also add the CA-certificates to the smtpd_tls_CAfile, in which case it is
101 +# not necessary to have them in the smtpd_tls_[d]cert_file.
102 +#
103 +# A certificate supplied here must be useable as SSL server certificate and
104 +# hence pass the "openssl verify -purpose sslserver ..." test.
105 +#
106 +smtpd_tls_cert_file = /etc/postfix/server.pem
107 +smtpd_tls_key_file = $smtpd_tls_cert_file
108 +#
109 +# Its DSA counterparts:
110 +smtpd_tls_dcert_file = /etc/postfix/server-dsa.pem
111 +smtpd_tls_dkey_file = $smtpd_tls_dcert_file
112 +
113 +# The certificate was issued by a certification authority (CA), the CA-cert
114 +# of which must be available, if not in the certificate file.
115 +# This file may also contain the the CA certificates of other trusted CAs.
116 +# You must use this file for the list of trusted CAs if you want to use
117 +# chroot-mode. No default is supplied for this value as of now.
118 +#
119 +# smtpd_tls_CAfile = /etc/postfix/CAcert.pem
120 +
121 +# To verify the peer certificate, we need to know the certificates of
122 +# certification authorities. These certificates in "pem" format are
123 +# collected in a directory. The same CAs are offered to clients for
124 +# client verification. Don't forget to create the necessary "hash"
125 +# links with $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs. A typical
126 +# place for the CA-certs may also be $OPENSSL_HOME/certs, so there is
127 +# no default and you explicitly have to set the value here!
128 +#
129 +# To use this option in chroot mode, this directory itself or a copy of it
130 +# must be inside the chroot jail. Please note also, that the CAs in this
131 +# directory are not listed to the client, so that e.g. Netscape might not
132 +# offer certificates issued by them.
133 +#
134 +# I therefore discourage the use of this option.
135 +#
136 +smtpd_tls_CApath = /etc/postfix/certs
137 +
138 +# To get additional information during the TLS setup and negotiations
139 +# you can increase the loglevel from 0..4:
140 +# 0: No output about the TLS subsystem
141 +# 1: Printout startup and certificate information
142 +# 2: 1 + Printout of levels during negotiation
143 +# 3: 2 + Hex and ASCII dump of negotiation process
144 +# 4: 3 + Hex and ASCII dump of complete transmission after STARTTLS
145 +# Use loglevel 3 only in case of problems. Use of loglevel 4 is strongly
146 +# discouraged.
147 +#
148 +# smtpd_tls_loglevel = 0
149 +
150 +# To include information about the protocol and cipher used as well as the
151 +# client and issuer CommonName into the "Received:" header, set the
152 +# smtpd_tls_received_header variable to true. The default is no, as the
153 +# information is not necessarily authentic. Only the final destination
154 +# is reliable, since the headers might have been changed in between.
155 +#
156 +#smtpd_tls_received_header = yes
157 +
158 +# By default TLS is disabled, so no difference to plain postfix is visible.
159 +# Explicitely switch it on here:
160 +#
161 +smtpd_use_tls = yes
162 +
163 +# You can ENFORCE the use of TLS, so that no commands (except QUIT of course)
164 +# are allowed without TLS. According to RFC2487 this MUST NOT be applied
165 +# in case of a publicly-referenced SMTP server. So this option is off
166 +# by default and should only seldom be used. Using this option implies
167 +# smtpd_use_tls = yes
168 +#
169 +# smtpd_enforce_tls = no
170 +
171 +# Besides RFC2487 some clients, namely Outlook [Express] prefer to run the
172 +# non-standard "wrapper" mode, not the STARTTLS enhancement to SMTP.
173 +# This is true for OE (Win32 < 5.0 and Win32 >=5.0 when run on a port!=25
174 +# and OE (5.01 Mac on all ports).
175 +# It is strictly discouraged to use this mode from main.cf. If you want to
176 +# support this service, enable a special port in master.cf. Port 465 (smtps)
177 +# was once chosen for this feature.
178 +#
179 +# smtpd_tls_wrappermode = no
180 +
181 +# To receive a client certificate, the server must explicitly ask for one.
182 +# Hence netscape will either complain if no certificate is available (for
183 +# the list of CAs in /etc/postfix/certs) or will offer you client certificates
184 +# to choose from. This might be annoying, so this option is "off" by default.
185 +# You will however need the certificate if you want to to e.g. certificate
186 +# based relaying.
187 +#
188 +# smtpd_tls_ask_ccert = no
189 +
190 +# You may also decide to REQUIRE a client certificate to allow TLS connections.
191 +# I don't think it will be necessary often, it is however included here for
192 +# completeness. This option implies smtpd_tls_ask_ccert = yes
193 +#
194 +# Please be aware, that this will inhibit TLS connections without a proper
195 +# certificate and only makes sense, when normal submission is disabled and
196 +# TLS is enforced (smtpd_enforce_tls). Otherwise clients may bypass by simply
197 +# not using STARTTLS at all. When TLS is not enforced, the connection will be
198 +# handled, as if only smtpd_tls_ask_ccert = yes would be set and an information
199 +# is logged.
200 +#
201 +# smtpd_tls_req_ccert = no
202 +
203 +# The verification depth for client certificates. A depth of 1 is sufficient,
204 +# if the certificate ist directly issued by a CA listed in the CA locations.
205 +# The default value (5) should also suffice for longer chains (root CA issues
206 +# special CA which then issues the actual certificate...)
207 +#
208 +# smtpd_tls_ccert_verifydepth = 5
209 +
210 +# The server and client negotiate a session, which takes some computer time
211 +# and network bandwidth. The session is cached only in the smtpd process
212 +# actually using this session and is lost when the process dies.
213 +# To share the session information between the smtpd processes, a disc based
214 +# session cache can be used based on the SDBM databases (routines included
215 +# in Postfix/TLS). Since concurrent writing must be supported, only SDBM
216 +# can be used.
217 +#
218 +smtpd_tls_session_cache_database = sdbm:/etc/postfix/smtpd_scache
219 +
220 +# The cached sessions time out after a certain amount of time. For Postfix/TLS
221 +# I do not use the OpenSSL default of 300sec, but a longer time of 3600sec
222 +# (=1 hour). RFC2246 recommends a maximum of 24 hours.
223 +#
224 +# smtpd_tls_session_cache_timeout = 3600s
225 +
226 +# Two additional options has been added for relay control to the UCE rules:
227 +#   permit_tls_clientcerts     (a)
228 +# and
229 +#   permit_tls_all_clientcerts. (b)
230 +#
231 +# If one of these options is added to
232 +#   smtpd_recipient_restrictions,
233 +# postfix will relay if 
234 +# (a) a valid (it passed the verification) client certificate is presented
235 +#     and its fingerprint is listed in the list of client certs
236 +#     (relay_clientcerts),
237 +# (b) any valid (it passed the verification) client certificate is presented.
238 +#
239 +# Option (b) must only be used, if a special CA issues the certificates and
240 +# only this CA is listed as trusted CA. If other CAs are trusted, any owner
241 +# of a valid (SSL client)-certificate can relay. Option (b) can be practical
242 +# for a specically created email relay. It is however recommended to stay with
243 +# option (a) and list all certificates, as (b) does not permit any control
244 +# when a certificate must no longer be used (e.g. an employee leaving).
245 +#
246 +# smtpd_recipient_restrictions = ... permit_tls_clientcerts ...
247 +
248 +# The list of client certificates for which relaying will be allowed.
249 +# Unfortunately the routines for lists in postfix use whitespaces as
250 +# seperators and choke on special chars. So using the certificate
251 +# X509ONELINES is quite impractical. We will use the fingerprints at
252 +# this point, as they are difficult to fake but easy to use for lookup.
253 +# As postmap (when using e.g. db) insists of having a pair of key and value,
254 +# but we only need the key, the value can be chosen freely, e.g. the name
255 +# of the user or host:
256 +# D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 lutzpc.at.home
257 +#
258 +# relay_clientcerts = hash:/etc/postfix/relay_clientcerts
259 +
260 +# To influence the cipher selection scheme, you can give cipherlist-string.
261 +# A detailed description would go to far here, please refer to the openssl
262 +# documentation.
263 +# If you don't know what to do with it, simply don't touch it and leave the
264 +# (openssl-)compiled in default!
265 +#
266 +# DO NOT USE " to enclose the string, just the string!!!
267 +#
268 +# smtpd_tls_cipherlist = DEFAULT
269 +
270 +# If you want to take advantage of ciphers with EDH, DH parameters are needed.
271 +# There are built in DH parameters for both 1025bit and 512bit available. It
272 +# is however better to have "own" parameters, since otherwise it would "pay"
273 +# for a possible attacker to start a brute force attack against these
274 +# parameters commonly used by everybody. For this reason, the parameters
275 +# chosen are already different from those distributed with other TLS packages.
276 +#
277 +# To generate your own set of parameters, use
278 +# openssl gendh -out /etc/postfix/dh_1024.pem -2 -rand /var/run/egd-pool 1024
279 +# openssl gendh -out /etc/postfix/dh_512.pem -2 -rand /var/run/egd-pool 512
280 +# (your source for "entropy" might vary; on Linux there is /dev/random, on
281 +# other system, you might consider the "Entropy Gathering Daemon EGD", 
282 +# available at http://www.lothar.com/tech/crypto/.
283 +#
284 +smtpd_tls_dh1024_param_file = /etc/postfix/dh_1024.pem
285 +smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem
286 +
287 +# The smtpd_starttls_timeout parameter limits the time in seconds to write and
288 +# read operations during TLS start and stop handhake procedures.
289 +#
290 +# smtpd_starttls_timeout = 300s
291 +
292 +# Section with SMTP specific settings
293 +
294 +# During the startup negotiation we might present a certificate to the server.
295 +# Netscape is rather clever here and lets the user select between only those
296 +# certs that will match the CAs accepted from the server. As I simply use
297 +# the integrated "SSL_connect()" from the OpenSSL package, this is not
298 +# possible by now and we have to chose just one cert.
299 +# So for now the default is to use _no_ cert and key unless explictly
300 +# set here. It is possible to use the same key/cert pair as for the server.
301 +# If a cert is to be presented, it must be in "pem" format, the private key
302 +# must not be encrypted, that does mean: it must be accessable without
303 +# password. Both parts (certificate and private key) may be in the
304 +# same file.
305 +#
306 +# In order to check the certificates, the CA-certificate (in case of a
307 +# certificate chain, all CA-certificates) must be available.
308 +# You should add these certificates to the server certificate, the server
309 +# certificate first, then the issuing CA(s).
310 +#
311 +# Example: the certificate for "client.dom.ain" was issued by "intermediate CA"
312 +# which itself has a certificate of "root CA". Create the client.pem file by
313 +# 'cat client_cert.pem intemediate_CA.pem root_CA.pem > client.pem'
314 +#
315 +# If you want to accept certificates issued by these CAs yourself, you can
316 +# also add the CA-certificates to the smtp_tls_CAfile, in which case it is
317 +# not necessary to have them in the smtp_tls_[d]cert_file.
318 +#
319 +# A certificate supplied here must be useable as SSL client certificate and
320 +# hence pass the "openssl verify -purpose sslclient ..." test.
321 +#
322 +smtp_tls_cert_file = /etc/postfix/client.pem
323 +smtp_tls_key_file = $smtp_tls_cert_file
324 +
325 +# The certificate was issued by a certification authority (CA), the CA-cert
326 +# of which must be available, if not in the certificate file.
327 +# This file may also contain the the CA certificates of other trusted CAs.
328 +# You must use this file for the list of trusted CAs if you want to use
329 +# chroot-mode. No default is supplied for this value as of now.
330 +#
331 +smtp_tls_CAfile = /etc/postfix/CAcert.pem
332 +
333 +# To verify the peer certificate, we need to know the certificates of
334 +# certification authorities. These certificates in "pem" format are
335 +# collected in a directory. Don't forget to create the necessary "hash"
336 +# links with $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs. A typical
337 +# place for the CA-certs may also be $OPENSSL_HOME/certs, so there is
338 +# no default and you explicitly have to set the value here!
339 +#
340 +# To use this option in chroot mode, this directory itself or a copy of it
341 +# must be inside the chroot jail.
342 +#
343 +smtp_tls_CApath = /etc/postfix/certs
344 +
345 +# To get additional information during the TLS setup and negotiations
346 +# you can increase the loglevel from 0..4:
347 +# 0: No output about the TLS subsystem
348 +# 1: Printout startup and certificate information
349 +# 2: 1 + Printout of levels during negotiation
350 +# 3: 2 + Hex and ASCII dump of negotiation process
351 +# 4: 3 + Hex and ASCII dump of complete transmission after STARTTLS
352 +# Use loglevel 3 only in case of problems. Use of loglevel 4 is strongly
353 +# discouraged.
354 +#
355 +smtp_tls_loglevel = 0
356 +
357 +# The server and client negotiate a session, which takes some computer time
358 +# and network bandwidth. The session is cached only in the smtpd process
359 +# actually using this session and is lost when the process dies.
360 +# To share the session information between the smtp processes, a disc based
361 +# session cache can be used based on the SDBM databases (routines included
362 +# in Postfix/TLS). Since concurrent writing must be supported, only SDBM
363 +# can be used.
364 +#
365 +smtp_tls_session_cache_database = sdbm:/etc/postfix/smtp_scache
366 +
367 +# The cached sessions time out after a certain amount of time. For Postfix/TLS
368 +# I do not use the OpenSSL default of 300sec, but a longer time of 3600sec
369 +# (=1 hour). RFC2246 recommends a maximum of 24 hours.
370 +#
371 +# smtp_tls_session_cache_timeout = 3600s
372 +
373 +# By default TLS is disabled, so no difference to plain postfix is visible.
374 +# If you enable TLS it will be used when offered by the server.
375 +# WARNING: I didn't have access to other software (except those explicitely
376 +# listed) to test the interaction. On corresponding mailing list
377 +# there was a discussion going on about MS exchange servers offering
378 +# STARTTLS even if it is not configured, so it might be wise to not
379 +# use this option on your central mail hub, as you don't know in advance
380 +# whether you are going to hit such host. Use the recipient/site specific
381 +# options instead.
382 +# HINT: I have it switched on on my mailservers and did experience one
383 +# single failure since client side TLS is implemented. (There was one
384 +# misconfired MS Exchange server; I contacted ths admin.) Hence, I am happy
385 +# with it running all the time, but I am interested in testing anyway.
386 +# You have been warned, however :-)
387 +#
388 +# In case of failure, a "4xx" code is issued and the mail stays in the queue.
389 +#
390 +# Explicitely switch it on here, if you want it.
391 +#
392 +smtp_use_tls = yes
393 +
394 +# You can ENFORCE the use of TLS, so that only connections with TLS will
395 +# be accepted. Additionally, the hostname of the receiving host is matched
396 +# against the CommonName in the certificate. Also, the certificate must
397 +# be verified "Ok", so that a CA trusted by the client must have issued
398 +# the certificate. If the certificate doesn't verify or the hostname doesn't
399 +# match, a "4xx" will be issued and the mail stays in the queue.
400 +# The hostname used in the check is beyond question, as it must be the
401 +# principle hostname (no CNAME allowed here).
402 +# The behaviour may be changed with the smtp_tls_enforce_peername option
403 +#
404 +# This option is useful only if you are definitely sure that you will only
405 +# connect to servers supporting RFC2487 _and_ with valid certificates.
406 +# I use it for my clients which will only send email to one mailhub, which
407 +# does offer the necessary STARTTLS support.
408 +#
409 +# smtp_enforce_tls = no
410 +
411 +# As of RFC2487 the requirements for hostname checking for MTA clients are
412 +# not set. When in smtp_enforce_tls mode, the option smtp_tls_enforce_peername
413 +# can be set to "no" to disable strict peername checking. In this case, the
414 +# mail delivery will be continued, if a TLS connection was established
415 +# _and_ the peer certificate passed verification _but_ regardless of the
416 +# CommonName listed in the certificate. This option only applies to the
417 +# default setting smtp_enforce_tls_mode, special settings in the
418 +# smtp_tls_per_site table override smtp_tls_enforce_peername.
419 +#
420 +# This can make sense in closed environment where special CAs are created.
421 +# If not used carefully, this option opens the danger of a "man-in-the-middle"
422 +# attack (the CommonName of this attacker is logged).
423 +#
424 +# smtp_tls_enforce_peername = yes
425 +
426 +# As generally trying TLS can be a bad idea (some hosts offer STARTTLS but
427 +# the negotiation will fail leading to unexplainable failures, it may be
428 +# a good idea to decide based on the recipient or the mailhub to which you are
429 +# connecting.
430 +#
431 +# Deciding per recipient may be difficult, since a singe email can have
432 +# several recipients. We use the "nexthop" mechanism inside postfix.
433 +# When an email is to be delivered, the "nexthop" is obtained. If it matches
434 +# an entry in the smtp_tls_per_site list, appropriate action is taken.
435 +# Since entries in the transport table or the use of a relay_host override
436 +# the nexthop setting, in these cases the relay_host etc must be listed
437 +# in the table. In any case, the hostname of the peer to be contacted is
438 +# looked up (that is: the MX or the name of the host, if no MX is given).
439 +#
440 +# Special hint for enforcement mode:
441 +# Since there is no secure mechanism for DNS lookups available, the
442 +# recommended setup is: put the sensible domains with their mailhost
443 +# into the transport table (since you can asure security of this table
444 +# unlike DNS), then set MUST mode for this mailhost.
445 +#
446 +# Format of the table:
447 +# The keys entries are on the left hand side, no wildcards allowed. On the
448 +# right hand side the keywords NONE (don't use TLS at all), MAY (try to use
449 +# STARTTLS if offered, no problem if not), MUST (enforce usage of STARTTLS,
450 +# check server certificate CommonName against server FQDN), MUST_NOPEERMATCH
451 +# (enforce usage of STARTTLS and verify certificate, but ignore differences
452 +# between CommonName and server FQDN).
453 +# dom.ain              NONE
454 +# host.dom.ain         MAY
455 +# important.host       MUST
456 +# some.host.dom.ain    MUST_NOPEERMATCH
457 +#
458 +# If an entry is not matched, the default policy is applied; if the default
459 +# policy is "enforce", NONE explicitely switches it off, otherwise the
460 +# "enforce" mode is used even for MAY entries.
461 +#
462 +smtp_tls_per_site = hash:/etc/postfix/tls_per_site
463 +
464 +# The verification depth for server certificates. A depth of 1 is sufficient,
465 +# if the certificate ist directly issued by a CA listed in the CA locations.
466 +# The default value (5) should also suffice for longer chains (root CA issues
467 +# special CA which then issues the actual certificate...)
468 +#
469 +# smtp_tls_scert_verifydepth = 5
470 +
471 +# As we decide on a "per site" basis, wether to use TLS or not, it would be
472 +# good to have a list of sites, that offered "STARTTLS'. We can collect it
473 +# ourselves with this option.
474 +#
475 +# If activated and TLS is not already enabled for this host, a line is added
476 +# to the logfile:
477 +# postfix/smtp[pid]: Host offered STARTTLS: [name.of.host]
478 +#
479 +smtp_tls_note_starttls_offer = yes
480 +
481 +# To influence the cipher selection scheme, you can give cipherlist-string.
482 +# A detailed description would go to far here, please refer to the openssl
483 +# documentation.
484 +# If you don't know what to do with it, simply don't touch it and leave the
485 +# (openssl-)compiled in default!
486 +#
487 +# DO NOT USE " to enclose the string, just the string!!!
488 +#
489 +# smtp_tls_cipherlist = DEFAULT
490 +
491 +# The smtp_starttls_timeout parameter limits the time in seconds to write and
492 +# read operations during TLS start and stop handhake procedures.
493 +#
494 +# In case of problems the client does NOT try the next address on
495 +# the mail exchanger list.
496 +#
497 +# smtp_starttls_timeout = 300s
498 +
499 +# In order to seed the PRNG Pseude Random Number Generator, random data is
500 +# needed. The PRNG pool is maintained by the "tlsmgr" daemon and is used
501 +# (read) by the smtp[d] processes after adding some more entropy by stirring
502 +# in time and process id.
503 +# The file, which is from time to time rewritten by the tlsmgr, is created
504 +# if not existant. A default value is given; the default should probably
505 +# be on the /var partition but _not_ inside chroot jail.
506 +#
507 +# tls_random_exchange_name = /etc/postfix/prng_exch
508 +
509 +# To feed the PRNG pool, entropy is being read from an external source,
510 +# both at startup and during run.
511 +# Specify a good entropy source here, like EGD or /dev/urandom; make sure
512 +# to only use non-blocking sources.
513 +# In both cases, 32 bytes are read at each re-seeding event (which is an
514 +# amount of 256bits and hence good enough for 128bit symmetric keys).
515 +# You must specify the type of source: "dev:" for a device special file
516 +# or "egd:" for a source with EGD compatible socket interface. A maximum
517 +# 255 bytes is read from these sources in each step.
518 +# If you specify a normal file, a larger amount of data can be read.
519 +#
520 +# The entropy source is queried again after a certain amount of time. The
521 +# time is calculated using the PRNG, it is between 0 and the time specified,
522 +# default is a maximum of 1 hour.
523 +#
524 +# tls_random_source = dev:/dev/urandom
525 +tls_random_source = egd:/var/run/egd-pool
526 +# tls_random_bytes = 32
527 +# tls_random_reseed_period = 3600s
528 +
529 +# The PRNG pool inside tlsmgr is used to re-generate the 1024 byte file
530 +# being read by smtp[d]. The time, after which the exchange file is
531 +# rewritten is calculated using the PRNG, it is between 0 and the time
532 +# specified, default is a maximum of 60 seconds.
533 +#
534 +# tls_random_upd_period = 60s
535 +
536 +# If you have a entropy source available, that is not easily drained (like
537 +# /dev/urandom), the daemons can also load additional entropy on startup from
538 +# the source specified. By default an amount of 32 bytes is read, the
539 +# equivalent to 256 bits. This is more than enough to generate a 128bit
540 +# (or 168bit) session key, but we may have to generate more than one.
541 +# Usage of this option may drain EGD (consider the case of 50 smtp starting
542 +# up with a full queue and "postfix start", which will request 1600bytes
543 +# of entropy). This is however not fatal, as long as "entropy" data could
544 +# be read from the exchange file.
545 +#
546 +# tls_daemon_random_source = dev:/dev/urandom
547 +tls_daemon_random_source = egd:/var/run/egd-pool
548 +# tls_daemon_random_bytes = 32
549 +
550 diff -Nur snapshot-20010228-orig/html/ssl/conf.html snapshot-20010228/html/ssl/conf.html
551 --- snapshot-20010228-orig/html/ssl/conf.html   Thu Jan  1 01:00:00 1970
552 +++ snapshot-20010228/html/ssl/conf.html        Wed Mar 21 13:38:29 2001
553 @@ -0,0 +1,537 @@
554 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
555 +<html>
556 +<head>
557 +<meta name="generator" content="HTML Tidy, see www.w3.org">
558 +<title>Postfix/TLS - Configuring main.cf and master.cf</title>
559 +</head>
560 +<body>
561 +<h1>Postfix/TLS - Configuring main.cf and master.cf</h1>
562 +
563 +To use the TLS extension you need to feed some information to
564 +postfix. Please see also the <code>conf/sample-tls.cf</code> file. 
565 +
566 +<h2>main.cf: smtpd (server) specific variables</h2>
567 +
568 +<pre>
569 +# To use TLS we do need a certificate and a private key. Both must be in
570 +# "pem" format, the private key must not be encrypted, that does mean:
571 +# it must be accessable without password. Both parts (certificate and
572 +# private key) may be in the same file.
573 +#
574 +# Both RSA and DSA are certificates are supported. Typically you will only
575 +# have RSA certificates issued by a commercial CA, also the tools supplied
576 +# with OpenSSL will by default issue RSA certificates.
577 +# You can have both at the same time, in this case the cipher used decides,
578 +# which certificate is presented. For Netscape and OpenSSL clients without
579 +# special cipher choices, the RSA certificate is preferred.
580 +#
581 +# In order to check the certificates, the CA-certificate (in case of a
582 +# certificate chain, all CA-certificates) must be available.
583 +# You should add these certificates to the server certificate, the server
584 +# certificate first, then the issuing CA(s).
585 +#
586 +# Example: the certificate for "server.dom.ain" was issued by "intermediate CA"
587 +# which itself has a certificate of "root CA". Create the server.pem file by
588 +# 'cat server_cert.pem intemediate_CA.pem root_CA.pem > server.pem'
589 +#
590 +# If you want to accept certificates issued by these CAs yourself, you can
591 +# also add the CA-certificates to the smtpd_tls_CAfile, in which case it is
592 +# not necessary to have them in the smtpd_tls_[d]cert_file.
593 +#
594 +# A certificate supplied here must be useable as SSL server certificate and
595 +# hence pass the "openssl verify -purpose sslserver ..." test.
596 +#
597 +smtpd_tls_cert_file = /etc/postfix/server.pem
598 +smtpd_tls_key_file = $smtpd_tls_cert_file
599 +#
600 +# Its DSA counterparts:
601 +smtpd_tls_dcert_file = /etc/postfix/server-dsa.pem
602 +smtpd_tls_dkey_file = $smtpd_tls_dcert_file
603 +
604 +# The certificate was issued by a certification authority (CA), the CA-cert
605 +# of which must be available, if not in the certificate file.
606 +# This file may also contain the the CA certificates of other trusted CAs.
607 +# You must use this file for the list of trusted CAs if you want to use
608 +# chroot-mode. No default is supplied for this value as of now.
609 +#
610 +# smtpd_tls_CAfile = /etc/postfix/CAcert.pem
611 +
612 +# To verify the peer certificate, we need to know the certificates of
613 +# certification authorities. These certificates in "pem" format are
614 +# collected in a directory. The same CAs are offered to clients for
615 +# client verification. Don't forget to create the necessary "hash"
616 +# links with $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs. A typical
617 +# place for the CA-certs may also be $OPENSSL_HOME/certs, so there is
618 +# no default and you explicitly have to set the value here!
619 +#
620 +# To use this option in chroot mode, this directory itself or a copy of it
621 +# must be inside the chroot jail. Please note also, that the CAs in this
622 +# directory are not listed to the client, so that e.g. Netscape might not
623 +# offer certificates issued by them.
624 +#
625 +# I therefore discourage the use of this option.
626 +#
627 +smtpd_tls_CApath = /etc/postfix/certs
628 +
629 +# To get additional information during the TLS setup and negotiations
630 +# you can increase the loglevel from 0..4:
631 +# 0: No output about the TLS subsystem
632 +# 1: Printout startup and certificate information
633 +# 2: 1 + Printout of levels during negotiation
634 +# 3: 2 + Hex and ASCII dump of negotiation process
635 +# 4: 3 + Hex and ASCII dump of complete transmission after STARTTLS
636 +# Use loglevel 3 only in case of problems. Use of loglevel 4 is strongly
637 +# discouraged.
638 +#
639 +# smtpd_tls_loglevel = 0
640 +
641 +# To include information about the protocol and cipher used as well as the
642 +# client and issuer CommonName into the "Received:" header, set the
643 +# smtpd_tls_received_header variable to true. The default is no, as the
644 +# information is not necessarily authentic. Only the final destination
645 +# is reliable, since the headers might have been changed in between.
646 +#
647 +#smtpd_tls_received_header = yes
648 +
649 +# By default TLS is disabled, so no difference to plain postfix is visible.
650 +# Explicitely switch it on here:
651 +#
652 +smtpd_use_tls = yes
653 +
654 +# You can ENFORCE the use of TLS, so that no commands (except QUIT of course)
655 +# are allowed without TLS. According to RFC2487 this MUST NOT be applied
656 +# in case of a publicly-referenced SMTP server. So this option is off
657 +# by default and should only seldom be used. Using this option implies
658 +# smtpd_use_tls = yes
659 +#
660 +# smtpd_enforce_tls = no
661 +
662 +# Besides RFC2487 some clients, namely Outlook [Express] prefer to run the
663 +# non-standard "wrapper" mode, not the STARTTLS enhancement to SMTP.
664 +# This is true for OE (Win32 < 5.0 and Win32 >=5.0 when run on a port!=25
665 +# and OE (5.01 Mac on all ports).
666 +# It is strictly discouraged to use this mode from main.cf. If you want to
667 +# support this service, enable a special port in master.cf. Port 465 (smtps)
668 +# was once chosen for this feature.
669 +#
670 +# smtpd_tls_wrappermode = no
671 +
672 +# To receive a client certificate, the server must explicitly ask for one.
673 +# Hence netscape will either complain if no certificate is available (for
674 +# the list of CAs in /etc/postfix/certs) or will offer you client certificates
675 +# to choose from. This might be annoying, so this option is "off" by default.
676 +# You will however need the certificate if you want to to e.g. certificate
677 +# based relaying.
678 +#
679 +# smtpd_tls_ask_ccert = no
680 +
681 +# You may also decide to REQUIRE a client certificate to allow TLS connections.
682 +# I don't think it will be necessary often, it is however included here for
683 +# completeness. This option implies smtpd_tls_ask_ccert = yes
684 +#
685 +# Please be aware, that this will inhibit TLS connections without a proper
686 +# certificate and only makes sense, when normal submission is disabled and
687 +# TLS is enforced (smtpd_enforce_tls). Otherwise clients may bypass by simply
688 +# not using STARTTLS at all. When TLS is not enforced, the connection will be
689 +# handled, as if only smtpd_tls_ask_ccert = yes would be set and an information
690 +# is logged.
691 +#
692 +# smtpd_tls_req_ccert = no
693 +
694 +# The verification depth for client certificates. A depth of 1 is sufficient,
695 +# if the certificate ist directly issued by a CA listed in the CA locations.
696 +# The default value (5) should also suffice for longer chains (root CA issues
697 +# special CA which then issues the actual certificate...)
698 +#
699 +# smtpd_tls_ccert_verifydepth = 5
700 +
701 +# The server and client negotiate a session, which takes some computer time
702 +# and network bandwidth. The session is cached only in the smtpd process
703 +# actually using this session and is lost when the process dies.
704 +# To share the session information between the smtpd processes, a disc based
705 +# session cache can be used based on the SDBM databases (routines included
706 +# in Postfix/TLS). Since concurrent writing must be supported, only SDBM
707 +# can be used.
708 +#
709 +smtpd_tls_session_cache_database = sdbm:/etc/postfix/smtpd_scache
710 +
711 +# The cached sessions time out after a certain amount of time. For Postfix/TLS
712 +# I do not use the OpenSSL default of 300sec, but a longer time of 3600sec
713 +# (=1 hour). RFC2246 recommends a maximum of 24 hours.
714 +#
715 +# smtpd_tls_session_cache_timeout = 3600s
716 +
717 +# Two additional options has been added for relay control to the UCE rules:
718 +#   permit_tls_clientcerts     (a)
719 +# and
720 +#   permit_tls_all_clientcerts. (b)
721 +#
722 +# If one of these options is added to
723 +#   smtpd_recipient_restrictions,
724 +# postfix will relay if 
725 +# (a) a valid (it passed the verification) client certificate is presented
726 +#     and its fingerprint is listed in the list of client certs
727 +#     (relay_clientcerts),
728 +# (b) any valid (it passed the verification) client certificate is presented.
729 +#
730 +# Option (b) must only be used, if a special CA issues the certificates and
731 +# only this CA is listed as trusted CA. If other CAs are trusted, any owner
732 +# of a valid (SSL client)-certificate can relay. Option (b) can be practical
733 +# for a specically created email relay. It is however recommended to stay with
734 +# option (a) and list all certificates, as (b) does not permit any control
735 +# when a certificate must no longer be used (e.g. an employee leaving).
736 +#
737 +# smtpd_recipient_restrictions = ... permit_tls_clientcerts ...
738 +
739 +# The list of client certificates for which relaying will be allowed.
740 +# Unfortunately the routines for lists in postfix use whitespaces as
741 +# seperators and choke on special chars. So using the certificate
742 +# X509ONELINES is quite impractical. We will use the fingerprints at
743 +# this point, as they are difficult to fake but easy to use for lookup.
744 +# As postmap (when using e.g. db) insists of having a pair of key and value,
745 +# but we only need the key, the value can be chosen freely, e.g. the name
746 +# of the user or host:
747 +# D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 lutzpc.at.home
748 +#
749 +# relay_clientcerts = hash:/etc/postfix/relay_clientcerts
750 +
751 +# To influence the cipher selection scheme, you can give cipherlist-string.
752 +# A detailed description would go to far here, please refer to the openssl
753 +# documentation.
754 +# If you don't know what to do with it, simply don't touch it and leave the
755 +# (openssl-)compiled in default!
756 +#
757 +# DO NOT USE " to enclose the string, just the string!!!
758 +#
759 +# smtpd_tls_cipherlist = DEFAULT
760 +
761 +# If you want to take advantage of ciphers with EDH, DH parameters are needed.
762 +# There are built in DH parameters for both 1025bit and 512bit available. It
763 +# is however better to have "own" parameters, since otherwise it would "pay"
764 +# for a possible attacker to start a brute force attack against these
765 +# parameters commonly used by everybody. For this reason, the parameters
766 +# chosen are already different from those distributed with other TLS packages.
767 +#
768 +# To generate your own set of parameters, use
769 +# openssl gendh -out /etc/postfix/dh_1024.pem -2 -rand /var/run/egd-pool 1024
770 +# openssl gendh -out /etc/postfix/dh_512.pem -2 -rand /var/run/egd-pool 512
771 +# (your source for "entropy" might vary; on Linux there is /dev/random, on
772 +# other system, you might consider the "Entropy Gathering Daemon EGD", 
773 +# available at http://www.lothar.com/tech/crypto/.
774 +#
775 +smtpd_tls_dh1024_param_file = /etc/postfix/dh_1024.pem
776 +smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem
777 +
778 +# The smtpd_starttls_timeout parameter limits the time in seconds to write and
779 +# read operations during TLS start and stop handhake procedures.
780 +#
781 +# smtpd_starttls_timeout = 300s
782 +</pre>
783 +
784 +<h2>main.cf: smtp (client) specific variables</h2>
785 +
786 +<pre>
787 +# During the startup negotiation we might present a certificate to the server.
788 +# Netscape is rather clever here and lets the user select between only those
789 +# certs that will match the CAs accepted from the server. As I simply use
790 +# the integrated "SSL_connect()" from the OpenSSL package, this is not
791 +# possible by now and we have to chose just one cert.
792 +# So for now the default is to use _no_ cert and key unless explictly
793 +# set here. It is possible to use the same key/cert pair as for the server.
794 +# If a cert is to be presented, it must be in "pem" format, the private key
795 +# must not be encrypted, that does mean: it must be accessable without
796 +# password. Both parts (certificate and private key) may be in the
797 +# same file.
798 +#
799 +# In order to check the certificates, the CA-certificate (in case of a
800 +# certificate chain, all CA-certificates) must be available.
801 +# You should add these certificates to the server certificate, the server
802 +# certificate first, then the issuing CA(s).
803 +#
804 +# Example: the certificate for "client.dom.ain" was issued by "intermediate CA"
805 +# which itself has a certificate of "root CA". Create the client.pem file by
806 +# 'cat client_cert.pem intemediate_CA.pem root_CA.pem > client.pem'
807 +#
808 +# If you want to accept certificates issued by these CAs yourself, you can
809 +# also add the CA-certificates to the smtp_tls_CAfile, in which case it is
810 +# not necessary to have them in the smtp_tls_[d]cert_file.
811 +#
812 +# A certificate supplied here must be useable as SSL client certificate and
813 +# hence pass the "openssl verify -purpose sslclient ..." test.
814 +#
815 +smtp_tls_cert_file = /etc/postfix/client.pem
816 +smtp_tls_key_file = $smtp_tls_cert_file
817 +
818 +# The certificate was issued by a certification authority (CA), the CA-cert
819 +# of which must be available, if not in the certificate file.
820 +# This file may also contain the the CA certificates of other trusted CAs.
821 +# You must use this file for the list of trusted CAs if you want to use
822 +# chroot-mode. No default is supplied for this value as of now.
823 +#
824 +smtp_tls_CAfile = /etc/postfix/CAcert.pem
825 +
826 +# To verify the peer certificate, we need to know the certificates of
827 +# certification authorities. These certificates in "pem" format are
828 +# collected in a directory. Don't forget to create the necessary "hash"
829 +# links with $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs. A typical
830 +# place for the CA-certs may also be $OPENSSL_HOME/certs, so there is
831 +# no default and you explicitly have to set the value here!
832 +#
833 +# To use this option in chroot mode, this directory itself or a copy of it
834 +# must be inside the chroot jail.
835 +#
836 +smtp_tls_CApath = /etc/postfix/certs
837 +
838 +# To get additional information during the TLS setup and negotiations
839 +# you can increase the loglevel from 0..4:
840 +# 0: No output about the TLS subsystem
841 +# 1: Printout startup and certificate information
842 +# 2: 1 + Printout of levels during negotiation
843 +# 3: 2 + Hex and ASCII dump of negotiation process
844 +# 4: 3 + Hex and ASCII dump of complete transmission after STARTTLS
845 +# Use loglevel 3 only in case of problems. Use of loglevel 4 is strongly
846 +# discouraged.
847 +#
848 +smtp_tls_loglevel = 0
849 +
850 +# The server and client negotiate a session, which takes some computer time
851 +# and network bandwidth. The session is cached only in the smtpd process
852 +# actually using this session and is lost when the process dies.
853 +# To share the session information between the smtp processes, a disc based
854 +# session cache can be used based on the SDBM databases (routines included
855 +# in Postfix/TLS). Since concurrent writing must be supported, only SDBM
856 +# can be used.
857 +#
858 +smtp_tls_session_cache_database = sdbm:/etc/postfix/smtp_scache
859 +
860 +# The cached sessions time out after a certain amount of time. For Postfix/TLS
861 +# I do not use the OpenSSL default of 300sec, but a longer time of 3600sec
862 +# (=1 hour). RFC2246 recommends a maximum of 24 hours.
863 +#
864 +# smtp_tls_session_cache_timeout = 3600s
865 +
866 +# By default TLS is disabled, so no difference to plain postfix is visible.
867 +# If you enable TLS it will be used when offered by the server.
868 +# WARNING: I didn't have access to other software (except those explicitely
869 +# listed) to test the interaction. On corresponding mailing list
870 +# there was a discussion going on about MS exchange servers offering
871 +# STARTTLS even if it is not configured, so it might be wise to not
872 +# use this option on your central mail hub, as you don't know in advance
873 +# whether you are going to hit such host. Use the recipient/site specific
874 +# options instead.
875 +# HINT: I have it switched on on my mailservers and did experience one
876 +# single failure since client side TLS is implemented. (There was one
877 +# misconfired MS Exchange server; I contacted ths admin.) Hence, I am happy
878 +# with it running all the time, but I am interested in testing anyway.
879 +# You have been warned, however :-)
880 +#
881 +# In case of failure, a "4xx" code is issued and the mail stays in the queue.
882 +#
883 +# Explicitely switch it on here, if you want it.
884 +#
885 +smtp_use_tls = yes
886 +
887 +# You can ENFORCE the use of TLS, so that only connections with TLS will
888 +# be accepted. Additionally, the hostname of the receiving host is matched
889 +# against the CommonName in the certificate. Also, the certificate must
890 +# be verified "Ok", so that a CA trusted by the client must have issued
891 +# the certificate. If the certificate doesn't verify or the hostname doesn't
892 +# match, a "4xx" will be issued and the mail stays in the queue.
893 +# The hostname used in the check is beyond question, as it must be the
894 +# principle hostname (no CNAME allowed here).
895 +# The behaviour may be changed with the smtp_tls_enforce_peername option
896 +#
897 +# This option is useful only if you are definitely sure that you will only
898 +# connect to servers supporting RFC2487 _and_ with valid certificates.
899 +# I use it for my clients which will only send email to one mailhub, which
900 +# does offer the necessary STARTTLS support.
901 +#
902 +# smtp_enforce_tls = no
903 +
904 +# As of RFC2487 the requirements for hostname checking for MTA clients are
905 +# not set. When in smtp_enforce_tls mode, the option smtp_tls_enforce_peername
906 +# can be set to "no" to disable strict peername checking. In this case, the
907 +# mail delivery will be continued, if a TLS connection was established
908 +# _and_ the peer certificate passed verification _but_ regardless of the
909 +# CommonName listed in the certificate. This option only applies to the
910 +# default setting smtp_enforce_tls_mode, special settings in the
911 +# smtp_tls_per_site table override smtp_tls_enforce_peername.
912 +#
913 +# This can make sense in closed environment where special CAs are created.
914 +# If not used carefully, this option opens the danger of a "man-in-the-middle"
915 +# attack (the CommonName of this attacker is logged).
916 +#
917 +# smtp_tls_enforce_peername = yes
918 +
919 +# As generally trying TLS can be a bad idea (some hosts offer STARTTLS but
920 +# the negotiation will fail leading to unexplainable failures, it may be
921 +# a good idea to decide based on the recipient or the mailhub to which you are
922 +# connecting.
923 +#
924 +# Deciding per recipient may be difficult, since a singe email can have
925 +# several recipients. We use the "nexthop" mechanism inside postfix.
926 +# When an email is to be delivered, the "nexthop" is obtained. If it matches
927 +# an entry in the smtp_tls_per_site list, appropriate action is taken.
928 +# Since entries in the transport table or the use of a relay_host override
929 +# the nexthop setting, in these cases the relay_host etc must be listed
930 +# in the table. In any case, the hostname of the peer to be contacted is
931 +# looked up (that is: the MX or the name of the host, if no MX is given).
932 +#
933 +# Special hint for enforcement mode:
934 +# Since there is no secure mechanism for DNS lookups available, the
935 +# recommended setup is: put the sensible domains with their mailhost
936 +# into the transport table (since you can asure security of this table
937 +# unlike DNS), then set MUST mode for this mailhost.
938 +#
939 +# Format of the table:
940 +# The keys entries are on the left hand side, no wildcards allowed. On the
941 +# right hand side the keywords NONE (don't use TLS at all), MAY (try to use
942 +# STARTTLS if offered, no problem if not), MUST (enforce usage of STARTTLS,
943 +# check server certificate CommonName against server FQDN), MUST_NOPEERMATCH
944 +# (enforce usage of STARTTLS and verify certificate, but ignore differences
945 +# between CommonName and server FQDN).
946 +# dom.ain              NONE
947 +# host.dom.ain         MAY
948 +# important.host       MUST
949 +# some.host.dom.ain    MUST_NOPEERMATCH
950 +#
951 +# If an entry is not matched, the default policy is applied; if the default
952 +# policy is "enforce", NONE explicitely switches it off, otherwise the
953 +# "enforce" mode is used even for MAY entries.
954 +#
955 +smtp_tls_per_site = hash:/etc/postfix/tls_per_site
956 +
957 +# The verification depth for server certificates. A depth of 1 is sufficient,
958 +# if the certificate ist directly issued by a CA listed in the CA locations.
959 +# The default value (5) should also suffice for longer chains (root CA issues
960 +# special CA which then issues the actual certificate...)
961 +#
962 +# smtp_tls_scert_verifydepth = 5
963 +
964 +# As we decide on a "per site" basis, wether to use TLS or not, it would be
965 +# good to have a list of sites, that offered "STARTTLS'. We can collect it
966 +# ourselves with this option.
967 +#
968 +# If activated and TLS is not already enabled for this host, a line is added
969 +# to the logfile:
970 +# postfix/smtp[pid]: Host offered STARTTLS: [name.of.host]
971 +#
972 +smtp_tls_note_starttls_offer = yes
973 +
974 +# To influence the cipher selection scheme, you can give cipherlist-string.
975 +# A detailed description would go to far here, please refer to the openssl
976 +# documentation.
977 +# If you don't know what to do with it, simply don't touch it and leave the
978 +# (openssl-)compiled in default!
979 +#
980 +# DO NOT USE " to enclose the string, just the string!!!
981 +#
982 +# smtp_tls_cipherlist = DEFAULT
983 +
984 +# The smtp_starttls_timeout parameter limits the time in seconds to write and
985 +# read operations during TLS start and stop handhake procedures.
986 +#
987 +# In case of problems the client does NOT try the next address on
988 +# the mail exchanger list.
989 +#
990 +# smtp_starttls_timeout = 300s
991 +</pre>
992 +
993 +<h2>main.cf: general variables</h2>
994 +
995 +<pre>
996 +# In order to seed the PRNG Pseude Random Number Generator, random data is
997 +# needed. The PRNG pool is maintained by the "tlsmgr" daemon and is used
998 +# (read) by the smtp[d] processes after adding some more entropy by stirring
999 +# in time and process id.
1000 +# The file, which is from time to time rewritten by the tlsmgr, is created
1001 +# if not existant. A default value is given; the default should probably
1002 +# be on the /var partition but _not_ inside chroot jail.
1003 +#
1004 +# tls_random_exchange_name = /etc/postfix/prng_exch
1005 +
1006 +# To feed the PRNG pool, entropy is being read from an external source,
1007 +# both at startup and during run.
1008 +# Specify a good entropy source here, like EGD or /dev/urandom; make sure
1009 +# to only use non-blocking sources.
1010 +# In both cases, 32 bytes are read at each re-seeding event (which is an
1011 +# amount of 256bits and hence good enough for 128bit symmetric keys).
1012 +# You must specify the type of source: "dev:" for a device special file
1013 +# or "egd:" for a source with EGD compatible socket interface. A maximum
1014 +# 255 bytes is read from these sources in each step.
1015 +# If you specify a normal file, a larger amount of data can be read.
1016 +#
1017 +# The entropy source is queried again after a certain amount of time. The
1018 +# time is calculated using the PRNG, it is between 0 and the time specified,
1019 +# default is a maximum of 1 hour.
1020 +#
1021 +# tls_random_source = dev:/dev/urandom
1022 +tls_random_source = egd:/var/run/egd-pool
1023 +# tls_random_bytes = 32
1024 +# tls_random_reseed_period = 3600s
1025 +
1026 +# The PRNG pool inside tlsmgr is used to re-generate the 1024 byte file
1027 +# being read by smtp[d]. The time, after which the exchange file is
1028 +# rewritten is calculated using the PRNG, it is between 0 and the time
1029 +# specified, default is a maximum of 60 seconds.
1030 +#
1031 +# tls_random_upd_period = 60s
1032 +
1033 +# If you have a entropy source available, that is not easily drained (like
1034 +# /dev/urandom), the daemons can also load additional entropy on startup from
1035 +# the source specified. By default an amount of 32 bytes is read, the
1036 +# equivalent to 256 bits. This is more than enough to generate a 128bit
1037 +# (or 168bit) session key, but we may have to generate more than one.
1038 +# Usage of this option may drain EGD (consider the case of 50 smtp starting
1039 +# up with a full queue and "postfix start", which will request 1600bytes
1040 +# of entropy). This is however not fatal, as long as "entropy" data could
1041 +# be read from the exchange file.
1042 +#
1043 +# tls_daemon_random_source = dev:/dev/urandom
1044 +tls_daemon_random_source = egd:/var/run/egd-pool
1045 +# tls_daemon_random_bytes = 32
1046 +</pre>
1047 +
1048 +<h2>master.cf: tlsmgr daemon</h2>
1049 +
1050 +If you don't have a /dev/urandom device and/or use session caching,
1051 +you must run the "tlsmgr" daemon (see conf/master.cf). The tlsmgr
1052 +needs to access entropy sources and can (currently) not be
1053 +chrooted. It can drop its privileges, if the entropy sources (e.g.
1054 +/dev/urandom or an EGD socket) don't have access restrictions. 
1055 +
1056 +<pre>
1057 +# ==========================================================================
1058 +# service type  private unpriv  chroot  wakeup  maxproc command + args
1059 +#               (yes)   (yes)   (yes)   (never) (50)
1060 +# ==========================================================================
1061 +tlsmgr    fifo  -       -       n       300     1       tlsmgr
1062 +</pre>
1063 +
1064 +<h2>master.cf: additional services</h2>
1065 +
1066 +It can be useful to have postfix listen on additional ports, namely
1067 +"submission"=587 for email submission as defined in RFC2476; this
1068 +is especially useful if you want to allow AUTH with plaintext
1069 +passwords (PLAIN, LOGIN) and hence run on a port with encryption
1070 +enforcement. Another useful port may be "smtps"=465 which was
1071 +intended with TLS-wrapping and is still used by Outlook (Express). 
1072 +
1073 +<p>Both example entries already contain the flags to enable SASL
1074 +authentication (which may be disabled on the normal port). Since
1075 +the actual service names are used, smtps and submission must be
1076 +defined in /etc/services (and probably also in
1077 +/var/spool/postfix/etc/services if chrooted)!!! (Use the port
1078 +numbers otherwise.)</p>
1079 +
1080 +<pre>
1081 +# ==========================================================================
1082 +# service type  private unpriv  chroot  wakeup  maxproc command + args
1083 +#               (yes)   (yes)   (yes)   (never) (50)
1084 +# ==========================================================================
1085 +smtps     inet  n       -       y       -       -       smtpd -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes
1086 +submission inet n       -       y       -       -       smtpd -o smtpd_enforce_tls=yes -o smtpd_sasl_auth_enable=yes
1087 +</pre>
1088 +</body>
1089 +</html>
1090 +
1091 diff -Nur snapshot-20010228-orig/html/ssl/index.html snapshot-20010228/html/ssl/index.html
1092 --- snapshot-20010228-orig/html/ssl/index.html  Thu Jan  1 01:00:00 1970
1093 +++ snapshot-20010228/html/ssl/index.html       Wed Mar 21 13:38:29 2001
1094 @@ -0,0 +1,50 @@
1095 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1096 +<html>
1097 +<head>
1098 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1099 +<title>Postfix/TLS - A TLS extension for POSTFIX</title>
1100 +</head>
1101 +<body>
1102 +<h1>Postfix/TLS - A TLS extension for POSTFIX</h1>
1103 +
1104 +<h2>Contents</h2>
1105 +
1106 +<ul>
1107 +<li><a href="intro.html">Introduction</a></li>
1108 +
1109 +<li><a href="install.html">Installating the patchkit</a></li>
1110 +
1111 +<li><a href="setup.html">Setting up the certificates</a></li>
1112 +
1113 +<li><a href="conf.html">Configuring main.cf</a></li>
1114 +
1115 +<li><a href="security.html">Security considerations</a></li>
1116 +
1117 +<li><a href="test.html">Testing</a></li>
1118 +
1119 +<li><a href="prng.html">PRNG - Pseudo Random Number
1120 +Generator</a></li>
1121 +
1122 +<li><a href="references.html">References</a></li>
1123 +</ul>
1124 +
1125 +<pre>
1126 +PLEASE REMEMBER THAT EXPORT/IMPORT AND/OR USE OF STRONG
1127 +CRYPTOGRAPHY SOFTWARE, PROVIDING CRYPTOGRAPHY HOOKS OR EVEN JUST
1128 +COMMUNICATING TECHNICAL DETAILS ABOUT CRYPTOGRAPHY SOFTWARE IS
1129 +ILLEGAL IN SOME PARTS OF THE WORLD. SO, WHEN YOU IMPORT THIS PACKAGE
1130 +TO YOUR COUNTRY, RE-DISTRIBUTE IT FROM THERE OR EVEN JUST EMAIL
1131 +TECHNICAL SUGGESTIONS OR EVEN SOURCE PATCHES TO THE AUTHOR OR
1132 +OTHER PEOPLE YOU ARE STRONGLY ADVICED TO PAY CLOSE ATTENTION TO ANY
1133 +EXPORT/IMPORT AND/OR USE LAWS WHICH APPLY TO YOU. THE AUTHOR OF
1134 +POSTFIX/TLS IS NOT LIABLE FOR ANY VIOLATIONS YOU MAKE HERE. SO BE
1135 +CAREFULLY YOURSELF, IT IS YOUR RESPONSIBILITY.
1136 +</pre>
1137 +
1138 +Lutz J&auml;nicke, <a href=
1139 +"http://www.aet.tu-cottbus.de/personen/jaenicke/">Homepage</a>,
1140 +Email: <a href="mailto:Lutz.Jaenicke@aet.TU-Cottbus.DE"><em>
1141 +Lutz.Jaenicke@aet.TU-Cottbus.DE</em></a>
1142 +</body>
1143 +</html>
1144 +
1145 diff -Nur snapshot-20010228-orig/html/ssl/install.html snapshot-20010228/html/ssl/install.html
1146 --- snapshot-20010228-orig/html/ssl/install.html        Thu Jan  1 01:00:00 1970
1147 +++ snapshot-20010228/html/ssl/install.html     Wed Mar 21 13:38:29 2001
1148 @@ -0,0 +1,90 @@
1149 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1150 +<html>
1151 +<head>
1152 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1153 +<title>Postfix/TLS - Installation</title>
1154 +</head>
1155 +<body>
1156 +<h1>Postfix/TLS - Installing the patchkit</h1>
1157 +
1158 +<h2>Prerequisits</h2>
1159 +
1160 +This patchkit is prepared for 
1161 +
1162 +<ul>
1163 +<li>Postfix Version release-20010228<br>
1164 + <a href="http://www.postfix.org/">http://www.postfix.org/</a> [<a
1165 +href="references.html#postfix">POSTFIX</a>]<br>
1166 + The use of other versions might lead to patch conflicts or silent
1167 +failures, as we directly change the source code.</li>
1168 +
1169 +<li>OpenSSL Version 0.9.5 or later (recommended: 0.9.6)<br>
1170 + <a href="http://www.openssl.org/">http://www.openssl.org/</a> [<a
1171 +href="references.html#openssl">OPENSSL</a>]<br>
1172 +We use OpenSSL as library (and some command line tools to create
1173 +the certificates, if necessary). OpenSSL is the successor of
1174 +SSLeay.
1175 +<p>Postfix/TLS uses properties that are only available starting with
1176 +version 0.9.5 of the OpenSSL library. 0.9.5a has proven stability
1177 +over several months. The latest release 0.9.6 contains several improvements
1178 +and has proven stability so far.
1179 +</li>
1180 +</ul>
1181 +
1182 +You may also need to update your "patch" utility (see below). 
1183 +
1184 +<h2>Patching</h2>
1185 +
1186 +The changes to the postfix source code as well as the additional
1187 +files are included in the "<code>pfixtls.diff</code>" in the main
1188 +directory of the patch kit. It is a unified diff. 
1189 +
1190 +<p>To apply the patches, go to the directory one level below the
1191 +original postfix source tree (you should see
1192 +"<code>postfix-xxxxxxx</code>" or "<code>snapshot-xxxxxxx</code>"
1193 +when doing an "<code>ls -al</code>"
1194 +at this point. The patch is then applied with:</p>
1195 +
1196 +<pre>
1197 +patch -p0 &lt; path-to/pfixtls.diff
1198 +</pre>
1199 +
1200 +If you experience problems during the patch process (e.g. with the
1201 +HP-UX 10.20 included patch), you might need to update your patch
1202 +program, e.g. to an actual GNU-patch. 
1203 +
1204 +<p>If you need to apply the patchkit to a different version of
1205 +patchlevel of postfix, you might try the following:</p>
1206 +
1207 +<pre>
1208 +cd postfix-directory ; patch -p1 &lt; path-to/pfixtls.diff
1209 +</pre>
1210 +
1211 +Since the patch is in unified form, it might also apply to a mildly
1212 +changed source, as long as no conflicts appear. 
1213 +
1214 +<h2>Compiling</h2>
1215 +
1216 +After patching postfix will configure and compile as before. In
1217 +order to enable the TLS functions, you must specify the path to the
1218 +OpenSSL header files as well as the appropriate libraries, and you
1219 +must define <code>HAS_SSL</code>. Your command for configuration
1220 +might then be: 
1221 +
1222 +<pre>
1223 +make makefiles CCARGS="-DHAS_SSL -I/usr/local/ssl/include" AUXLIBS="-L/usr/local/ssl/lib -lssl -lcrypto"
1224 +</pre>
1225 +
1226 +You might need additional customization e.g. for using Berkeley-DB
1227 +as listed in the postfix INSTALL instructions. You can then
1228 +continue in the usual way with: 
1229 +
1230 +<pre>
1231 +make
1232 +</pre>
1233 +
1234 +and then follow the instructions in the postfix INSTALL file. 
1235 +
1236 +</body>
1237 +</html>
1238 +
1239 diff -Nur snapshot-20010228-orig/html/ssl/intro.html snapshot-20010228/html/ssl/intro.html
1240 --- snapshot-20010228-orig/html/ssl/intro.html  Thu Jan  1 01:00:00 1970
1241 +++ snapshot-20010228/html/ssl/intro.html       Wed Mar 21 13:38:29 2001
1242 @@ -0,0 +1,184 @@
1243 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1244 +<html>
1245 +<head>
1246 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1247 +<title>Postfix/TLS - Introduction</title>
1248 +</head>
1249 +<body>
1250 +<h1>Postfix/TLS - Introduction</h1>
1251 +
1252 +Postfix/TLS is an extension of the Postfix [<a href=
1253 +"references.html#postfix">POSTFIX</a>] MTA software to support the
1254 +TLS protocol. 
1255 +
1256 +<h2>A note about the start of the project</h2>
1257 +
1258 +When I started writing this software, I had a sophisticated way to
1259 +allow <a href="relaycert.html">relaying for roaming users</a> in
1260 +mind. In the meantime, this project is living on its own. 
1261 +
1262 +<h2>RFC2246: The TLS (former SSL) protocol</h2>
1263 +
1264 +By default all communication on the Internet is done without
1265 +encryption and without strong authentication. That does mean that
1266 +everybody with physical access to the communication line along
1267 +which a network packet will travel can eavesdrop on your
1268 +communication. Even worse, it might be possible to redirect or
1269 +alter your communication so that information, that you want to send
1270 +to a party can be lost or changed without your notice. 
1271 +
1272 +<p>In order to solve these security issues, the SSL protocol
1273 +(Secure Socket Layers) was introduced by Netscape, Inc., which now
1274 +has evolved into the standardised TLS protocol (Transportation
1275 +Layer Security) as <a href="rfc2246.txt">RFC2246</a>. It offers
1276 +both encryption of the communication (stopping eavesdropping) and
1277 +strong authentication (making sure that both parties of a
1278 +communication are correctly identified and that the communication
1279 +cannot be altered).</p>
1280 +
1281 +<p>Postfix/TLS does not realize the TLS protocol itself; it rather
1282 +uses the OpenSSL package [<a href=
1283 +"references.html#openssl">OPENSSL</a>] for this task. At the
1284 +OpenSSL WWW-site you can also find links to in-depth documentation
1285 +of the protocol and its features, so that it is not necessary to
1286 +included them here. (And, of course, there is no use of re-writing
1287 +what other people already wrote down, it just introduces additional
1288 +errors.)</p>
1289 +
1290 +<h2>RFC2487: Introducing TLS to SMTP</h2>
1291 +
1292 +The integration of the TLS protocol to Internet mail, SMTP (Simple
1293 +Mail Transport Protocol) is described in <a href="rfc2487.txt">
1294 +RFC2487</a>. 
1295 +
1296 +<p>Unlike the first incarnations of SSL as a <em>wrapper</em>
1297 +around normal network communications [<a href=
1298 +"references.html#stunnel">STUNNEL</a>] [<a href=
1299 +"references.html#jonama">JONAMA</a>], the TLS protocol is now
1300 +completely <em>integrated</em> into the ESMTP: during the startup
1301 +negotiation (EHLO) the server offers the support of TLS by
1302 +advertising the <strong>STARTTLS</strong> feature. The client can
1303 +now send the <strong>STARTTLS</strong> command to do authentication
1304 +and switch to encrypted communication.</p>
1305 +
1306 +<h2>Postfix/TLS: what can it do for you</h2>
1307 +
1308 +The list of features presented here should be understood as a list
1309 +of ideas. Not all of them are realized yet, please see the notes at
1310 +each feature. 
1311 +
1312 +<ul>
1313 +<li>Encrypted email transfer from one host to another.<br>
1314 +Status: realized.<br>
1315 +Comment: Once the STARTTLS negotiation is finished, the
1316 +communication between both parties is encrypted.
1317 +This also includes the MAIL FROM: and RCPT TO: envelop sender
1318 +and recipient negotiation, so that an eavesdropper will not be able
1319 +to get these informations.</li>
1320 +
1321 +<li>Authentication of the receiving host to prevent
1322 +interception.<br>
1323 +Status: realized.<br>
1324 +Comment: This is a quite important feature that is not difficult to
1325 +implement. The problem lies in the fact, that not all hosts (read
1326 +this: by now nearly no one) support this protocol. The sender must
1327 +hence maintain a list of receivers which must identify by TLS,
1328 +otherwise one could just intercept the communication and not offer
1329 +STARTTLS, so that no authentication is done. One must also be
1330 +careful to use the correct name of the host (see CNAMEs), but this
1331 +problem is the same for http-servers.</li>
1332 +
1333 +<li>Authentication of the sending host to prevent forgery.<br>
1334 +Status: Difficult to do.<br>
1335 +Comment: The transmission of emails is just a connection to the
1336 +SMTP port (25) of the receiving host. This is done by either
1337 +another MTA (Mail Transport Agent) or a MUA (Mail User Agent). In
1338 +the first case, the sending MTA should present a client certificate
1339 +issued on the name of the sending host. In the latter case however,
1340 +the user has no access to the host's certificate and will (or not)
1341 +present his own personal certificate. At this point I think that a
1342 +satisfying <em>and</em> reliable solution is hardly possible (do
1343 +you want your users' email bounce without reason?), so it has least
1344 +priority.</li>
1345 +
1346 +<li>Authentication of the sending host to allow relaying.<br>
1347 +Status: realized.<br>
1348 +Comment: This was the intention I had in mind when starting this
1349 +project, so it was realized first. Based on the certificate the
1350 +client MTA or MUA presents to the server, relaying can be
1351 +allowed.</li>
1352 +
1353 +<li>Any more ideas???<br>
1354 +Status: Send me an email.</li>
1355 +</ul>
1356 +
1357 +<h2>Postfix/TLS: what it cannot do for you</h2>
1358 +
1359 +There is one thing that I explicitly want to point out: 
1360 +
1361 +<ul>
1362 +<li>Securing the privacy of your email.<br>
1363 +Status: Cannot be done.<br>
1364 +Comment: RFC2487 only takes care of the transportation between mail
1365 +servers. To assure that nobody can eavesdrop on your private email
1366 +communication, it would be necessary that 
1367 +
1368 +<ul>
1369 +<li>all of the mailhubs in between are enforcing TLS.</li>
1370 +
1371 +<li>all mailhubs themselves are trustworthy, as the email is only
1372 +encrypted during transport, not when queued or spooled.</li>
1373 +
1374 +<li>the destination is trustworthy, as the mail is spooled in clear
1375 +and everybody who can access your mailbox (read this: at least the
1376 +superuser) can read your mail!</li>
1377 +</ul>
1378 +
1379 +Hence, if you want privacy, you have to <em>send out</em> your
1380 +email encrypted, e.g. using S/MIME or the traditional PGP
1381 +package.</li>
1382 +
1383 +<li>Authenticate the sender of an email.<br>
1384 +Status: Cannot be done.<br>
1385 +Comment: A lot of MUAs send out emails by just connecting the SMTP
1386 +port of the sending host or nearest mailhub. There is no way to
1387 +assure that the sender listed in the email is the real sender of
1388 +the email. And even if it would be possible to identify the sender,
1389 +the contents of the email might have been altered in between.<br>
1390 +To ensure the identity of the sender and the integrity of the
1391 +email, you can again use S/MIME or PGP.</li>
1392 +</ul>
1393 +
1394 +<h2>Other OpenSource packages</h2>
1395 +
1396 +As of version sendmail-8.11, sendmail includes RFC2487 support [<a
1397 +href="references.html#sendmail">SENDMAIL</a>]. 
1398 +
1399 +<p>Frederik Vermeulen has realized an RFC2487 extension [<a href=
1400 +"references.html#qmailtls">QMAILTLS</a>] for the Qmail [<a href=
1401 +"references.html#qmail">QMAIL</a>] MTA.</p>
1402 +
1403 +<p>Matti Aarnio has integrated RFC2487 into ZMailer [<a href=
1404 +"references.html#zmailer">ZMAILER</a>].</p>
1405 +
1406 +<p>Michal Trojnara is currently integrating basic SMTP support into
1407 +his stunnel software, starting with stunnel-3.3 [<a href=
1408 +"references.html#stunnel">STUNNEL</a>].</p>
1409 +
1410 +<p>Trey Childs is also working on a "wrapper" solution [<a href=
1411 +"references.html#smtps">SMTPS</a>].</p>
1412 +
1413 +<h2>Commercial implementations</h2>
1414 +
1415 +The commercial version of sendmail includes RFC2487 support [<a
1416 +href="references.html#sendmail.inc">SENDMAIL.INC</a>]. 
1417 +
1418 +<p>Netscape Enterprise Server and Microsoft Exchange Server do offer
1419 +RFC2487 functionality.</p>
1420 +
1421 +<p>The CommunigatePro mailserver software also supports RFC2487
1422 +[<a href="references.html#communigate">COMMUNIGATE</a>].</p>
1423 +
1424 +</body>
1425 +</html>
1426 +
1427 diff -Nur snapshot-20010228-orig/html/ssl/loadCAcert.pl snapshot-20010228/html/ssl/loadCAcert.pl
1428 --- snapshot-20010228-orig/html/ssl/loadCAcert.pl       Thu Jan  1 01:00:00 1970
1429 +++ snapshot-20010228/html/ssl/loadCAcert.pl    Wed Mar 21 13:38:29 2001
1430 @@ -0,0 +1,23 @@
1431 +#!/usr/local/bin/perl -T
1432 +
1433 +require 5.003;
1434 +use strict;
1435 +use CGI;
1436 +
1437 +my $cert_dir = "/usr/local/ssl/certs";
1438 +my $cert_file = "CAcert.pem";
1439 +
1440 +my $query = new CGI;
1441 +
1442 +my $kind = $query->param('FORMAT');
1443 +if($kind eq 'DER') { $cert_file = "CAcert.der"; }
1444 +
1445 +my $cert_path = "$cert_dir/$cert_file";
1446 +
1447 +open(CERT, "<$cert_path");
1448 +my $data = join '', <CERT>;
1449 +close(CERT);
1450 +print "Content-Type: application/x-x509-ca-cert\n";
1451 +print "Content-Length: ", length($data), "\n\n$data";
1452 +
1453 +1;
1454 diff -Nur snapshot-20010228-orig/html/ssl/myownca.html snapshot-20010228/html/ssl/myownca.html
1455 --- snapshot-20010228-orig/html/ssl/myownca.html        Thu Jan  1 01:00:00 1970
1456 +++ snapshot-20010228/html/ssl/myownca.html     Wed Mar 21 13:38:29 2001
1457 @@ -0,0 +1,175 @@
1458 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1459 +<html>
1460 +<head>
1461 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1462 +<title>Postfix/TLS - Being your on CA</title>
1463 +</head>
1464 +<body>
1465 +<h1>Postfix/TLS - Lutz's very short course on being your own
1466 +CA</h1>
1467 +
1468 +This section is kept quite short as there are already a lot of
1469 +pages explaining these things (e.g. [<a href=
1470 +"references.html#introcert">INTROCERT</a>]). There are also
1471 +projects under way to make this task easier [<a href=
1472 +"references.html#openca">OPENCA</a>], so I wont't waste your time
1473 +(and mine) by writing a book about it. 
1474 +
1475 +<h2>Be your own CA</h2>
1476 +
1477 +If you want to do relaying based on client certificates you may
1478 +want to issue your own client certificates; hence you want to be
1479 +your own certificate authority (CA). Of course nobody else will
1480 +accept your certificates, so the damage you do is not so high (the
1481 +requirements for a good "professional" CA are very high, as you
1482 +should have the CA key on a private host without network for
1483 +security, be strict about checking the identity of requesters etc).
1484 +
1485 +
1486 +<p>For laziness, we also don't care about the (worthful)
1487 +possibility to generate certificates for specific purposes (e.g.
1488 +for servers, clients, email-signing) and simply generate "unlimited
1489 +general purpose" certificates. So a certificate issued for the
1490 +person "John Doe" is also valid for the "John Doe"-server.</p>
1491 +
1492 +<p>Using OpenSSL it is quite simple to become your own CA. Just
1493 +run</p>
1494 +
1495 +<pre>
1496 +CA.pl -newca
1497 +</pre>
1498 +
1499 +and you are done. Just make sure, that you select a useful CN
1500 +(Common Name)! By just using your name, you might create a lot of
1501 +confusion, as the CA certificate for "Lutz Jaenicke" looks quite
1502 +the same as the personal client certificate for "Lutz Jaenicke" (I
1503 +can tell you). Of course you can further improve this private CA by
1504 +editing the <code>openssl.cnf</code> file, especially the comment. 
1505 +
1506 +<p>If you want the full comfort of being your own CA, you must
1507 +import your CA certificate to Netscape. Unfortunately Netscape does
1508 +not offer an explicit function to perform this task (unlike for
1509 +client certificates). If you have an http-server available (and I
1510 +think you do), you can add the <a href="loadCAcert.pl">
1511 +loadCAcert.pl</a> script to your <code>cgi-bin</code> directory. If
1512 +you call it from Netscape (or Internet Explorer), you can load the
1513 +certificate! (Taken from [<a href=
1514 +"references.html/#introcert">6</a>])</p>
1515 +
1516 +<h2>Create your site certificate</h2>
1517 +
1518 +Ok, you now must create a site certificate for your postfix server.
1519 +As your clients will use it for verification, it must contain the
1520 +name of your host as common name (CN): host.in.domain. 
1521 +
1522 +<p>You want your postfix system to start up at boot time without
1523 +trouble? Then your server private key must not be encrypted. So
1524 +when you create the key you must add the <code>-nodes</code> option
1525 +in <code>CA.pl</code> to the line with the <code>-newcert</code>
1526 +and/or <code>-newreq</code> command:</p>
1527 +
1528 +<pre>
1529 +*** CA.pl   Wed Mar 24 10:30:38 1999
1530 +--- CA1.pl  Sat Mar 27 19:36:47 1999
1531 +***************
1532 +*** 56,67 ****
1533 +        exit 0;
1534 +    } elsif (/^-newcert$/) {
1535 +        # create a certificate
1536 +!       system ("$REQ -new -x509 -keyout newreq.pem -out newreq.pem $DAYS");
1537 +        $RET=$?;
1538 +        print "Certificate (and private key) is in newreq.pem\n"
1539 +    } elsif (/^-newreq$/) {
1540 +        # create a certificate request
1541 +!       system ("$REQ -new -keyout newreq.pem -out newreq.pem $DAYS");
1542 +        $RET=$?;
1543 +        print "Request (and private key) is in newreq.pem\n";
1544 +    } elsif (/^-newca$/) {
1545 +--- 56,67 ----
1546 +        exit 0;
1547 +    } elsif (/^-newcert$/) {
1548 +        # create a certificate
1549 +!       system ("$REQ -new -x509 -nodes -keyout newreq.pem -out newreq.pem $DAYS");
1550 +        $RET=$?;
1551 +        print "Certificate (and private key) is in newreq.pem\n"
1552 +    } elsif (/^-newreq$/) {
1553 +        # create a certificate request
1554 +!       system ("$REQ -new -nodes -keyout newreq.pem -out newreq.pem $DAYS");
1555 +        $RET=$?;
1556 +        print "Request (and private key) is in newreq.pem\n";
1557 +    } elsif (/^-newca$/) {
1558 +</pre>
1559 +
1560 +For sslwrap or stunnel the authors propose to use self signed certs
1561 +created with <code>-newcert</code>. I rather propose to create an
1562 +ordinary certificate request with 
1563 +
1564 +<pre>
1565 +CA.pl -newreq
1566 +</pre>
1567 +
1568 +and then sign it with your CA: 
1569 +
1570 +<pre>
1571 +CA.pl -sign
1572 +</pre>
1573 +
1574 +Now you can install the cert from <code>cacert.pem</code> to <code>
1575 +/etc/postfix/CAcert.pem</code>, the created certificate from <code>
1576 +newcert.pem</code> to <code>/etc/postfix/cert.pem</code> and the
1577 +key part form <code>newreq.pem</code> to <code>
1578 +/etc/postfix/key.pem</code>. Please be aware, that the <code>
1579 +key.pem</code> is not protected by password, so you have to protect
1580 +it by file access privileges. As the information is read before
1581 +smtpd changes to chroot jail, it still has root privileges, so you
1582 +should 
1583 +
1584 +<pre>
1585 +chown root /etc/postfix/key.pem ; chmod 400 /etc/postfix/key.pem
1586 +</pre>
1587 +
1588 +<h2>Create a client certificate</h2>
1589 +
1590 +Creating a client certificate is as easy as a site certificate. At
1591 +least, if you are doing it as a CA. First you create and sign a
1592 +pair of key and certificate. Be sure to add the correct common name
1593 +(CN) for the client: 
1594 +
1595 +<pre>
1596 +CA.pl -newreq
1597 +CA.pl -sign
1598 +</pre>
1599 +
1600 +If you want to do client certificate based relaying, you do need
1601 +the fingerprint of the certificate, which can be obtained with 
1602 +
1603 +<pre>
1604 +openssl x509 -fingerprint -in newcert.pem
1605 +</pre>
1606 +
1607 +Now this certificate must be imported into netscape. Therefore the
1608 +data you just created must be converted to a ".p12" file in PKCS#12
1609 +format. You do need the <code>pkcs12</code> utility [<a href=
1610 +"references.html#pkcs12">PKCS12</a>], which is included in the
1611 +OpenSSL package as of version 0.9.3. The necessary command is: 
1612 +
1613 +<pre>
1614 +pkcs12 -export -in newcert.pem -inkey newreq.pem \
1615 +  -certfile /usr/local/ssl/CAcert.pem -name "Name" -out newcert.p12
1616 +</pre>
1617 +
1618 +Of course your filenames may vary. Please take special care to
1619 +supply a good name to your certificate. First: The name will be
1620 +listed every time when a client certificate is to be send by
1621 +netcape. As a person may have several certificates, the name might
1622 +include a hint on the CA (e.g. "Lutz Jaenicke (Lutz CA)"). <strong>
1623 +If you want to have a lot of fun, you can just omit the name.
1624 +Netscape will happily import the certificate, but you won't see it
1625 +in the list of user certificates. And as you don't see it, you
1626 +cannot select it. And as Netscape will not overwrite it, if you
1627 +offer the same (corrected) certificate with a name, you want to
1628 +delete it, but as you cannot select it, you cannot delete it. You
1629 +got the point?</strong>
1630 +</body>
1631 +</html>
1632 +
1633 diff -Nur snapshot-20010228-orig/html/ssl/prng.html snapshot-20010228/html/ssl/prng.html
1634 --- snapshot-20010228-orig/html/ssl/prng.html   Thu Jan  1 01:00:00 1970
1635 +++ snapshot-20010228/html/ssl/prng.html        Wed Mar 21 13:38:29 2001
1636 @@ -0,0 +1,97 @@
1637 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1638 +<html>
1639 +<head>
1640 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1641 +<title>Postfix/TLS - PRNG Pseudo Random Number Generator</title>
1642 +</head>
1643 +<body>
1644 +<h1>Postfix/TLS - PRNG Pseudo Random Number Generator</h1>
1645 +
1646 +One of the crucial points of encryption is the generation of the
1647 +keys, for which random numbers are required. As of OpenSSL 0.9.5,
1648 +the seeding of the included PRNG Pseudo Random Number Generator is
1649 +checked. Starting with Postfix/TLS 0.5.4, an architecture to
1650 +collect entropy is included. 
1651 +
1652 +<h2>Included PRNG</h2>
1653 +
1654 +OpenSSL features a quite sophisticated PRNG. In order to generate
1655 +random numbers of lengths of more then 1024bit, a 8192bit (=1kB)
1656 +pool is kept and used to generate these random numbers. To achieve
1657 +full complexity for an attacker, it is necessary to have the full
1658 +range of random numbers available and not restrict the search space
1659 +used for searching keys, hence an according amount of entropy is
1660 +necessary. 
1661 +
1662 +<h2>Obtaining Entropy</h2>
1663 +
1664 +To get entropy, unpredictable events are needed. Unfortunately,
1665 +computers and software tend to be very predictable, so that a lot
1666 +of effort is necessary to collect unpredictable events. The
1667 +mathematical techniques are discussed in the excellent book of
1668 +Schneier "Applied Cryptography". 
1669 +
1670 +<p>We use at least one feature: if you have collected a pool of
1671 +data with entropy in it, you can add up more data without losing
1672 +the entropy already there, so that we can mix external sources and
1673 +internal bits to only increase the entropy.</p>
1674 +
1675 +<h2>External sources</h2>
1676 +
1677 +Only few operating systems provide good entropy collection. 
1678 +
1679 +<h3>/dev/random and /dev/urandom</h3>
1680 +
1681 +Linux offers the <tt>/dev/random</tt> and <tt>/dev/urandom</tt>
1682 +devices, some BSD derivatives as well. 
1683 +
1684 +<p><tt>/dev/random</tt> will provide high quality random data, but
1685 +it will block until enough entropy is available, if too much random
1686 +data is requested to fast. <tt>/dev/urandom</tt> will fill up the
1687 +real entropy data with data from an internal PRNG and will never
1688 +block. For a system with automated startup /dev/urandom should be
1689 +used. Reading from /dev/urandom will however trigger kernel
1690 +activity to satisfy the demands. Imagine starting up postfix with a
1691 +large number of emails in the queue. 50 (default) smtp processes
1692 +want to start at the same time and access <tt>
1693 +/dev/urandom</tt>.</p>
1694 +
1695 +<h3>Entropy Gathering Daemon</h3>
1696 +
1697 +A replacement for operating systems without good random number
1698 +collection is the <a href="references.html#egd">EGD</a> Entropy
1699 +Gathering Daemon. It will also extract entropy from a lot of
1700 +sources. 
1701 +
1702 +<p>EGD has a command driven interface, there is a command for
1703 +blocking and one for non-blocking read. Unlike <tt>
1704 +/dev/urandom</tt> the non-blocking command will not trigger an
1705 +internal PRNG to fill up, but will simply return a smaller number
1706 +of bytes than requested, even 0 if totally drained.</p>
1707 +
1708 +<p>EGD should hence not be used for direct feeding of smtp[d]
1709 +processes. Again, imagine 50 smtp processes starting delivery at
1710 +the same time.</p>
1711 +
1712 +<p><em>To circumvent this problem, I have witten my own daemon,
1713 +that has a EGD compatible interface but can never run dry, just
1714 +like <tt>/dev/urandom</tt>. Check out <a href=
1715 +"references.html#prngd">PRNGD</a> for details.</em></p>
1716 +
1717 +<h3>Intermediate File</h3>
1718 +
1719 +Hence, Postfix/TLS maintains its own pool of entropy by means
1720 +of the <em>tlsmgr</em> daemon. It will collect entropy from an
1721 +external source at startup and periodically during runtime to ever
1722 +increase the entropy in the pool. The smtp[d] processes are fed
1723 +from an PRNG exchange file that is updated in short periods. Upon
1724 +restart, tlsmgr will also read entropy from this file, so that the
1725 +large entropy pool is fully utilized.
1726 +
1727 +<p>The single smtp[d] daemons can also access an external source. Their
1728 +collected entropy is also stirred into the intermediate file, so that
1729 +a significant amount of entropy is available alltogether.
1730 +
1731 +</body>
1732 +</html>
1733 +
1734 diff -Nur snapshot-20010228-orig/html/ssl/references.html snapshot-20010228/html/ssl/references.html
1735 --- snapshot-20010228-orig/html/ssl/references.html     Thu Jan  1 01:00:00 1970
1736 +++ snapshot-20010228/html/ssl/references.html  Wed Mar 21 13:38:29 2001
1737 @@ -0,0 +1,101 @@
1738 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1739 +<html>
1740 +<head>
1741 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1742 +<title>Postfix/TLS - References</title>
1743 +</head>
1744 +<body>
1745 +<h1>Postfix/TLS - References</h1>
1746 +
1747 +<ol>
1748 +<li>[<a name="postfix">POSTFIX] The Postfix (formerly VMailer) Home
1749 +Page: <a href="http://www.postfix.org/">
1750 +http://www.postfix.org/</a>.</a></li>
1751 +
1752 +<li>[<a name="openssl">OPENSSL</a>] OpenSSL: The Open Source
1753 +toolkit for SSL/TLS: <a href="http://www.openssl.org/">
1754 +http://www.openssl.org/</a>.</li>
1755 +
1756 +<li>[<a name="pkcs12">PKCS12</a>]OpenSSL PKCS#12 Program FAQ: <a
1757 +href="http://www.drh-consultancy.demon.co.uk/pkcs12faq.html">
1758 +http://www.drh-consultancy.demon.co.uk/pkcs12faq.html</a>.</li>
1759 +
1760 +<li>[<a name="sslwrap">SSLWRAP</a>] SSLwrap Homepage: <a href=
1761 +"http://www.rickk.com/sslwrap/">
1762 +http://www.rickk.com/sslwrap/</a>.</li>
1763 +
1764 +<li>[<a name="stunnel">STUNNEL</a>] Stunnel Homepage: <a href=
1765 +"http://mike.daewoo.com.pl/computer/stunnel/">
1766 +http://mike.daewoo.com.pl/computer/stunnel/</a>.</li>
1767 +
1768 +<li>[<a name="introcert">INTROCERT</a>] Introducing SSL and
1769 +Certificates using SSLeay: <a href=
1770 +"http://www.camb.opengroup.org/RI/www/prism/wwwj/index.html">
1771 +http://www.camb.opengroup.org/RI/www/prism/wwwj/index.html</a>.</li>
1772 +
1773 +<li>[<a name="imcorg">IMC</a>] Internet Mail Consortium: <a href=
1774 +"http://www.imc.org/">http://www.imc.org/</a>.</li>
1775 +
1776 +<li>[<a name="imcorgappstls">IETF-APPS-TLS</a>] ietf-apps-tls
1777 +mailing list: <a href="http://www.imc.org/ietf-apps-tls/">
1778 +http://www.imc.org/ietf-apps-tls/</a></li>
1779 +
1780 +<li>[<a name="openca">OPENCA</a>] The OpenCA Project: <a href=
1781 +"http://www.openca.org/">http://www.openca.org/</a>.</li>
1782 +
1783 +<li>[<a name="dfncert">DFNCERT</a>] DFN-CERT: <a href=
1784 +"http://www.cert.dfn.de/">http://www.cert.dfn.de/</a>.</li>
1785 +
1786 +<li>[<a name="sendmail">SENDMAIL</a>] Sendmail: <a href=
1787 +"http://www.sendmail.org/">http://www.sendmail.org/</a>.</li>
1788 +
1789 +<li>[<a name="sendmail.inc">SENDMAIL.INC</a>] Sendmail Inc: <a
1790 +href="http://www.sendmail.com/">http://www.sendmail.com/</a>.</li>
1791 +
1792 +<li>[<a name="qmail">QMAIL</a>] Qmail: <a href=
1793 +"http://www.qmail.org/">http://www.qmail.org/</a>.</li>
1794 +
1795 +<li>[<a name="qmailtls">QMAILTLS</a>] Qmail/TLS: <a href=
1796 +"http://www.esat.kuleuven.ac.be/~vermeule/qmail/tls.patch">
1797 +http://www.esat.kuleuven.ac.be/~vermeule/qmail/tls.patch</a>.</li>
1798 +
1799 +<li>[<a name="zmailer">ZMAILER</a>] ZMailer: <a href=
1800 +"http://www.zmailer.org/">http://www.zmailer.org/</a>.</li>
1801 +
1802 +<li>[<a name="jonama">JONAMA</a>] Jonama: <a href=
1803 +"http://www.multimania.com/jonama/">
1804 +http://www.multimania.com/jonama/</a>.</li>
1805 +
1806 +<li>[<a name="smtps">SMTPS</a>] Trey Child's STARTTLS wrapper: <a
1807 +href="http://sites.netscape.net/tc15163/homepage">
1808 +http://sites.netscape.net/tc15163/homepage</a>.</li>
1809 +
1810 +<li>[<a name="safegossip">SAFEGOSSIP</a>] Safegossip universal
1811 +TLS-wrapper: <a href="http://www.skygate.co.uk/safegossip/">
1812 +http://www.skygate.co.uk/safegossip/</a>.</li>
1813 +
1814 +<li>[<a name="sendmailtls">SENDMAIL-TLS</a>] Jeremy Beker's
1815 +sendmail-tls wrapper: <a href="http://opensource.3gi.com/">
1816 +http://opensource.3gi.com/</a>.</li>
1817 +
1818 +<li>[<a name="sendmailtls">COMMUNIGATE</a>] Stalker Software's
1819 +CommunigatePro mailserver product: <a href="http://www.stalker.com/">
1820 +http://www.stalker.com/</a>.</li>
1821 +
1822 +<li>[<a name="egd">EGD</a>] Entropy Gathering Daemon: <a href=
1823 +"http://www.lothar.com/tech/crypto/">
1824 +http://www.lothar.com/tech/crypto/</a>.</li>
1825 +
1826 +<li>[<a name="prngd">PRNGD</a>] Pseudo Random Number Generator
1827 +Daemon: <a href=
1828 +"http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html">
1829 +http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html</a>.</li>
1830 +
1831 +<li>[<a name="oe_ssl">Outlook/SSL</a>] Outlook (Express) and
1832 +STARTTLS info: <a href=
1833 +"http://support.microsoft.com/support/kb/articles/Q218/4/30.ASP">
1834 +http://support.microsoft.com/support/kb/articles/Q218/4/30.ASP</a>.</li>
1835 +</ol>
1836 +</body>
1837 +</html>
1838 +
1839 diff -Nur snapshot-20010228-orig/html/ssl/relaycert.html snapshot-20010228/html/ssl/relaycert.html
1840 --- snapshot-20010228-orig/html/ssl/relaycert.html      Thu Jan  1 01:00:00 1970
1841 +++ snapshot-20010228/html/ssl/relaycert.html   Wed Mar 21 13:38:29 2001
1842 @@ -0,0 +1,124 @@
1843 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1844 +<html>
1845 +<head>
1846 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1847 +<title>Postfix/TLS - Initial Motivation</title>
1848 +</head>
1849 +<body>
1850 +<h1>Postfix/TLS - Initial Motivation</h1>
1851 +
1852 +This introduction shall point out the motivation, why I spend my
1853 +time writing this TLS extension for postfix. 
1854 +
1855 +<h2>Roaming users problem</h2>
1856 +
1857 +It quite often happens that my users want to access their mailboxes
1858 +and to send emails from hosts outside our network. The main reasons
1859 +are the access from home via Internet service providers (ISP) or
1860 +from abroad during business trips (in our case typically to other
1861 +universities around the world). Sending and accessing leads to two
1862 +loosely coupled problems. 
1863 +
1864 +<h2>UCE control</h2>
1865 +
1866 +One problem is sending emails, because from abroad it is seldom
1867 +possible to predict the sending hostname we will have and when
1868 +using an ISP the assigned hostname is typically random. As we of
1869 +course must have UCE control in effect, I either must open up
1870 +relaying complete ISP domains on my users request (Arrgghh!) or
1871 +must introduce an authentication beside the hostname or IP address.
1872 +
1873 +
1874 +<h2>Passwords and insecure networks</h2>
1875 +
1876 +This directly leads to the second problem. Recent versions of
1877 +Netscape do offer password based authentication. This solves the
1878 +UCE problem but introduces another one, which I consider far more
1879 +severe: The users have to send a password in plain text over the
1880 +network. Of course I could solve this problem by issuing special
1881 +passwords just for this reasons, but some of my users don't have a
1882 +clue of what is going on between the keyboard and the screen, so
1883 +they would happily try their real password. 
1884 +
1885 +<p>The same problem of course also applies to the POP and IMAP
1886 +services. I tackled them first, because they are typically attacked
1887 +by port scanners, so I closed them down by tcpwrappers (Hi Wietse!)
1888 +to only allow my local hosts to access them.</p>
1889 +
1890 +<h2>Encryption via SSL</h2>
1891 +
1892 +The solution to the plain text password problem was easily found
1893 +with the use of SSL. You just tunnel the POP or IMAP connection
1894 +through SSL, using either <strong>SSLwrap</strong> [<a href=
1895 +"references.html#sslwrap">SSLWRAP</a>] or <strong>stunnel</strong>
1896 +[<a href="references.html#stunnel">STUNNEL</a>]. 
1897 +
1898 +<p>Netscape supports IMAP with SSL tunneling since version 4, I
1899 +have one user with Outlook Express, who uses POP3 with SSL
1900 +tunneling, so this solves the plain text password problem by
1901 +encryption.</p>
1902 +
1903 +<h2>Netscape 4.5</h2>
1904 +
1905 +Starting with Netscape 4.5, also sending with SSL encryption is
1906 +supported. As Netscape also supports client certificates, this
1907 +seemed to be an easy solution for the UCE control problem. So I
1908 +happily added an "smtps" service with SSL wrapper and client
1909 +certificate verification. Unfortunately it didn't work and the
1910 +connection just hung! After some digging around I found out, that
1911 +Netscape 4.5 seems to realize the protocol described in <a href=
1912 +"rfc2487.txt">RFC 2487</a> [<a href=
1913 +"references.html#imcorg">IMC</a>]. 
1914 +
1915 +<h2>RFC 2487 - SMTP Service Extension for Secure SMTP over TLS</h2>
1916 +
1917 +RFC 2487 describes how to include TLS (the successor of SSL) into
1918 +the normal Extended SMTP protocol. During the normal EHLO start
1919 +negotiation the server offers the STARTTLS option to the client,
1920 +which then issues the STARTTLS command. After the server accepts
1921 +the command (220), the normal SSL handshake will start. 
1922 +
1923 +<p>Unfortunately it is impossible to handle this situation with a
1924 +normal tunneling software, as they are not prepared to do clear
1925 +text negotiation before running SSL and don't have the slightest
1926 +idea on the SMTP protocol. Therefore the way to go was to extend a
1927 +given mail server software. The first candidate was sendmail-8.9.3,
1928 +as I was a long term sendmail user. After digging around some I
1929 +came to the conclusion, that even though possible, the source code
1930 +was quite difficult to understand and adding the necessary
1931 +configuration options didn't look inviting.</p>
1932 +
1933 +<h2>Postfix</h2>
1934 +
1935 +At this point (February 1999) I checked other mail servers and was
1936 +immedideately fascinated by postfix source. It was very good to
1937 +read and understand, so I decided that if I would take the time,
1938 +then postfix would be the way to go. 
1939 +
1940 +<p>I then started to first change our site to postfix. It took some
1941 +hours to do this, because our mail system is running on a common
1942 +network I administrate for several chairs, each of them with its
1943 +own mail server and domain, but a common user base, so a lot of
1944 +rewriting takes place, we need virtual services for symbolic names
1945 +like "webmaster" etc.</p>
1946 +
1947 +<h2>Postfix/TLS</h2>
1948 +
1949 +Some time after having done this I finally found the time to write
1950 +my TLS extensions for postfix. I took the source of the <code>
1951 +s_server</code> of the OpenSSL package and added a simplified
1952 +version of it to postfix, so that by now we can run the SMTP
1953 +protocol encrypted on the server side. This would also allow us to
1954 +use plain text password authentication, but as it is available
1955 +without cost, I rather decided to go with client certificates. If
1956 +you can offer a client certificate to our server, that is included
1957 +in a list on our server, you can relay your emails through our
1958 +server! 
1959 +
1960 +<h2>Summary</h2>
1961 +
1962 +Postfix/TLS is an addition to the smtpd server, which implements the RFC 2487
1963 + TLS Service Extension and allows UCE control based on client certificates.
1964 +</body>
1965 +</html>
1966 +
1967 diff -Nur snapshot-20010228-orig/html/ssl/rfc2246.txt snapshot-20010228/html/ssl/rfc2246.txt
1968 --- snapshot-20010228-orig/html/ssl/rfc2246.txt Thu Jan  1 01:00:00 1970
1969 +++ snapshot-20010228/html/ssl/rfc2246.txt      Wed Mar 21 13:38:29 2001
1970 @@ -0,0 +1,4483 @@
1971 +
1972 +
1973 +
1974 +
1975 +
1976 +
1977 +Network Working Group                                         T. Dierks
1978 +Request for Comments: 2246                                     Certicom
1979 +Category: Standards Track                                      C. Allen
1980 +                                                               Certicom
1981 +                                                           January 1999
1982 +
1983 +
1984 +                            The TLS Protocol
1985 +                              Version 1.0
1986 +
1987 +Status of this Memo
1988 +
1989 +   This document specifies an Internet standards track protocol for the
1990 +   Internet community, and requests discussion and suggestions for
1991 +   improvements.  Please refer to the current edition of the "Internet
1992 +   Official Protocol Standards" (STD 1) for the standardization state
1993 +   and status of this protocol.  Distribution of this memo is unlimited.
1994 +
1995 +Copyright Notice
1996 +
1997 +   Copyright (C) The Internet Society (1999).  All Rights Reserved.
1998 +
1999 +Abstract
2000 +
2001 +   This document specifies Version 1.0 of the Transport Layer Security
2002 +   (TLS) protocol. The TLS protocol provides communications privacy over
2003 +   the Internet. The protocol allows client/server applications to
2004 +   communicate in a way that is designed to prevent eavesdropping,
2005 +   tampering, or message forgery.
2006 +
2007 +Table of Contents
2008 +
2009 +   1.       Introduction                                              3
2010 +   2.       Goals                                                     4
2011 +   3.       Goals of this document                                    5
2012 +   4.       Presentation language                                     5
2013 +   4.1.     Basic block size                                          6
2014 +   4.2.     Miscellaneous                                             6
2015 +   4.3.     Vectors                                                   6
2016 +   4.4.     Numbers                                                   7
2017 +   4.5.     Enumerateds                                               7
2018 +   4.6.     Constructed types                                         8
2019 +   4.6.1.   Variants                                                  9
2020 +   4.7.     Cryptographic attributes                                 10
2021 +   4.8.     Constants                                                11
2022 +   5.       HMAC and the pseudorandom function                       11
2023 +   6.       The TLS Record Protocol                                  13
2024 +   6.1.     Connection states                                        14
2025 +
2026 +
2027 +
2028 +Dierks & Allen              Standards Track                     [Page 1]
2029 +\f
2030 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2031 +
2032 +
2033 +   6.2.     Record layer                                             16
2034 +   6.2.1.   Fragmentation                                            16
2035 +   6.2.2.   Record compression and decompression                     17
2036 +   6.2.3.   Record payload protection                                18
2037 +   6.2.3.1. Null or standard stream cipher                           19
2038 +   6.2.3.2. CBC block cipher                                         19
2039 +   6.3.     Key calculation                                          21
2040 +   6.3.1.   Export key generation example                            22
2041 +   7.       The TLS Handshake Protocol                               23
2042 +   7.1.     Change cipher spec protocol                              24
2043 +   7.2.     Alert protocol                                           24
2044 +   7.2.1.   Closure alerts                                           25
2045 +   7.2.2.   Error alerts                                             26
2046 +   7.3.     Handshake Protocol overview                              29
2047 +   7.4.     Handshake protocol                                       32
2048 +   7.4.1.   Hello messages                                           33
2049 +   7.4.1.1. Hello request                                            33
2050 +   7.4.1.2. Client hello                                             34
2051 +   7.4.1.3. Server hello                                             36
2052 +   7.4.2.   Server certificate                                       37
2053 +   7.4.3.   Server key exchange message                              39
2054 +   7.4.4.   Certificate request                                      41
2055 +   7.4.5.   Server hello done                                        42
2056 +   7.4.6.   Client certificate                                       43
2057 +   7.4.7.   Client key exchange message                              43
2058 +   7.4.7.1. RSA encrypted premaster secret message                   44
2059 +   7.4.7.2. Client Diffie-Hellman public value                       45
2060 +   7.4.8.   Certificate verify                                       45
2061 +   7.4.9.   Finished                                                 46
2062 +   8.       Cryptographic computations                               47
2063 +   8.1.     Computing the master secret                              47
2064 +   8.1.1.   RSA                                                      48
2065 +   8.1.2.   Diffie-Hellman                                           48
2066 +   9.       Mandatory Cipher Suites                                  48
2067 +   10.      Application data protocol                                48
2068 +   A.       Protocol constant values                                 49
2069 +   A.1.     Record layer                                             49
2070 +   A.2.     Change cipher specs message                              50
2071 +   A.3.     Alert messages                                           50
2072 +   A.4.     Handshake protocol                                       51
2073 +   A.4.1.   Hello messages                                           51
2074 +   A.4.2.   Server authentication and key exchange messages          52
2075 +   A.4.3.   Client authentication and key exchange messages          53
2076 +   A.4.4.   Handshake finalization message                           54
2077 +   A.5.     The CipherSuite                                          54
2078 +   A.6.     The Security Parameters                                  56
2079 +   B.       Glossary                                                 57
2080 +   C.       CipherSuite definitions                                  61
2081 +
2082 +
2083 +
2084 +Dierks & Allen              Standards Track                     [Page 2]
2085 +\f
2086 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2087 +
2088 +
2089 +   D.       Implementation Notes                                     64
2090 +   D.1.     Temporary RSA keys                                       64
2091 +   D.2.     Random Number Generation and Seeding                     64
2092 +   D.3.     Certificates and authentication                          65
2093 +   D.4.     CipherSuites                                             65
2094 +   E.       Backward Compatibility With SSL                          66
2095 +   E.1.     Version 2 client hello                                   67
2096 +   E.2.     Avoiding man-in-the-middle version rollback              68
2097 +   F.       Security analysis                                        69
2098 +   F.1.     Handshake protocol                                       69
2099 +   F.1.1.   Authentication and key exchange                          69
2100 +   F.1.1.1. Anonymous key exchange                                   69
2101 +   F.1.1.2. RSA key exchange and authentication                      70
2102 +   F.1.1.3. Diffie-Hellman key exchange with authentication          71
2103 +   F.1.2.   Version rollback attacks                                 71
2104 +   F.1.3.   Detecting attacks against the handshake protocol         72
2105 +   F.1.4.   Resuming sessions                                        72
2106 +   F.1.5.   MD5 and SHA                                              72
2107 +   F.2.     Protecting application data                              72
2108 +   F.3.     Final notes                                              73
2109 +   G.       Patent Statement                                         74
2110 +            Security Considerations                                  75
2111 +            References                                               75
2112 +            Credits                                                  77
2113 +            Comments                                                 78
2114 +            Full Copyright Statement                                 80
2115 +
2116 +1. Introduction
2117 +
2118 +   The primary goal of the TLS Protocol is to provide privacy and data
2119 +   integrity between two communicating applications. The protocol is
2120 +   composed of two layers: the TLS Record Protocol and the TLS Handshake
2121 +   Protocol. At the lowest level, layered on top of some reliable
2122 +   transport protocol (e.g., TCP[TCP]), is the TLS Record Protocol. The
2123 +   TLS Record Protocol provides connection security that has two basic
2124 +   properties:
2125 +
2126 +     - The connection is private. Symmetric cryptography is used for
2127 +       data encryption (e.g., DES [DES], RC4 [RC4], etc.) The keys for
2128 +       this symmetric encryption are generated uniquely for each
2129 +       connection and are based on a secret negotiated by another
2130 +       protocol (such as the TLS Handshake Protocol). The Record
2131 +       Protocol can also be used without encryption.
2132 +
2133 +     - The connection is reliable. Message transport includes a message
2134 +       integrity check using a keyed MAC. Secure hash functions (e.g.,
2135 +       SHA, MD5, etc.) are used for MAC computations. The Record
2136 +       Protocol can operate without a MAC, but is generally only used in
2137 +
2138 +
2139 +
2140 +Dierks & Allen              Standards Track                     [Page 3]
2141 +\f
2142 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2143 +
2144 +
2145 +       this mode while another protocol is using the Record Protocol as
2146 +       a transport for negotiating security parameters.
2147 +
2148 +   The TLS Record Protocol is used for encapsulation of various higher
2149 +   level protocols. One such encapsulated protocol, the TLS Handshake
2150 +   Protocol, allows the server and client to authenticate each other and
2151 +   to negotiate an encryption algorithm and cryptographic keys before
2152 +   the application protocol transmits or receives its first byte of
2153 +   data. The TLS Handshake Protocol provides connection security that
2154 +   has three basic properties:
2155 +
2156 +     - The peer's identity can be authenticated using asymmetric, or
2157 +       public key, cryptography (e.g., RSA [RSA], DSS [DSS], etc.). This
2158 +       authentication can be made optional, but is generally required
2159 +       for at least one of the peers.
2160 +
2161 +     - The negotiation of a shared secret is secure: the negotiated
2162 +       secret is unavailable to eavesdroppers, and for any authenticated
2163 +       connection the secret cannot be obtained, even by an attacker who
2164 +       can place himself in the middle of the connection.
2165 +
2166 +     - The negotiation is reliable: no attacker can modify the
2167 +       negotiation communication without being detected by the parties
2168 +       to the communication.
2169 +
2170 +   One advantage of TLS is that it is application protocol independent.
2171 +   Higher level protocols can layer on top of the TLS Protocol
2172 +   transparently. The TLS standard, however, does not specify how
2173 +   protocols add security with TLS; the decisions on how to initiate TLS
2174 +   handshaking and how to interpret the authentication certificates
2175 +   exchanged are left up to the judgment of the designers and
2176 +   implementors of protocols which run on top of TLS.
2177 +
2178 +2. Goals
2179 +
2180 +   The goals of TLS Protocol, in order of their priority, are:
2181 +
2182 +    1. Cryptographic security: TLS should be used to establish a secure
2183 +       connection between two parties.
2184 +
2185 +    2. Interoperability: Independent programmers should be able to
2186 +       develop applications utilizing TLS that will then be able to
2187 +       successfully exchange cryptographic parameters without knowledge
2188 +       of one another's code.
2189 +
2190 +    3. Extensibility: TLS seeks to provide a framework into which new
2191 +       public key and bulk encryption methods can be incorporated as
2192 +       necessary. This will also accomplish two sub-goals: to prevent
2193 +
2194 +
2195 +
2196 +Dierks & Allen              Standards Track                     [Page 4]
2197 +\f
2198 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2199 +
2200 +
2201 +       the need to create a new protocol (and risking the introduction
2202 +       of possible new weaknesses) and to avoid the need to implement an
2203 +       entire new security library.
2204 +
2205 +    4. Relative efficiency: Cryptographic operations tend to be highly
2206 +       CPU intensive, particularly public key operations. For this
2207 +       reason, the TLS protocol has incorporated an optional session
2208 +       caching scheme to reduce the number of connections that need to
2209 +       be established from scratch. Additionally, care has been taken to
2210 +       reduce network activity.
2211 +
2212 +3. Goals of this document
2213 +
2214 +   This document and the TLS protocol itself are based on the SSL 3.0
2215 +   Protocol Specification as published by Netscape. The differences
2216 +   between this protocol and SSL 3.0 are not dramatic, but they are
2217 +   significant enough that TLS 1.0 and SSL 3.0 do not interoperate
2218 +   (although TLS 1.0 does incorporate a mechanism by which a TLS
2219 +   implementation can back down to SSL 3.0). This document is intended
2220 +   primarily for readers who will be implementing the protocol and those
2221 +   doing cryptographic analysis of it. The specification has been
2222 +   written with this in mind, and it is intended to reflect the needs of
2223 +   those two groups. For that reason, many of the algorithm-dependent
2224 +   data structures and rules are included in the body of the text (as
2225 +   opposed to in an appendix), providing easier access to them.
2226 +
2227 +   This document is not intended to supply any details of service
2228 +   definition nor interface definition, although it does cover select
2229 +   areas of policy as they are required for the maintenance of solid
2230 +   security.
2231 +
2232 +4. Presentation language
2233 +
2234 +   This document deals with the formatting of data in an external
2235 +   representation. The following very basic and somewhat casually
2236 +   defined presentation syntax will be used. The syntax draws from
2237 +   several sources in its structure. Although it resembles the
2238 +   programming language "C" in its syntax and XDR [XDR] in both its
2239 +   syntax and intent, it would be risky to draw too many parallels. The
2240 +   purpose of this presentation language is to document TLS only, not to
2241 +   have general application beyond that particular goal.
2242 +
2243 +
2244 +
2245 +
2246 +
2247 +
2248 +
2249 +
2250 +
2251 +
2252 +Dierks & Allen              Standards Track                     [Page 5]
2253 +\f
2254 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2255 +
2256 +
2257 +4.1. Basic block size
2258 +
2259 +   The representation of all data items is explicitly specified. The
2260 +   basic data block size is one byte (i.e. 8 bits). Multiple byte data
2261 +   items are concatenations of bytes, from left to right, from top to
2262 +   bottom. From the bytestream a multi-byte item (a numeric in the
2263 +   example) is formed (using C notation) by:
2264 +
2265 +       value = (byte[0] << 8*(n-1)) | (byte[1] << 8*(n-2)) |
2266 +               ... | byte[n-1];
2267 +
2268 +   This byte ordering for multi-byte values is the commonplace network
2269 +   byte order or big endian format.
2270 +
2271 +4.2. Miscellaneous
2272 +
2273 +   Comments begin with "/*" and end with "*/".
2274 +
2275 +   Optional components are denoted by enclosing them in "[[ ]]" double
2276 +   brackets.
2277 +
2278 +   Single byte entities containing uninterpreted data are of type
2279 +   opaque.
2280 +
2281 +4.3. Vectors
2282 +
2283 +   A vector (single dimensioned array) is a stream of homogeneous data
2284 +   elements. The size of the vector may be specified at documentation
2285 +   time or left unspecified until runtime. In either case the length
2286 +   declares the number of bytes, not the number of elements, in the
2287 +   vector. The syntax for specifying a new type T' that is a fixed
2288 +   length vector of type T is
2289 +
2290 +       T T'[n];
2291 +
2292 +   Here T' occupies n bytes in the data stream, where n is a multiple of
2293 +   the size of T. The length of the vector is not included in the
2294 +   encoded stream.
2295 +
2296 +   In the following example, Datum is defined to be three consecutive
2297 +   bytes that the protocol does not interpret, while Data is three
2298 +   consecutive Datum, consuming a total of nine bytes.
2299 +
2300 +       opaque Datum[3];      /* three uninterpreted bytes */
2301 +       Datum Data[9];        /* 3 consecutive 3 byte vectors */
2302 +
2303 +
2304 +
2305 +
2306 +
2307 +
2308 +Dierks & Allen              Standards Track                     [Page 6]
2309 +\f
2310 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2311 +
2312 +
2313 +   Variable length vectors are defined by specifying a subrange of legal
2314 +   lengths, inclusively, using the notation <floor..ceiling>.  When
2315 +   encoded, the actual length precedes the vector's contents in the byte
2316 +   stream. The length will be in the form of a number consuming as many
2317 +   bytes as required to hold the vector's specified maximum (ceiling)
2318 +   length. A variable length vector with an actual length field of zero
2319 +   is referred to as an empty vector.
2320 +
2321 +       T T'<floor..ceiling>;
2322 +
2323 +   In the following example, mandatory is a vector that must contain
2324 +   between 300 and 400 bytes of type opaque. It can never be empty. The
2325 +   actual length field consumes two bytes, a uint16, sufficient to
2326 +   represent the value 400 (see Section 4.4). On the other hand, longer
2327 +   can represent up to 800 bytes of data, or 400 uint16 elements, and it
2328 +   may be empty. Its encoding will include a two byte actual length
2329 +   field prepended to the vector. The length of an encoded vector must
2330 +   be an even multiple of the length of a single element (for example, a
2331 +   17 byte vector of uint16 would be illegal).
2332 +
2333 +       opaque mandatory<300..400>;
2334 +             /* length field is 2 bytes, cannot be empty */
2335 +       uint16 longer<0..800>;
2336 +             /* zero to 400 16-bit unsigned integers */
2337 +
2338 +4.4. Numbers
2339 +
2340 +   The basic numeric data type is an unsigned byte (uint8). All larger
2341 +   numeric data types are formed from fixed length series of bytes
2342 +   concatenated as described in Section 4.1 and are also unsigned. The
2343 +   following numeric types are predefined.
2344 +
2345 +       uint8 uint16[2];
2346 +       uint8 uint24[3];
2347 +       uint8 uint32[4];
2348 +       uint8 uint64[8];
2349 +
2350 +   All values, here and elsewhere in the specification, are stored in
2351 +   "network" or "big-endian" order; the uint32 represented by the hex
2352 +   bytes 01 02 03 04 is equivalent to the decimal value 16909060.
2353 +
2354 +4.5. Enumerateds
2355 +
2356 +   An additional sparse data type is available called enum. A field of
2357 +   type enum can only assume the values declared in the definition.
2358 +   Each definition is a different type. Only enumerateds of the same
2359 +   type may be assigned or compared. Every element of an enumerated must
2360 +
2361 +
2362 +
2363 +
2364 +Dierks & Allen              Standards Track                     [Page 7]
2365 +\f
2366 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2367 +
2368 +
2369 +   be assigned a value, as demonstrated in the following example.  Since
2370 +   the elements of the enumerated are not ordered, they can be assigned
2371 +   any unique value, in any order.
2372 +
2373 +       enum { e1(v1), e2(v2), ... , en(vn) [[, (n)]] } Te;
2374 +
2375 +   Enumerateds occupy as much space in the byte stream as would its
2376 +   maximal defined ordinal value. The following definition would cause
2377 +   one byte to be used to carry fields of type Color.
2378 +
2379 +       enum { red(3), blue(5), white(7) } Color;
2380 +
2381 +   One may optionally specify a value without its associated tag to
2382 +   force the width definition without defining a superfluous element.
2383 +   In the following example, Taste will consume two bytes in the data
2384 +   stream but can only assume the values 1, 2 or 4.
2385 +
2386 +       enum { sweet(1), sour(2), bitter(4), (32000) } Taste;
2387 +
2388 +   The names of the elements of an enumeration are scoped within the
2389 +   defined type. In the first example, a fully qualified reference to
2390 +   the second element of the enumeration would be Color.blue. Such
2391 +   qualification is not required if the target of the assignment is well
2392 +   specified.
2393 +
2394 +       Color color = Color.blue;     /* overspecified, legal */
2395 +       Color color = blue;           /* correct, type implicit */
2396 +
2397 +   For enumerateds that are never converted to external representation,
2398 +   the numerical information may be omitted.
2399 +
2400 +       enum { low, medium, high } Amount;
2401 +
2402 +4.6. Constructed types
2403 +
2404 +   Structure types may be constructed from primitive types for
2405 +   convenience. Each specification declares a new, unique type. The
2406 +   syntax for definition is much like that of C.
2407 +
2408 +       struct {
2409 +         T1 f1;
2410 +         T2 f2;
2411 +         ...
2412 +         Tn fn;
2413 +       } [[T]];
2414 +
2415 +
2416 +
2417 +
2418 +
2419 +
2420 +Dierks & Allen              Standards Track                     [Page 8]
2421 +\f
2422 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2423 +
2424 +
2425 +   The fields within a structure may be qualified using the type's name
2426 +   using a syntax much like that available for enumerateds. For example,
2427 +   T.f2 refers to the second field of the previous declaration.
2428 +   Structure definitions may be embedded.
2429 +
2430 +4.6.1. Variants
2431 +
2432 +   Defined structures may have variants based on some knowledge that is
2433 +   available within the environment. The selector must be an enumerated
2434 +   type that defines the possible variants the structure defines. There
2435 +   must be a case arm for every element of the enumeration declared in
2436 +   the select. The body of the variant structure may be given a label
2437 +   for reference. The mechanism by which the variant is selected at
2438 +   runtime is not prescribed by the presentation language.
2439 +
2440 +       struct {
2441 +           T1 f1;
2442 +           T2 f2;
2443 +           ....
2444 +           Tn fn;
2445 +           select (E) {
2446 +               case e1: Te1;
2447 +               case e2: Te2;
2448 +               ....
2449 +               case en: Ten;
2450 +           } [[fv]];
2451 +       } [[Tv]];
2452 +
2453 +   For example:
2454 +
2455 +       enum { apple, orange } VariantTag;
2456 +       struct {
2457 +           uint16 number;
2458 +           opaque string<0..10>; /* variable length */
2459 +       } V1;
2460 +       struct {
2461 +           uint32 number;
2462 +           opaque string[10];    /* fixed length */
2463 +       } V2;
2464 +       struct {
2465 +           select (VariantTag) { /* value of selector is implicit */
2466 +               case apple: V1;   /* VariantBody, tag = apple */
2467 +               case orange: V2;  /* VariantBody, tag = orange */
2468 +           } variant_body;       /* optional label on variant */
2469 +       } VariantRecord;
2470 +
2471 +   Variant structures may be qualified (narrowed) by specifying a value
2472 +   for the selector prior to the type. For example, a
2473 +
2474 +
2475 +
2476 +Dierks & Allen              Standards Track                     [Page 9]
2477 +\f
2478 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2479 +
2480 +
2481 +       orange VariantRecord
2482 +
2483 +   is a narrowed type of a VariantRecord containing a variant_body of
2484 +   type V2.
2485 +
2486 +4.7. Cryptographic attributes
2487 +
2488 +   The four cryptographic operations digital signing, stream cipher
2489 +   encryption, block cipher encryption, and public key encryption are
2490 +   designated digitally-signed, stream-ciphered, block-ciphered, and
2491 +   public-key-encrypted, respectively. A field's cryptographic
2492 +   processing is specified by prepending an appropriate key word
2493 +   designation before the field's type specification. Cryptographic keys
2494 +   are implied by the current session state (see Section 6.1).
2495 +
2496 +   In digital signing, one-way hash functions are used as input for a
2497 +   signing algorithm. A digitally-signed element is encoded as an opaque
2498 +   vector <0..2^16-1>, where the length is specified by the signing
2499 +   algorithm and key.
2500 +
2501 +   In RSA signing, a 36-byte structure of two hashes (one SHA and one
2502 +   MD5) is signed (encrypted with the private key). It is encoded with
2503 +   PKCS #1 block type 0 or type 1 as described in [PKCS1].
2504 +
2505 +   In DSS, the 20 bytes of the SHA hash are run directly through the
2506 +   Digital Signing Algorithm with no additional hashing. This produces
2507 +   two values, r and s. The DSS signature is an opaque vector, as above,
2508 +   the contents of which are the DER encoding of:
2509 +
2510 +       Dss-Sig-Value  ::=  SEQUENCE  {
2511 +            r       INTEGER,
2512 +            s       INTEGER
2513 +       }
2514 +
2515 +   In stream cipher encryption, the plaintext is exclusive-ORed with an
2516 +   identical amount of output generated from a cryptographically-secure
2517 +   keyed pseudorandom number generator.
2518 +
2519 +   In block cipher encryption, every block of plaintext encrypts to a
2520 +   block of ciphertext. All block cipher encryption is done in CBC
2521 +   (Cipher Block Chaining) mode, and all items which are block-ciphered
2522 +   will be an exact multiple of the cipher block length.
2523 +
2524 +   In public key encryption, a public key algorithm is used to encrypt
2525 +   data in such a way that it can be decrypted only with the matching
2526 +   private key. A public-key-encrypted element is encoded as an opaque
2527 +   vector <0..2^16-1>, where the length is specified by the signing
2528 +   algorithm and key.
2529 +
2530 +
2531 +
2532 +Dierks & Allen              Standards Track                    [Page 10]
2533 +\f
2534 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2535 +
2536 +
2537 +   An RSA encrypted value is encoded with PKCS #1 block type 2 as
2538 +   described in [PKCS1].
2539 +
2540 +   In the following example:
2541 +
2542 +       stream-ciphered struct {
2543 +           uint8 field1;
2544 +           uint8 field2;
2545 +           digitally-signed opaque hash[20];
2546 +       } UserType;
2547 +
2548 +   The contents of hash are used as input for the signing algorithm,
2549 +   then the entire structure is encrypted with a stream cipher. The
2550 +   length of this structure, in bytes would be equal to 2 bytes for
2551 +   field1 and field2, plus two bytes for the length of the signature,
2552 +   plus the length of the output of the signing algorithm. This is known
2553 +   due to the fact that the algorithm and key used for the signing are
2554 +   known prior to encoding or decoding this structure.
2555 +
2556 +4.8. Constants
2557 +
2558 +   Typed constants can be defined for purposes of specification by
2559 +   declaring a symbol of the desired type and assigning values to it.
2560 +   Under-specified types (opaque, variable length vectors, and
2561 +   structures that contain opaque) cannot be assigned values. No fields
2562 +   of a multi-element structure or vector may be elided.
2563 +
2564 +   For example,
2565 +
2566 +       struct {
2567 +           uint8 f1;
2568 +           uint8 f2;
2569 +       } Example1;
2570 +
2571 +       Example1 ex1 = {1, 4};  /* assigns f1 = 1, f2 = 4 */
2572 +
2573 +5. HMAC and the pseudorandom function
2574 +
2575 +   A number of operations in the TLS record and handshake layer required
2576 +   a keyed MAC; this is a secure digest of some data protected by a
2577 +   secret. Forging the MAC is infeasible without knowledge of the MAC
2578 +   secret. The construction we use for this operation is known as HMAC,
2579 +   described in [HMAC].
2580 +
2581 +   HMAC can be used with a variety of different hash algorithms. TLS
2582 +   uses it in the handshake with two different algorithms: MD5 and SHA-
2583 +   1, denoting these as HMAC_MD5(secret, data) and HMAC_SHA(secret,
2584 +
2585 +
2586 +
2587 +
2588 +Dierks & Allen              Standards Track                    [Page 11]
2589 +\f
2590 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2591 +
2592 +
2593 +   data). Additional hash algorithms can be defined by cipher suites and
2594 +   used to protect record data, but MD5 and SHA-1 are hard coded into
2595 +   the description of the handshaking for this version of the protocol.
2596 +
2597 +   In addition, a construction is required to do expansion of secrets
2598 +   into blocks of data for the purposes of key generation or validation.
2599 +   This pseudo-random function (PRF) takes as input a secret, a seed,
2600 +   and an identifying label and produces an output of arbitrary length.
2601 +
2602 +   In order to make the PRF as secure as possible, it uses two hash
2603 +   algorithms in a way which should guarantee its security if either
2604 +   algorithm remains secure.
2605 +
2606 +   First, we define a data expansion function, P_hash(secret, data)
2607 +   which uses a single hash function to expand a secret and seed into an
2608 +   arbitrary quantity of output:
2609 +
2610 +       P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
2611 +                              HMAC_hash(secret, A(2) + seed) +
2612 +                              HMAC_hash(secret, A(3) + seed) + ...
2613 +
2614 +   Where + indicates concatenation.
2615 +
2616 +   A() is defined as:
2617 +       A(0) = seed
2618 +       A(i) = HMAC_hash(secret, A(i-1))
2619 +
2620 +   P_hash can be iterated as many times as is necessary to produce the
2621 +   required quantity of data. For example, if P_SHA-1 was being used to
2622 +   create 64 bytes of data, it would have to be iterated 4 times
2623 +   (through A(4)), creating 80 bytes of output data; the last 16 bytes
2624 +   of the final iteration would then be discarded, leaving 64 bytes of
2625 +   output data.
2626 +
2627 +   TLS's PRF is created by splitting the secret into two halves and
2628 +   using one half to generate data with P_MD5 and the other half to
2629 +   generate data with P_SHA-1, then exclusive-or'ing the outputs of
2630 +   these two expansion functions together.
2631 +
2632 +   S1 and S2 are the two halves of the secret and each is the same
2633 +   length. S1 is taken from the first half of the secret, S2 from the
2634 +   second half. Their length is created by rounding up the length of the
2635 +   overall secret divided by two; thus, if the original secret is an odd
2636 +   number of bytes long, the last byte of S1 will be the same as the
2637 +   first byte of S2.
2638 +
2639 +       L_S = length in bytes of secret;
2640 +       L_S1 = L_S2 = ceil(L_S / 2);
2641 +
2642 +
2643 +
2644 +Dierks & Allen              Standards Track                    [Page 12]
2645 +\f
2646 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2647 +
2648 +
2649 +   The secret is partitioned into two halves (with the possibility of
2650 +   one shared byte) as described above, S1 taking the first L_S1 bytes
2651 +   and S2 the last L_S2 bytes.
2652 +
2653 +   The PRF is then defined as the result of mixing the two pseudorandom
2654 +   streams by exclusive-or'ing them together.
2655 +
2656 +       PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
2657 +                                  P_SHA-1(S2, label + seed);
2658 +
2659 +   The label is an ASCII string. It should be included in the exact form
2660 +   it is given without a length byte or trailing null character.  For
2661 +   example, the label "slithy toves" would be processed by hashing the
2662 +   following bytes:
2663 +
2664 +       73 6C 69 74 68 79 20 74 6F 76 65 73
2665 +
2666 +   Note that because MD5 produces 16 byte outputs and SHA-1 produces 20
2667 +   byte outputs, the boundaries of their internal iterations will not be
2668 +   aligned; to generate a 80 byte output will involve P_MD5 being
2669 +   iterated through A(5), while P_SHA-1 will only iterate through A(4).
2670 +
2671 +6. The TLS Record Protocol
2672 +
2673 +   The TLS Record Protocol is a layered protocol. At each layer,
2674 +   messages may include fields for length, description, and content.
2675 +   The Record Protocol takes messages to be transmitted, fragments the
2676 +   data into manageable blocks, optionally compresses the data, applies
2677 +   a MAC, encrypts, and transmits the result. Received data is
2678 +   decrypted, verified, decompressed, and reassembled, then delivered to
2679 +   higher level clients.
2680 +
2681 +   Four record protocol clients are described in this document: the
2682 +   handshake protocol, the alert protocol, the change cipher spec
2683 +   protocol, and the application data protocol. In order to allow
2684 +   extension of the TLS protocol, additional record types can be
2685 +   supported by the record protocol. Any new record types should
2686 +   allocate type values immediately beyond the ContentType values for
2687 +   the four record types described here (see Appendix A.2). If a TLS
2688 +   implementation receives a record type it does not understand, it
2689 +   should just ignore it. Any protocol designed for use over TLS must be
2690 +   carefully designed to deal with all possible attacks against it.
2691 +   Note that because the type and length of a record are not protected
2692 +   by encryption, care should be take to minimize the value of traffic
2693 +   analysis of these values.
2694 +
2695 +
2696 +
2697 +
2698 +
2699 +
2700 +Dierks & Allen              Standards Track                    [Page 13]
2701 +\f
2702 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2703 +
2704 +
2705 +6.1. Connection states
2706 +
2707 +   A TLS connection state is the operating environment of the TLS Record
2708 +   Protocol. It specifies a compression algorithm, encryption algorithm,
2709 +   and MAC algorithm. In addition, the parameters for these algorithms
2710 +   are known: the MAC secret and the bulk encryption keys and IVs for
2711 +   the connection in both the read and the write directions. Logically,
2712 +   there are always four connection states outstanding: the current read
2713 +   and write states, and the pending read and write states. All records
2714 +   are processed under the current read and write states. The security
2715 +   parameters for the pending states can be set by the TLS Handshake
2716 +   Protocol, and the Handshake Protocol can selectively make either of
2717 +   the pending states current, in which case the appropriate current
2718 +   state is disposed of and replaced with the pending state; the pending
2719 +   state is then reinitialized to an empty state. It is illegal to make
2720 +   a state which has not been initialized with security parameters a
2721 +   current state. The initial current state always specifies that no
2722 +   encryption, compression, or MAC will be used.
2723 +
2724 +   The security parameters for a TLS Connection read and write state are
2725 +   set by providing the following values:
2726 +
2727 +   connection end
2728 +       Whether this entity is considered the "client" or the "server" in
2729 +       this connection.
2730 +
2731 +   bulk encryption algorithm
2732 +       An algorithm to be used for bulk encryption. This specification
2733 +       includes the key size of this algorithm, how much of that key is
2734 +       secret, whether it is a block or stream cipher, the block size of
2735 +       the cipher (if appropriate), and whether it is considered an
2736 +       "export" cipher.
2737 +
2738 +   MAC algorithm
2739 +       An algorithm to be used for message authentication. This
2740 +       specification includes the size of the hash which is returned by
2741 +       the MAC algorithm.
2742 +
2743 +   compression algorithm
2744 +       An algorithm to be used for data compression. This specification
2745 +       must include all information the algorithm requires to do
2746 +       compression.
2747 +
2748 +   master secret
2749 +       A 48 byte secret shared between the two peers in the connection.
2750 +
2751 +   client random
2752 +       A 32 byte value provided by the client.
2753 +
2754 +
2755 +
2756 +Dierks & Allen              Standards Track                    [Page 14]
2757 +\f
2758 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2759 +
2760 +
2761 +   server random
2762 +       A 32 byte value provided by the server.
2763 +
2764 +   These parameters are defined in the presentation language as:
2765 +
2766 +       enum { server, client } ConnectionEnd;
2767 +
2768 +       enum { null, rc4, rc2, des, 3des, des40 } BulkCipherAlgorithm;
2769 +
2770 +       enum { stream, block } CipherType;
2771 +
2772 +       enum { true, false } IsExportable;
2773 +
2774 +       enum { null, md5, sha } MACAlgorithm;
2775 +
2776 +       enum { null(0), (255) } CompressionMethod;
2777 +
2778 +       /* The algorithms specified in CompressionMethod,
2779 +          BulkCipherAlgorithm, and MACAlgorithm may be added to. */
2780 +
2781 +       struct {
2782 +           ConnectionEnd          entity;
2783 +           BulkCipherAlgorithm    bulk_cipher_algorithm;
2784 +           CipherType             cipher_type;
2785 +           uint8                  key_size;
2786 +           uint8                  key_material_length;
2787 +           IsExportable           is_exportable;
2788 +           MACAlgorithm           mac_algorithm;
2789 +           uint8                  hash_size;
2790 +           CompressionMethod      compression_algorithm;
2791 +           opaque                 master_secret[48];
2792 +           opaque                 client_random[32];
2793 +           opaque                 server_random[32];
2794 +       } SecurityParameters;
2795 +
2796 +   The record layer will use the security parameters to generate the
2797 +   following six items:
2798 +
2799 +       client write MAC secret
2800 +       server write MAC secret
2801 +       client write key
2802 +       server write key
2803 +       client write IV (for block ciphers only)
2804 +       server write IV (for block ciphers only)
2805 +
2806 +   The client write parameters are used by the server when receiving and
2807 +   processing records and vice-versa. The algorithm used for generating
2808 +   these items from the security parameters is described in section 6.3.
2809 +
2810 +
2811 +
2812 +Dierks & Allen              Standards Track                    [Page 15]
2813 +\f
2814 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2815 +
2816 +
2817 +   Once the security parameters have been set and the keys have been
2818 +   generated, the connection states can be instantiated by making them
2819 +   the current states. These current states must be updated for each
2820 +   record processed. Each connection state includes the following
2821 +   elements:
2822 +
2823 +   compression state
2824 +       The current state of the compression algorithm.
2825 +
2826 +   cipher state
2827 +       The current state of the encryption algorithm. This will consist
2828 +       of the scheduled key for that connection. In addition, for block
2829 +       ciphers running in CBC mode (the only mode specified for TLS),
2830 +       this will initially contain the IV for that connection state and
2831 +       be updated to contain the ciphertext of the last block encrypted
2832 +       or decrypted as records are processed. For stream ciphers, this
2833 +       will contain whatever the necessary state information is to allow
2834 +       the stream to continue to encrypt or decrypt data.
2835 +
2836 +   MAC secret
2837 +       The MAC secret for this connection as generated above.
2838 +
2839 +   sequence number
2840 +       Each connection state contains a sequence number, which is
2841 +       maintained separately for read and write states. The sequence
2842 +       number must be set to zero whenever a connection state is made
2843 +       the active state. Sequence numbers are of type uint64 and may not
2844 +       exceed 2^64-1. A sequence number is incremented after each
2845 +       record: specifically, the first record which is transmitted under
2846 +       a particular connection state should use sequence number 0.
2847 +
2848 +6.2. Record layer
2849 +
2850 +   The TLS Record Layer receives uninterpreted data from higher layers
2851 +   in non-empty blocks of arbitrary size.
2852 +
2853 +6.2.1. Fragmentation
2854 +
2855 +   The record layer fragments information blocks into TLSPlaintext
2856 +   records carrying data in chunks of 2^14 bytes or less. Client message
2857 +   boundaries are not preserved in the record layer (i.e., multiple
2858 +   client messages of the same ContentType may be coalesced into a
2859 +   single TLSPlaintext record, or a single message may be fragmented
2860 +   across several records).
2861 +
2862 +       struct {
2863 +           uint8 major, minor;
2864 +       } ProtocolVersion;
2865 +
2866 +
2867 +
2868 +Dierks & Allen              Standards Track                    [Page 16]
2869 +\f
2870 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2871 +
2872 +
2873 +       enum {
2874 +           change_cipher_spec(20), alert(21), handshake(22),
2875 +           application_data(23), (255)
2876 +       } ContentType;
2877 +
2878 +       struct {
2879 +           ContentType type;
2880 +           ProtocolVersion version;
2881 +           uint16 length;
2882 +           opaque fragment[TLSPlaintext.length];
2883 +       } TLSPlaintext;
2884 +
2885 +   type
2886 +       The higher level protocol used to process the enclosed fragment.
2887 +
2888 +   version
2889 +       The version of the protocol being employed. This document
2890 +       describes TLS Version 1.0, which uses the version { 3, 1 }. The
2891 +       version value 3.1 is historical: TLS version 1.0 is a minor
2892 +       modification to the SSL 3.0 protocol, which bears the version
2893 +       value 3.0. (See Appendix A.1).
2894 +
2895 +   length
2896 +       The length (in bytes) of the following TLSPlaintext.fragment.
2897 +       The length should not exceed 2^14.
2898 +
2899 +   fragment
2900 +       The application data. This data is transparent and treated as an
2901 +       independent block to be dealt with by the higher level protocol
2902 +       specified by the type field.
2903 +
2904 + Note: Data of different TLS Record layer content types may be
2905 +       interleaved. Application data is generally of lower precedence
2906 +       for transmission than other content types.
2907 +
2908 +6.2.2. Record compression and decompression
2909 +
2910 +   All records are compressed using the compression algorithm defined in
2911 +   the current session state. There is always an active compression
2912 +   algorithm; however, initially it is defined as
2913 +   CompressionMethod.null. The compression algorithm translates a
2914 +   TLSPlaintext structure into a TLSCompressed structure. Compression
2915 +   functions are initialized with default state information whenever a
2916 +   connection state is made active.
2917 +
2918 +
2919 +
2920 +
2921 +
2922 +
2923 +
2924 +Dierks & Allen              Standards Track                    [Page 17]
2925 +\f
2926 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2927 +
2928 +
2929 +   Compression must be lossless and may not increase the content length
2930 +   by more than 1024 bytes. If the decompression function encounters a
2931 +   TLSCompressed.fragment that would decompress to a length in excess of
2932 +   2^14 bytes, it should report a fatal decompression failure error.
2933 +
2934 +       struct {
2935 +           ContentType type;       /* same as TLSPlaintext.type */
2936 +           ProtocolVersion version;/* same as TLSPlaintext.version */
2937 +           uint16 length;
2938 +           opaque fragment[TLSCompressed.length];
2939 +       } TLSCompressed;
2940 +
2941 +   length
2942 +       The length (in bytes) of the following TLSCompressed.fragment.
2943 +       The length should not exceed 2^14 + 1024.
2944 +
2945 +   fragment
2946 +       The compressed form of TLSPlaintext.fragment.
2947 +
2948 + Note: A CompressionMethod.null operation is an identity operation; no
2949 +       fields are altered.
2950 +
2951 +   Implementation note:
2952 +       Decompression functions are responsible for ensuring that
2953 +       messages cannot cause internal buffer overflows.
2954 +
2955 +6.2.3. Record payload protection
2956 +
2957 +   The encryption and MAC functions translate a TLSCompressed structure
2958 +   into a TLSCiphertext. The decryption functions reverse the process.
2959 +   The MAC of the record also includes a sequence number so that
2960 +   missing, extra or repeated messages are detectable.
2961 +
2962 +       struct {
2963 +           ContentType type;
2964 +           ProtocolVersion version;
2965 +           uint16 length;
2966 +           select (CipherSpec.cipher_type) {
2967 +               case stream: GenericStreamCipher;
2968 +               case block: GenericBlockCipher;
2969 +           } fragment;
2970 +       } TLSCiphertext;
2971 +
2972 +   type
2973 +       The type field is identical to TLSCompressed.type.
2974 +
2975 +   version
2976 +       The version field is identical to TLSCompressed.version.
2977 +
2978 +
2979 +
2980 +Dierks & Allen              Standards Track                    [Page 18]
2981 +\f
2982 +RFC 2246              The TLS Protocol Version 1.0          January 1999
2983 +
2984 +
2985 +   length
2986 +       The length (in bytes) of the following TLSCiphertext.fragment.
2987 +       The length may not exceed 2^14 + 2048.
2988 +
2989 +   fragment
2990 +       The encrypted form of TLSCompressed.fragment, with the MAC.
2991 +
2992 +6.2.3.1. Null or standard stream cipher
2993 +
2994 +   Stream ciphers (including BulkCipherAlgorithm.null - see Appendix
2995 +   A.6) convert TLSCompressed.fragment structures to and from stream
2996 +   TLSCiphertext.fragment structures.
2997 +
2998 +       stream-ciphered struct {
2999 +           opaque content[TLSCompressed.length];
3000 +           opaque MAC[CipherSpec.hash_size];
3001 +       } GenericStreamCipher;
3002 +
3003 +   The MAC is generated as:
3004 +
3005 +       HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
3006 +                     TLSCompressed.version + TLSCompressed.length +
3007 +                     TLSCompressed.fragment));
3008 +
3009 +   where "+" denotes concatenation.
3010 +
3011 +   seq_num
3012 +       The sequence number for this record.
3013 +
3014 +   hash
3015 +       The hashing algorithm specified by
3016 +       SecurityParameters.mac_algorithm.
3017 +
3018 +   Note that the MAC is computed before encryption. The stream cipher
3019 +   encrypts the entire block, including the MAC. For stream ciphers that
3020 +   do not use a synchronization vector (such as RC4), the stream cipher
3021 +   state from the end of one record is simply used on the subsequent
3022 +   packet. If the CipherSuite is TLS_NULL_WITH_NULL_NULL, encryption
3023 +   consists of the identity operation (i.e., the data is not encrypted
3024 +   and the MAC size is zero implying that no MAC is used).
3025 +   TLSCiphertext.length is TLSCompressed.length plus
3026 +   CipherSpec.hash_size.
3027 +
3028 +6.2.3.2. CBC block cipher
3029 +
3030 +   For block ciphers (such as RC2 or DES), the encryption and MAC
3031 +   functions convert TLSCompressed.fragment structures to and from block
3032 +   TLSCiphertext.fragment structures.
3033 +
3034 +
3035 +
3036 +Dierks & Allen              Standards Track                    [Page 19]
3037 +\f
3038 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3039 +
3040 +
3041 +       block-ciphered struct {
3042 +           opaque content[TLSCompressed.length];
3043 +           opaque MAC[CipherSpec.hash_size];
3044 +           uint8 padding[GenericBlockCipher.padding_length];
3045 +           uint8 padding_length;
3046 +       } GenericBlockCipher;
3047 +
3048 +   The MAC is generated as described in Section 6.2.3.1.
3049 +
3050 +   padding
3051 +       Padding that is added to force the length of the plaintext to be
3052 +       an integral multiple of the block cipher's block length. The
3053 +       padding may be any length up to 255 bytes long, as long as it
3054 +       results in the TLSCiphertext.length being an integral multiple of
3055 +       the block length. Lengths longer than necessary might be
3056 +       desirable to frustrate attacks on a protocol based on analysis of
3057 +       the lengths of exchanged messages. Each uint8 in the padding data
3058 +       vector must be filled with the padding length value.
3059 +
3060 +   padding_length
3061 +       The padding length should be such that the total size of the
3062 +       GenericBlockCipher structure is a multiple of the cipher's block
3063 +       length. Legal values range from zero to 255, inclusive. This
3064 +       length specifies the length of the padding field exclusive of the
3065 +       padding_length field itself.
3066 +
3067 +   The encrypted data length (TLSCiphertext.length) is one more than the
3068 +   sum of TLSCompressed.length, CipherSpec.hash_size, and
3069 +   padding_length.
3070 +
3071 + Example: If the block length is 8 bytes, the content length
3072 +          (TLSCompressed.length) is 61 bytes, and the MAC length is 20
3073 +          bytes, the length before padding is 82 bytes. Thus, the
3074 +          padding length modulo 8 must be equal to 6 in order to make
3075 +          the total length an even multiple of 8 bytes (the block
3076 +          length). The padding length can be 6, 14, 22, and so on,
3077 +          through 254. If the padding length were the minimum necessary,
3078 +          6, the padding would be 6 bytes, each containing the value 6.
3079 +          Thus, the last 8 octets of the GenericBlockCipher before block
3080 +          encryption would be xx 06 06 06 06 06 06 06, where xx is the
3081 +          last octet of the MAC.
3082 +
3083 + Note: With block ciphers in CBC mode (Cipher Block Chaining) the
3084 +       initialization vector (IV) for the first record is generated with
3085 +       the other keys and secrets when the security parameters are set.
3086 +       The IV for subsequent records is the last ciphertext block from
3087 +       the previous record.
3088 +
3089 +
3090 +
3091 +
3092 +Dierks & Allen              Standards Track                    [Page 20]
3093 +\f
3094 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3095 +
3096 +
3097 +6.3. Key calculation
3098 +
3099 +   The Record Protocol requires an algorithm to generate keys, IVs, and
3100 +   MAC secrets from the security parameters provided by the handshake
3101 +   protocol.
3102 +
3103 +   The master secret is hashed into a sequence of secure bytes, which
3104 +   are assigned to the MAC secrets, keys, and non-export IVs required by
3105 +   the current connection state (see Appendix A.6). CipherSpecs require
3106 +   a client write MAC secret, a server write MAC secret, a client write
3107 +   key, a server write key, a client write IV, and a server write IV,
3108 +   which are generated from the master secret in that order. Unused
3109 +   values are empty.
3110 +
3111 +   When generating keys and MAC secrets, the master secret is used as an
3112 +   entropy source, and the random values provide unencrypted salt
3113 +   material and IVs for exportable ciphers.
3114 +
3115 +   To generate the key material, compute
3116 +
3117 +       key_block = PRF(SecurityParameters.master_secret,
3118 +                          "key expansion",
3119 +                          SecurityParameters.server_random +
3120 +                          SecurityParameters.client_random);
3121 +
3122 +   until enough output has been generated. Then the key_block is
3123 +   partitioned as follows:
3124 +
3125 +       client_write_MAC_secret[SecurityParameters.hash_size]
3126 +       server_write_MAC_secret[SecurityParameters.hash_size]
3127 +       client_write_key[SecurityParameters.key_material_length]
3128 +       server_write_key[SecurityParameters.key_material_length]
3129 +       client_write_IV[SecurityParameters.IV_size]
3130 +       server_write_IV[SecurityParameters.IV_size]
3131 +
3132 +   The client_write_IV and server_write_IV are only generated for non-
3133 +   export block ciphers. For exportable block ciphers, the
3134 +   initialization vectors are generated later, as described below. Any
3135 +   extra key_block material is discarded.
3136 +
3137 +   Implementation note:
3138 +       The cipher spec which is defined in this document which requires
3139 +       the most material is 3DES_EDE_CBC_SHA: it requires 2 x 24 byte
3140 +       keys, 2 x 20 byte MAC secrets, and 2 x 8 byte IVs, for a total of
3141 +       104 bytes of key material.
3142 +
3143 +
3144 +
3145 +
3146 +
3147 +
3148 +Dierks & Allen              Standards Track                    [Page 21]
3149 +\f
3150 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3151 +
3152 +
3153 +   Exportable encryption algorithms (for which CipherSpec.is_exportable
3154 +   is true) require additional processing as follows to derive their
3155 +   final write keys:
3156 +
3157 +       final_client_write_key =
3158 +       PRF(SecurityParameters.client_write_key,
3159 +                                  "client write key",
3160 +                                  SecurityParameters.client_random +
3161 +                                  SecurityParameters.server_random);
3162 +       final_server_write_key =
3163 +       PRF(SecurityParameters.server_write_key,
3164 +                                  "server write key",
3165 +                                  SecurityParameters.client_random +
3166 +                                  SecurityParameters.server_random);
3167 +
3168 +   Exportable encryption algorithms derive their IVs solely from the
3169 +   random values from the hello messages:
3170 +
3171 +       iv_block = PRF("", "IV block", SecurityParameters.client_random +
3172 +                      SecurityParameters.server_random);
3173 +
3174 +   The iv_block is partitioned into two initialization vectors as the
3175 +   key_block was above:
3176 +
3177 +       client_write_IV[SecurityParameters.IV_size]
3178 +       server_write_IV[SecurityParameters.IV_size]
3179 +
3180 +   Note that the PRF is used without a secret in this case: this just
3181 +   means that the secret has a length of zero bytes and contributes
3182 +   nothing to the hashing in the PRF.
3183 +
3184 +6.3.1. Export key generation example
3185 +
3186 +   TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 requires five random bytes for
3187 +   each of the two encryption keys and 16 bytes for each of the MAC
3188 +   keys, for a total of 42 bytes of key material. The PRF output is
3189 +   stored in the key_block. The key_block is partitioned, and the write
3190 +   keys are salted because this is an exportable encryption algorithm.
3191 +
3192 +       key_block               = PRF(master_secret,
3193 +                                     "key expansion",
3194 +                                     server_random +
3195 +                                     client_random)[0..41]
3196 +       client_write_MAC_secret = key_block[0..15]
3197 +       server_write_MAC_secret = key_block[16..31]
3198 +       client_write_key        = key_block[32..36]
3199 +       server_write_key        = key_block[37..41]
3200 +
3201 +
3202 +
3203 +
3204 +Dierks & Allen              Standards Track                    [Page 22]
3205 +\f
3206 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3207 +
3208 +
3209 +       final_client_write_key  = PRF(client_write_key,
3210 +                                     "client write key",
3211 +                                     client_random +
3212 +                                     server_random)[0..15]
3213 +       final_server_write_key  = PRF(server_write_key,
3214 +                                     "server write key",
3215 +                                     client_random +
3216 +                                     server_random)[0..15]
3217 +
3218 +       iv_block                = PRF("", "IV block", client_random +
3219 +                                     server_random)[0..15]
3220 +       client_write_IV = iv_block[0..7]
3221 +       server_write_IV = iv_block[8..15]
3222 +
3223 +7. The TLS Handshake Protocol
3224 +
3225 +   The TLS Handshake Protocol consists of a suite of three sub-protocols
3226 +   which are used to allow peers to agree upon security parameters for
3227 +   the record layer, authenticate themselves, instantiate negotiated
3228 +   security parameters, and report error conditions to each other.
3229 +
3230 +   The Handshake Protocol is responsible for negotiating a session,
3231 +   which consists of the following items:
3232 +
3233 +   session identifier
3234 +       An arbitrary byte sequence chosen by the server to identify an
3235 +       active or resumable session state.
3236 +
3237 +   peer certificate
3238 +       X509v3 [X509] certificate of the peer. This element of the state
3239 +       may be null.
3240 +
3241 +   compression method
3242 +       The algorithm used to compress data prior to encryption.
3243 +
3244 +   cipher spec
3245 +       Specifies the bulk data encryption algorithm (such as null, DES,
3246 +       etc.) and a MAC algorithm (such as MD5 or SHA). It also defines
3247 +       cryptographic attributes such as the hash_size. (See Appendix A.6
3248 +       for formal definition)
3249 +
3250 +   master secret
3251 +       48-byte secret shared between the client and server.
3252 +
3253 +   is resumable
3254 +       A flag indicating whether the session can be used to initiate new
3255 +       connections.
3256 +
3257 +
3258 +
3259 +
3260 +Dierks & Allen              Standards Track                    [Page 23]
3261 +\f
3262 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3263 +
3264 +
3265 +   These items are then used to create security parameters for use by
3266 +   the Record Layer when protecting application data. Many connections
3267 +   can be instantiated using the same session through the resumption
3268 +   feature of the TLS Handshake Protocol.
3269 +
3270 +7.1. Change cipher spec protocol
3271 +
3272 +   The change cipher spec protocol exists to signal transitions in
3273 +   ciphering strategies. The protocol consists of a single message,
3274 +   which is encrypted and compressed under the current (not the pending)
3275 +   connection state. The message consists of a single byte of value 1.
3276 +
3277 +       struct {
3278 +           enum { change_cipher_spec(1), (255) } type;
3279 +       } ChangeCipherSpec;
3280 +
3281 +   The change cipher spec message is sent by both the client and server
3282 +   to notify the receiving party that subsequent records will be
3283 +   protected under the newly negotiated CipherSpec and keys. Reception
3284 +   of this message causes the receiver to instruct the Record Layer to
3285 +   immediately copy the read pending state into the read current state.
3286 +   Immediately after sending this message, the sender should instruct
3287 +   the record layer to make the write pending state the write active
3288 +   state. (See section 6.1.) The change cipher spec message is sent
3289 +   during the handshake after the security parameters have been agreed
3290 +   upon, but before the verifying finished message is sent (see section
3291 +   7.4.9).
3292 +
3293 +7.2. Alert protocol
3294 +
3295 +   One of the content types supported by the TLS Record layer is the
3296 +   alert type. Alert messages convey the severity of the message and a
3297 +   description of the alert. Alert messages with a level of fatal result
3298 +   in the immediate termination of the connection. In this case, other
3299 +   connections corresponding to the session may continue, but the
3300 +   session identifier must be invalidated, preventing the failed session
3301 +   from being used to establish new connections. Like other messages,
3302 +   alert messages are encrypted and compressed, as specified by the
3303 +   current connection state.
3304 +
3305 +       enum { warning(1), fatal(2), (255) } AlertLevel;
3306 +
3307 +       enum {
3308 +           close_notify(0),
3309 +           unexpected_message(10),
3310 +           bad_record_mac(20),
3311 +           decryption_failed(21),
3312 +           record_overflow(22),
3313 +
3314 +
3315 +
3316 +Dierks & Allen              Standards Track                    [Page 24]
3317 +\f
3318 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3319 +
3320 +
3321 +           decompression_failure(30),
3322 +           handshake_failure(40),
3323 +           bad_certificate(42),
3324 +           unsupported_certificate(43),
3325 +           certificate_revoked(44),
3326 +           certificate_expired(45),
3327 +           certificate_unknown(46),
3328 +           illegal_parameter(47),
3329 +           unknown_ca(48),
3330 +           access_denied(49),
3331 +           decode_error(50),
3332 +           decrypt_error(51),
3333 +           export_restriction(60),
3334 +           protocol_version(70),
3335 +           insufficient_security(71),
3336 +           internal_error(80),
3337 +           user_canceled(90),
3338 +           no_renegotiation(100),
3339 +           (255)
3340 +       } AlertDescription;
3341 +
3342 +       struct {
3343 +           AlertLevel level;
3344 +           AlertDescription description;
3345 +       } Alert;
3346 +
3347 +7.2.1. Closure alerts
3348 +
3349 +   The client and the server must share knowledge that the connection is
3350 +   ending in order to avoid a truncation attack. Either party may
3351 +   initiate the exchange of closing messages.
3352 +
3353 +   close_notify
3354 +       This message notifies the recipient that the sender will not send
3355 +       any more messages on this connection. The session becomes
3356 +       unresumable if any connection is terminated without proper
3357 +       close_notify messages with level equal to warning.
3358 +
3359 +   Either party may initiate a close by sending a close_notify alert.
3360 +   Any data received after a closure alert is ignored.
3361 +
3362 +   Each party is required to send a close_notify alert before closing
3363 +   the write side of the connection. It is required that the other party
3364 +   respond with a close_notify alert of its own and close down the
3365 +   connection immediately, discarding any pending writes. It is not
3366 +   required for the initiator of the close to wait for the responding
3367 +   close_notify alert before closing the read side of the connection.
3368 +
3369 +
3370 +
3371 +
3372 +Dierks & Allen              Standards Track                    [Page 25]
3373 +\f
3374 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3375 +
3376 +
3377 +   If the application protocol using TLS provides that any data may be
3378 +   carried over the underlying transport after the TLS connection is
3379 +   closed, the TLS implementation must receive the responding
3380 +   close_notify alert before indicating to the application layer that
3381 +   the TLS connection has ended. If the application protocol will not
3382 +   transfer any additional data, but will only close the underlying
3383 +   transport connection, then the implementation may choose to close the
3384 +   transport without waiting for the responding close_notify. No part of
3385 +   this standard should be taken to dictate the manner in which a usage
3386 +   profile for TLS manages its data transport, including when
3387 +   connections are opened or closed.
3388 +
3389 +   NB: It is assumed that closing a connection reliably delivers
3390 +       pending data before destroying the transport.
3391 +
3392 +7.2.2. Error alerts
3393 +
3394 +   Error handling in the TLS Handshake protocol is very simple. When an
3395 +   error is detected, the detecting party sends a message to the other
3396 +   party. Upon transmission or receipt of an fatal alert message, both
3397 +   parties immediately close the connection. Servers and clients are
3398 +   required to forget any session-identifiers, keys, and secrets
3399 +   associated with a failed connection. The following error alerts are
3400 +   defined:
3401 +
3402 +   unexpected_message
3403 +       An inappropriate message was received. This alert is always fatal
3404 +       and should never be observed in communication between proper
3405 +       implementations.
3406 +
3407 +   bad_record_mac
3408 +       This alert is returned if a record is received with an incorrect
3409 +       MAC. This message is always fatal.
3410 +
3411 +   decryption_failed
3412 +       A TLSCiphertext decrypted in an invalid way: either it wasn`t an
3413 +       even multiple of the block length or its padding values, when
3414 +       checked, weren`t correct. This message is always fatal.
3415 +
3416 +   record_overflow
3417 +       A TLSCiphertext record was received which had a length more than
3418 +       2^14+2048 bytes, or a record decrypted to a TLSCompressed record
3419 +       with more than 2^14+1024 bytes. This message is always fatal.
3420 +
3421 +   decompression_failure
3422 +       The decompression function received improper input (e.g. data
3423 +       that would expand to excessive length). This message is always
3424 +       fatal.
3425 +
3426 +
3427 +
3428 +Dierks & Allen              Standards Track                    [Page 26]
3429 +\f
3430 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3431 +
3432 +
3433 +   handshake_failure
3434 +       Reception of a handshake_failure alert message indicates that the
3435 +       sender was unable to negotiate an acceptable set of security
3436 +       parameters given the options available. This is a fatal error.
3437 +
3438 +   bad_certificate
3439 +       A certificate was corrupt, contained signatures that did not
3440 +       verify correctly, etc.
3441 +
3442 +   unsupported_certificate
3443 +       A certificate was of an unsupported type.
3444 +
3445 +   certificate_revoked
3446 +       A certificate was revoked by its signer.
3447 +
3448 +   certificate_expired
3449 +       A certificate has expired or is not currently valid.
3450 +
3451 +   certificate_unknown
3452 +       Some other (unspecified) issue arose in processing the
3453 +       certificate, rendering it unacceptable.
3454 +
3455 +   illegal_parameter
3456 +       A field in the handshake was out of range or inconsistent with
3457 +       other fields. This is always fatal.
3458 +
3459 +   unknown_ca
3460 +       A valid certificate chain or partial chain was received, but the
3461 +       certificate was not accepted because the CA certificate could not
3462 +       be located or couldn`t be matched with a known, trusted CA.  This
3463 +       message is always fatal.
3464 +
3465 +   access_denied
3466 +       A valid certificate was received, but when access control was
3467 +       applied, the sender decided not to proceed with negotiation.
3468 +       This message is always fatal.
3469 +
3470 +   decode_error
3471 +       A message could not be decoded because some field was out of the
3472 +       specified range or the length of the message was incorrect. This
3473 +       message is always fatal.
3474 +
3475 +   decrypt_error
3476 +       A handshake cryptographic operation failed, including being
3477 +       unable to correctly verify a signature, decrypt a key exchange,
3478 +       or validate a finished message.
3479 +
3480 +
3481 +
3482 +
3483 +
3484 +Dierks & Allen              Standards Track                    [Page 27]
3485 +\f
3486 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3487 +
3488 +
3489 +   export_restriction
3490 +       A negotiation not in compliance with export restrictions was
3491 +       detected; for example, attempting to transfer a 1024 bit
3492 +       ephemeral RSA key for the RSA_EXPORT handshake method. This
3493 +       message is always fatal.
3494 +
3495 +   protocol_version
3496 +       The protocol version the client has attempted to negotiate is
3497 +       recognized, but not supported. (For example, old protocol
3498 +       versions might be avoided for security reasons). This message is
3499 +       always fatal.
3500 +
3501 +   insufficient_security
3502 +       Returned instead of handshake_failure when a negotiation has
3503 +       failed specifically because the server requires ciphers more
3504 +       secure than those supported by the client. This message is always
3505 +       fatal.
3506 +
3507 +   internal_error
3508 +       An internal error unrelated to the peer or the correctness of the
3509 +       protocol makes it impossible to continue (such as a memory
3510 +       allocation failure). This message is always fatal.
3511 +
3512 +   user_canceled
3513 +       This handshake is being canceled for some reason unrelated to a
3514 +       protocol failure. If the user cancels an operation after the
3515 +       handshake is complete, just closing the connection by sending a
3516 +       close_notify is more appropriate. This alert should be followed
3517 +       by a close_notify. This message is generally a warning.
3518 +
3519 +   no_renegotiation
3520 +       Sent by the client in response to a hello request or by the
3521 +       server in response to a client hello after initial handshaking.
3522 +       Either of these would normally lead to renegotiation; when that
3523 +       is not appropriate, the recipient should respond with this alert;
3524 +       at that point, the original requester can decide whether to
3525 +       proceed with the connection. One case where this would be
3526 +       appropriate would be where a server has spawned a process to
3527 +       satisfy a request; the process might receive security parameters
3528 +       (key length, authentication, etc.) at startup and it might be
3529 +       difficult to communicate changes to these parameters after that
3530 +       point. This message is always a warning.
3531 +
3532 +   For all errors where an alert level is not explicitly specified, the
3533 +   sending party may determine at its discretion whether this is a fatal
3534 +   error or not; if an alert with a level of warning is received, the
3535 +
3536 +
3537 +
3538 +
3539 +
3540 +Dierks & Allen              Standards Track                    [Page 28]
3541 +\f
3542 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3543 +
3544 +
3545 +   receiving party may decide at its discretion whether to treat this as
3546 +   a fatal error or not. However, all messages which are transmitted
3547 +   with a level of fatal must be treated as fatal messages.
3548 +
3549 +7.3. Handshake Protocol overview
3550 +
3551 +   The cryptographic parameters of the session state are produced by the
3552 +   TLS Handshake Protocol, which operates on top of the TLS Record
3553 +   Layer. When a TLS client and server first start communicating, they
3554 +   agree on a protocol version, select cryptographic algorithms,
3555 +   optionally authenticate each other, and use public-key encryption
3556 +   techniques to generate shared secrets.
3557 +
3558 +   The TLS Handshake Protocol involves the following steps:
3559 +
3560 +     - Exchange hello messages to agree on algorithms, exchange random
3561 +       values, and check for session resumption.
3562 +
3563 +     - Exchange the necessary cryptographic parameters to allow the
3564 +       client and server to agree on a premaster secret.
3565 +
3566 +     - Exchange certificates and cryptographic information to allow the
3567 +       client and server to authenticate themselves.
3568 +
3569 +     - Generate a master secret from the premaster secret and exchanged
3570 +       random values.
3571 +
3572 +     - Provide security parameters to the record layer.
3573 +
3574 +     - Allow the client and server to verify that their peer has
3575 +       calculated the same security parameters and that the handshake
3576 +       occurred without tampering by an attacker.
3577 +
3578 +   Note that higher layers should not be overly reliant on TLS always
3579 +   negotiating the strongest possible connection between two peers:
3580 +   there are a number of ways a man in the middle attacker can attempt
3581 +   to make two entities drop down to the least secure method they
3582 +   support. The protocol has been designed to minimize this risk, but
3583 +   there are still attacks available: for example, an attacker could
3584 +   block access to the port a secure service runs on, or attempt to get
3585 +   the peers to negotiate an unauthenticated connection. The fundamental
3586 +   rule is that higher levels must be cognizant of what their security
3587 +   requirements are and never transmit information over a channel less
3588 +   secure than what they require. The TLS protocol is secure, in that
3589 +   any cipher suite offers its promised level of security: if you
3590 +   negotiate 3DES with a 1024 bit RSA key exchange with a host whose
3591 +   certificate you have verified, you can expect to be that secure.
3592 +
3593 +
3594 +
3595 +
3596 +Dierks & Allen              Standards Track                    [Page 29]
3597 +\f
3598 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3599 +
3600 +
3601 +   However, you should never send data over a link encrypted with 40 bit
3602 +   security unless you feel that data is worth no more than the effort
3603 +   required to break that encryption.
3604 +
3605 +   These goals are achieved by the handshake protocol, which can be
3606 +   summarized as follows: The client sends a client hello message to
3607 +   which the server must respond with a server hello message, or else a
3608 +   fatal error will occur and the connection will fail. The client hello
3609 +   and server hello are used to establish security enhancement
3610 +   capabilities between client and server. The client hello and server
3611 +   hello establish the following attributes: Protocol Version, Session
3612 +   ID, Cipher Suite, and Compression Method. Additionally, two random
3613 +   values are generated and exchanged: ClientHello.random and
3614 +   ServerHello.random.
3615 +
3616 +   The actual key exchange uses up to four messages: the server
3617 +   certificate, the server key exchange, the client certificate, and the
3618 +   client key exchange. New key exchange methods can be created by
3619 +   specifying a format for these messages and defining the use of the
3620 +   messages to allow the client and server to agree upon a shared
3621 +   secret. This secret should be quite long; currently defined key
3622 +   exchange methods exchange secrets which range from 48 to 128 bytes in
3623 +   length.
3624 +
3625 +   Following the hello messages, the server will send its certificate,
3626 +   if it is to be authenticated. Additionally, a server key exchange
3627 +   message may be sent, if it is required (e.g. if their server has no
3628 +   certificate, or if its certificate is for signing only). If the
3629 +   server is authenticated, it may request a certificate from the
3630 +   client, if that is appropriate to the cipher suite selected. Now the
3631 +   server will send the server hello done message, indicating that the
3632 +   hello-message phase of the handshake is complete. The server will
3633 +   then wait for a client response. If the server has sent a certificate
3634 +   request message, the client must send the certificate message. The
3635 +   client key exchange message is now sent, and the content of that
3636 +   message will depend on the public key algorithm selected between the
3637 +   client hello and the server hello. If the client has sent a
3638 +   certificate with signing ability, a digitally-signed certificate
3639 +   verify message is sent to explicitly verify the certificate.
3640 +
3641 +   At this point, a change cipher spec message is sent by the client,
3642 +   and the client copies the pending Cipher Spec into the current Cipher
3643 +   Spec. The client then immediately sends the finished message under
3644 +   the new algorithms, keys, and secrets. In response, the server will
3645 +   send its own change cipher spec message, transfer the pending to the
3646 +   current Cipher Spec, and send its finished message under the new
3647 +
3648 +
3649 +
3650 +
3651 +
3652 +Dierks & Allen              Standards Track                    [Page 30]
3653 +\f
3654 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3655 +
3656 +
3657 +   Cipher Spec. At this point, the handshake is complete and the client
3658 +   and server may begin to exchange application layer data. (See flow
3659 +   chart below.)
3660 +
3661 +      Client                                               Server
3662 +
3663 +      ClientHello                  -------->
3664 +                                                      ServerHello
3665 +                                                     Certificate*
3666 +                                               ServerKeyExchange*
3667 +                                              CertificateRequest*
3668 +                                   <--------      ServerHelloDone
3669 +      Certificate*
3670 +      ClientKeyExchange
3671 +      CertificateVerify*
3672 +      [ChangeCipherSpec]
3673 +      Finished                     -------->
3674 +                                               [ChangeCipherSpec]
3675 +                                   <--------             Finished
3676 +      Application Data             <------->     Application Data
3677 +
3678 +             Fig. 1 - Message flow for a full handshake
3679 +
3680 +   * Indicates optional or situation-dependent messages that are not
3681 +   always sent.
3682 +
3683 +  Note: To help avoid pipeline stalls, ChangeCipherSpec is an
3684 +       independent TLS Protocol content type, and is not actually a TLS
3685 +       handshake message.
3686 +
3687 +   When the client and server decide to resume a previous session or
3688 +   duplicate an existing session (instead of negotiating new security
3689 +   parameters) the message flow is as follows:
3690 +
3691 +   The client sends a ClientHello using the Session ID of the session to
3692 +   be resumed. The server then checks its session cache for a match.  If
3693 +   a match is found, and the server is willing to re-establish the
3694 +   connection under the specified session state, it will send a
3695 +   ServerHello with the same Session ID value. At this point, both
3696 +   client and server must send change cipher spec messages and proceed
3697 +   directly to finished messages. Once the re-establishment is complete,
3698 +   the client and server may begin to exchange application layer data.
3699 +   (See flow chart below.) If a Session ID match is not found, the
3700 +   server generates a new session ID and the TLS client and server
3701 +   perform a full handshake.
3702 +
3703 +
3704 +
3705 +
3706 +
3707 +
3708 +Dierks & Allen              Standards Track                    [Page 31]
3709 +\f
3710 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3711 +
3712 +
3713 +      Client                                                Server
3714 +
3715 +      ClientHello                   -------->
3716 +                                                       ServerHello
3717 +                                                [ChangeCipherSpec]
3718 +                                    <--------             Finished
3719 +      [ChangeCipherSpec]
3720 +      Finished                      -------->
3721 +      Application Data              <------->     Application Data
3722 +
3723 +          Fig. 2 - Message flow for an abbreviated handshake
3724 +
3725 +   The contents and significance of each message will be presented in
3726 +   detail in the following sections.
3727 +
3728 +7.4. Handshake protocol
3729 +
3730 +   The TLS Handshake Protocol is one of the defined higher level clients
3731 +   of the TLS Record Protocol. This protocol is used to negotiate the
3732 +   secure attributes of a session. Handshake messages are supplied to
3733 +   the TLS Record Layer, where they are encapsulated within one or more
3734 +   TLSPlaintext structures, which are processed and transmitted as
3735 +   specified by the current active session state.
3736 +
3737 +       enum {
3738 +           hello_request(0), client_hello(1), server_hello(2),
3739 +           certificate(11), server_key_exchange (12),
3740 +           certificate_request(13), server_hello_done(14),
3741 +           certificate_verify(15), client_key_exchange(16),
3742 +           finished(20), (255)
3743 +       } HandshakeType;
3744 +
3745 +       struct {
3746 +           HandshakeType msg_type;    /* handshake type */
3747 +           uint24 length;             /* bytes in message */
3748 +           select (HandshakeType) {
3749 +               case hello_request:       HelloRequest;
3750 +               case client_hello:        ClientHello;
3751 +               case server_hello:        ServerHello;
3752 +               case certificate:         Certificate;
3753 +               case server_key_exchange: ServerKeyExchange;
3754 +               case certificate_request: CertificateRequest;
3755 +               case server_hello_done:   ServerHelloDone;
3756 +               case certificate_verify:  CertificateVerify;
3757 +               case client_key_exchange: ClientKeyExchange;
3758 +               case finished:            Finished;
3759 +           } body;
3760 +       } Handshake;
3761 +
3762 +
3763 +
3764 +Dierks & Allen              Standards Track                    [Page 32]
3765 +\f
3766 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3767 +
3768 +
3769 +   The handshake protocol messages are presented below in the order they
3770 +   must be sent; sending handshake messages in an unexpected order
3771 +   results in a fatal error. Unneeded handshake messages can be omitted,
3772 +   however. Note one exception to the ordering: the Certificate message
3773 +   is used twice in the handshake (from server to client, then from
3774 +   client to server), but described only in its first position. The one
3775 +   message which is not bound by these ordering rules in the Hello
3776 +   Request message, which can be sent at any time, but which should be
3777 +   ignored by the client if it arrives in the middle of a handshake.
3778 +
3779 +7.4.1. Hello messages
3780 +
3781 +   The hello phase messages are used to exchange security enhancement
3782 +   capabilities between the client and server. When a new session
3783 +   begins, the Record Layer's connection state encryption, hash, and
3784 +   compression algorithms are initialized to null. The current
3785 +   connection state is used for renegotiation messages.
3786 +
3787 +7.4.1.1. Hello request
3788 +
3789 +   When this message will be sent:
3790 +       The hello request message may be sent by the server at any time.
3791 +
3792 +   Meaning of this message:
3793 +       Hello request is a simple notification that the client should
3794 +       begin the negotiation process anew by sending a client hello
3795 +       message when convenient. This message will be ignored by the
3796 +       client if the client is currently negotiating a session. This
3797 +       message may be ignored by the client if it does not wish to
3798 +       renegotiate a session, or the client may, if it wishes, respond
3799 +       with a no_renegotiation alert. Since handshake messages are
3800 +       intended to have transmission precedence over application data,
3801 +       it is expected that the negotiation will begin before no more
3802 +       than a few records are received from the client. If the server
3803 +       sends a hello request but does not receive a client hello in
3804 +       response, it may close the connection with a fatal alert.
3805 +
3806 +   After sending a hello request, servers should not repeat the request
3807 +   until the subsequent handshake negotiation is complete.
3808 +
3809 +   Structure of this message:
3810 +       struct { } HelloRequest;
3811 +
3812 + Note: This message should never be included in the message hashes which
3813 +       are maintained throughout the handshake and used in the finished
3814 +       messages and the certificate verify message.
3815 +
3816 +
3817 +
3818 +
3819 +
3820 +Dierks & Allen              Standards Track                    [Page 33]
3821 +\f
3822 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3823 +
3824 +
3825 +7.4.1.2. Client hello
3826 +
3827 +   When this message will be sent:
3828 +       When a client first connects to a server it is required to send
3829 +       the client hello as its first message. The client can also send a
3830 +       client hello in response to a hello request or on its own
3831 +       initiative in order to renegotiate the security parameters in an
3832 +       existing connection.
3833 +
3834 +       Structure of this message:
3835 +           The client hello message includes a random structure, which is
3836 +           used later in the protocol.
3837 +
3838 +           struct {
3839 +              uint32 gmt_unix_time;
3840 +              opaque random_bytes[28];
3841 +           } Random;
3842 +
3843 +       gmt_unix_time
3844 +       The current time and date in standard UNIX 32-bit format (seconds
3845 +       since the midnight starting Jan 1, 1970, GMT) according to the
3846 +       sender's internal clock. Clocks are not required to be set
3847 +       correctly by the basic TLS Protocol; higher level or application
3848 +       protocols may define additional requirements.
3849 +
3850 +   random_bytes
3851 +       28 bytes generated by a secure random number generator.
3852 +
3853 +   The client hello message includes a variable length session
3854 +   identifier. If not empty, the value identifies a session between the
3855 +   same client and server whose security parameters the client wishes to
3856 +   reuse. The session identifier may be from an earlier connection, this
3857 +   connection, or another currently active connection. The second option
3858 +   is useful if the client only wishes to update the random structures
3859 +   and derived values of a connection, while the third option makes it
3860 +   possible to establish several independent secure connections without
3861 +   repeating the full handshake protocol. These independent connections
3862 +   may occur sequentially or simultaneously; a SessionID becomes valid
3863 +   when the handshake negotiating it completes with the exchange of
3864 +   Finished messages and persists until removed due to aging or because
3865 +   a fatal error was encountered on a connection associated with the
3866 +   session. The actual contents of the SessionID are defined by the
3867 +   server.
3868 +
3869 +       opaque SessionID<0..32>;
3870 +
3871 +
3872 +
3873 +
3874 +
3875 +
3876 +Dierks & Allen              Standards Track                    [Page 34]
3877 +\f
3878 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3879 +
3880 +
3881 +   Warning:
3882 +       Because the SessionID is transmitted without encryption or
3883 +       immediate MAC protection, servers must not place confidential
3884 +       information in session identifiers or let the contents of fake
3885 +       session identifiers cause any breach of security. (Note that the
3886 +       content of the handshake as a whole, including the SessionID, is
3887 +       protected by the Finished messages exchanged at the end of the
3888 +       handshake.)
3889 +
3890 +   The CipherSuite list, passed from the client to the server in the
3891 +   client hello message, contains the combinations of cryptographic
3892 +   algorithms supported by the client in order of the client's
3893 +   preference (favorite choice first). Each CipherSuite defines a key
3894 +   exchange algorithm, a bulk encryption algorithm (including secret key
3895 +   length) and a MAC algorithm. The server will select a cipher suite
3896 +   or, if no acceptable choices are presented, return a handshake
3897 +   failure alert and close the connection.
3898 +
3899 +       uint8 CipherSuite[2];    /* Cryptographic suite selector */
3900 +
3901 +   The client hello includes a list of compression algorithms supported
3902 +   by the client, ordered according to the client's preference.
3903 +
3904 +       enum { null(0), (255) } CompressionMethod;
3905 +
3906 +       struct {
3907 +           ProtocolVersion client_version;
3908 +           Random random;
3909 +           SessionID session_id;
3910 +           CipherSuite cipher_suites<2..2^16-1>;
3911 +           CompressionMethod compression_methods<1..2^8-1>;
3912 +       } ClientHello;
3913 +
3914 +   client_version
3915 +       The version of the TLS protocol by which the client wishes to
3916 +       communicate during this session. This should be the latest
3917 +       (highest valued) version supported by the client. For this
3918 +       version of the specification, the version will be 3.1 (See
3919 +       Appendix E for details about backward compatibility).
3920 +
3921 +   random
3922 +       A client-generated random structure.
3923 +
3924 +   session_id
3925 +       The ID of a session the client wishes to use for this connection.
3926 +       This field should be empty if no session_id is available or the
3927 +       client wishes to generate new security parameters.
3928 +
3929 +
3930 +
3931 +
3932 +Dierks & Allen              Standards Track                    [Page 35]
3933 +\f
3934 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3935 +
3936 +
3937 +   cipher_suites
3938 +       This is a list of the cryptographic options supported by the
3939 +       client, with the client's first preference first. If the
3940 +       session_id field is not empty (implying a session resumption
3941 +       request) this vector must include at least the cipher_suite from
3942 +       that session. Values are defined in Appendix A.5.
3943 +
3944 +   compression_methods
3945 +       This is a list of the compression methods supported by the
3946 +       client, sorted by client preference. If the session_id field is
3947 +       not empty (implying a session resumption request) it must include
3948 +       the compression_method from that session. This vector must
3949 +       contain, and all implementations must support,
3950 +       CompressionMethod.null. Thus, a client and server will always be
3951 +       able to agree on a compression method.
3952 +
3953 +   After sending the client hello message, the client waits for a server
3954 +   hello message. Any other handshake message returned by the server
3955 +   except for a hello request is treated as a fatal error.
3956 +
3957 +   Forward compatibility note:
3958 +       In the interests of forward compatibility, it is permitted for a
3959 +       client hello message to include extra data after the compression
3960 +       methods. This data must be included in the handshake hashes, but
3961 +       must otherwise be ignored. This is the only handshake message for
3962 +       which this is legal; for all other messages, the amount of data
3963 +       in the message must match the description of the message
3964 +       precisely.
3965 +
3966 +7.4.1.3. Server hello
3967 +
3968 +   When this message will be sent:
3969 +       The server will send this message in response to a client hello
3970 +       message when it was able to find an acceptable set of algorithms.
3971 +       If it cannot find such a match, it will respond with a handshake
3972 +       failure alert.
3973 +
3974 +   Structure of this message:
3975 +       struct {
3976 +           ProtocolVersion server_version;
3977 +           Random random;
3978 +           SessionID session_id;
3979 +           CipherSuite cipher_suite;
3980 +           CompressionMethod compression_method;
3981 +       } ServerHello;
3982 +
3983 +
3984 +
3985 +
3986 +
3987 +
3988 +Dierks & Allen              Standards Track                    [Page 36]
3989 +\f
3990 +RFC 2246              The TLS Protocol Version 1.0          January 1999
3991 +
3992 +
3993 +   server_version
3994 +       This field will contain the lower of that suggested by the client
3995 +       in the client hello and the highest supported by the server. For
3996 +       this version of the specification, the version is 3.1 (See
3997 +       Appendix E for details about backward compatibility).
3998 +
3999 +   random
4000 +       This structure is generated by the server and must be different
4001 +       from (and independent of) ClientHello.random.
4002 +
4003 +   session_id
4004 +       This is the identity of the session corresponding to this
4005 +       connection. If the ClientHello.session_id was non-empty, the
4006 +       server will look in its session cache for a match. If a match is
4007 +       found and the server is willing to establish the new connection
4008 +       using the specified session state, the server will respond with
4009 +       the same value as was supplied by the client. This indicates a
4010 +       resumed session and dictates that the parties must proceed
4011 +       directly to the finished messages. Otherwise this field will
4012 +       contain a different value identifying the new session. The server
4013 +       may return an empty session_id to indicate that the session will
4014 +       not be cached and therefore cannot be resumed. If a session is
4015 +       resumed, it must be resumed using the same cipher suite it was
4016 +       originally negotiated with.
4017 +
4018 +   cipher_suite
4019 +       The single cipher suite selected by the server from the list in
4020 +       ClientHello.cipher_suites. For resumed sessions this field is the
4021 +       value from the state of the session being resumed.
4022 +
4023 +   compression_method
4024 +       The single compression algorithm selected by the server from the
4025 +       list in ClientHello.compression_methods. For resumed sessions
4026 +       this field is the value from the resumed session state.
4027 +
4028 +7.4.2. Server certificate
4029 +
4030 +   When this message will be sent:
4031 +       The server must send a certificate whenever the agreed-upon key
4032 +       exchange method is not an anonymous one. This message will always
4033 +       immediately follow the server hello message.
4034 +
4035 +   Meaning of this message:
4036 +       The certificate type must be appropriate for the selected cipher
4037 +       suite's key exchange algorithm, and is generally an X.509v3
4038 +       certificate. It must contain a key which matches the key exchange
4039 +       method, as follows. Unless otherwise specified, the signing
4040 +
4041 +
4042 +
4043 +
4044 +Dierks & Allen              Standards Track                    [Page 37]
4045 +\f
4046 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4047 +
4048 +
4049 +       algorithm for the certificate must be the same as the algorithm
4050 +       for the certificate key. Unless otherwise specified, the public
4051 +       key may be of any length.
4052 +
4053 +       Key Exchange Algorithm  Certificate Key Type
4054 +
4055 +       RSA                     RSA public key; the certificate must
4056 +                               allow the key to be used for encryption.
4057 +
4058 +       RSA_EXPORT              RSA public key of length greater than
4059 +                               512 bits which can be used for signing,
4060 +                               or a key of 512 bits or shorter which
4061 +                               can be used for either encryption or
4062 +                               signing.
4063 +
4064 +       DHE_DSS                 DSS public key.
4065 +
4066 +       DHE_DSS_EXPORT          DSS public key.
4067 +
4068 +       DHE_RSA                 RSA public key which can be used for
4069 +                               signing.
4070 +
4071 +       DHE_RSA_EXPORT          RSA public key which can be used for
4072 +                               signing.
4073 +
4074 +       DH_DSS                  Diffie-Hellman key. The algorithm used
4075 +                               to sign the certificate should be DSS.
4076 +
4077 +       DH_RSA                  Diffie-Hellman key. The algorithm used
4078 +                               to sign the certificate should be RSA.
4079 +
4080 +   All certificate profiles, key and cryptographic formats are defined
4081 +   by the IETF PKIX working group [PKIX]. When a key usage extension is
4082 +   present, the digitalSignature bit must be set for the key to be
4083 +   eligible for signing, as described above, and the keyEncipherment bit
4084 +   must be present to allow encryption, as described above. The
4085 +   keyAgreement bit must be set on Diffie-Hellman certificates.
4086 +
4087 +   As CipherSuites which specify new key exchange methods are specified
4088 +   for the TLS Protocol, they will imply certificate format and the
4089 +   required encoded keying information.
4090 +
4091 +   Structure of this message:
4092 +       opaque ASN.1Cert<1..2^24-1>;
4093 +
4094 +       struct {
4095 +           ASN.1Cert certificate_list<0..2^24-1>;
4096 +       } Certificate;
4097 +
4098 +
4099 +
4100 +Dierks & Allen              Standards Track                    [Page 38]
4101 +\f
4102 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4103 +
4104 +
4105 +   certificate_list
4106 +       This is a sequence (chain) of X.509v3 certificates. The sender's
4107 +       certificate must come first in the list. Each following
4108 +       certificate must directly certify the one preceding it. Because
4109 +       certificate validation requires that root keys be distributed
4110 +       independently, the self-signed certificate which specifies the
4111 +       root certificate authority may optionally be omitted from the
4112 +       chain, under the assumption that the remote end must already
4113 +       possess it in order to validate it in any case.
4114 +
4115 +   The same message type and structure will be used for the client's
4116 +   response to a certificate request message. Note that a client may
4117 +   send no certificates if it does not have an appropriate certificate
4118 +   to send in response to the server's authentication request.
4119 +
4120 + Note: PKCS #7 [PKCS7] is not used as the format for the certificate
4121 +       vector because PKCS #6 [PKCS6] extended certificates are not
4122 +       used. Also PKCS #7 defines a SET rather than a SEQUENCE, making
4123 +       the task of parsing the list more difficult.
4124 +
4125 +7.4.3. Server key exchange message
4126 +
4127 +   When this message will be sent:
4128 +       This message will be sent immediately after the server
4129 +       certificate message (or the server hello message, if this is an
4130 +       anonymous negotiation).
4131 +
4132 +       The server key exchange message is sent by the server only when
4133 +       the server certificate message (if sent) does not contain enough
4134 +       data to allow the client to exchange a premaster secret. This is
4135 +       true for the following key exchange methods:
4136 +
4137 +           RSA_EXPORT (if the public key in the server certificate is
4138 +           longer than 512 bits)
4139 +           DHE_DSS
4140 +           DHE_DSS_EXPORT
4141 +           DHE_RSA
4142 +           DHE_RSA_EXPORT
4143 +           DH_anon
4144 +
4145 +       It is not legal to send the server key exchange message for the
4146 +       following key exchange methods:
4147 +
4148 +           RSA
4149 +           RSA_EXPORT (when the public key in the server certificate is
4150 +           less than or equal to 512 bits in length)
4151 +           DH_DSS
4152 +           DH_RSA
4153 +
4154 +
4155 +
4156 +Dierks & Allen              Standards Track                    [Page 39]
4157 +\f
4158 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4159 +
4160 +
4161 +   Meaning of this message:
4162 +       This message conveys cryptographic information to allow the
4163 +       client to communicate the premaster secret: either an RSA public
4164 +       key to encrypt the premaster secret with, or a Diffie-Hellman
4165 +       public key with which the client can complete a key exchange
4166 +       (with the result being the premaster secret.)
4167 +
4168 +   As additional CipherSuites are defined for TLS which include new key
4169 +   exchange algorithms, the server key exchange message will be sent if
4170 +   and only if the certificate type associated with the key exchange
4171 +   algorithm does not provide enough information for the client to
4172 +   exchange a premaster secret.
4173 +
4174 + Note: According to current US export law, RSA moduli larger than 512
4175 +       bits may not be used for key exchange in software exported from
4176 +       the US. With this message, the larger RSA keys encoded in
4177 +       certificates may be used to sign temporary shorter RSA keys for
4178 +       the RSA_EXPORT key exchange method.
4179 +
4180 +   Structure of this message:
4181 +       enum { rsa, diffie_hellman } KeyExchangeAlgorithm;
4182 +
4183 +       struct {
4184 +           opaque rsa_modulus<1..2^16-1>;
4185 +           opaque rsa_exponent<1..2^16-1>;
4186 +       } ServerRSAParams;
4187 +
4188 +       rsa_modulus
4189 +           The modulus of the server's temporary RSA key.
4190 +
4191 +       rsa_exponent
4192 +           The public exponent of the server's temporary RSA key.
4193 +
4194 +       struct {
4195 +           opaque dh_p<1..2^16-1>;
4196 +           opaque dh_g<1..2^16-1>;
4197 +           opaque dh_Ys<1..2^16-1>;
4198 +       } ServerDHParams;     /* Ephemeral DH parameters */
4199 +
4200 +       dh_p
4201 +           The prime modulus used for the Diffie-Hellman operation.
4202 +
4203 +       dh_g
4204 +           The generator used for the Diffie-Hellman operation.
4205 +
4206 +       dh_Ys
4207 +           The server's Diffie-Hellman public value (g^X mod p).
4208 +
4209 +
4210 +
4211 +
4212 +Dierks & Allen              Standards Track                    [Page 40]
4213 +\f
4214 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4215 +
4216 +
4217 +       struct {
4218 +           select (KeyExchangeAlgorithm) {
4219 +               case diffie_hellman:
4220 +                   ServerDHParams params;
4221 +                   Signature signed_params;
4222 +               case rsa:
4223 +                   ServerRSAParams params;
4224 +                   Signature signed_params;
4225 +           };
4226 +       } ServerKeyExchange;
4227 +
4228 +       params
4229 +           The server's key exchange parameters.
4230 +
4231 +       signed_params
4232 +           For non-anonymous key exchanges, a hash of the corresponding
4233 +           params value, with the signature appropriate to that hash
4234 +           applied.
4235 +
4236 +       md5_hash
4237 +           MD5(ClientHello.random + ServerHello.random + ServerParams);
4238 +
4239 +       sha_hash
4240 +           SHA(ClientHello.random + ServerHello.random + ServerParams);
4241 +
4242 +       enum { anonymous, rsa, dsa } SignatureAlgorithm;
4243 +
4244 +       select (SignatureAlgorithm)
4245 +       {   case anonymous: struct { };
4246 +           case rsa:
4247 +               digitally-signed struct {
4248 +                   opaque md5_hash[16];
4249 +                   opaque sha_hash[20];
4250 +               };
4251 +           case dsa:
4252 +               digitally-signed struct {
4253 +                   opaque sha_hash[20];
4254 +               };
4255 +       } Signature;
4256 +
4257 +7.4.4. Certificate request
4258 +
4259 +   When this message will be sent:
4260 +       A non-anonymous server can optionally request a certificate from
4261 +       the client, if appropriate for the selected cipher suite. This
4262 +       message, if sent, will immediately follow the Server Key Exchange
4263 +       message (if it is sent; otherwise, the Server Certificate
4264 +       message).
4265 +
4266 +
4267 +
4268 +Dierks & Allen              Standards Track                    [Page 41]
4269 +\f
4270 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4271 +
4272 +
4273 +   Structure of this message:
4274 +       enum {
4275 +           rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
4276 +           (255)
4277 +       } ClientCertificateType;
4278 +
4279 +       opaque DistinguishedName<1..2^16-1>;
4280 +
4281 +       struct {
4282 +           ClientCertificateType certificate_types<1..2^8-1>;
4283 +           DistinguishedName certificate_authorities<3..2^16-1>;
4284 +       } CertificateRequest;
4285 +
4286 +       certificate_types
4287 +              This field is a list of the types of certificates requested,
4288 +              sorted in order of the server's preference.
4289 +
4290 +       certificate_authorities
4291 +           A list of the distinguished names of acceptable certificate
4292 +           authorities. These distinguished names may specify a desired
4293 +           distinguished name for a root CA or for a subordinate CA;
4294 +           thus, this message can be used both to describe known roots
4295 +           and a desired authorization space.
4296 +
4297 + Note: DistinguishedName is derived from [X509].
4298 +
4299 + Note: It is a fatal handshake_failure alert for an anonymous server to
4300 +       request client identification.
4301 +
4302 +7.4.5. Server hello done
4303 +
4304 +   When this message will be sent:
4305 +       The server hello done message is sent by the server to indicate
4306 +       the end of the server hello and associated messages. After
4307 +       sending this message the server will wait for a client response.
4308 +
4309 +   Meaning of this message:
4310 +       This message means that the server is done sending messages to
4311 +       support the key exchange, and the client can proceed with its
4312 +       phase of the key exchange.
4313 +
4314 +       Upon receipt of the server hello done message the client should
4315 +       verify that the server provided a valid certificate if required
4316 +       and check that the server hello parameters are acceptable.
4317 +
4318 +   Structure of this message:
4319 +       struct { } ServerHelloDone;
4320 +
4321 +
4322 +
4323 +
4324 +Dierks & Allen              Standards Track                    [Page 42]
4325 +\f
4326 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4327 +
4328 +
4329 +7.4.6. Client certificate
4330 +
4331 +   When this message will be sent:
4332 +       This is the first message the client can send after receiving a
4333 +       server hello done message. This message is only sent if the
4334 +       server requests a certificate. If no suitable certificate is
4335 +       available, the client should send a certificate message
4336 +       containing no certificates. If client authentication is required
4337 +       by the server for the handshake to continue, it may respond with
4338 +       a fatal handshake failure alert. Client certificates are sent
4339 +       using the Certificate structure defined in Section 7.4.2.
4340 +
4341 + Note: When using a static Diffie-Hellman based key exchange method
4342 +       (DH_DSS or DH_RSA), if client authentication is requested, the
4343 +       Diffie-Hellman group and generator encoded in the client's
4344 +       certificate must match the server specified Diffie-Hellman
4345 +       parameters if the client's parameters are to be used for the key
4346 +       exchange.
4347 +
4348 +7.4.7. Client key exchange message
4349 +
4350 +   When this message will be sent:
4351 +       This message is always sent by the client. It will immediately
4352 +       follow the client certificate message, if it is sent. Otherwise
4353 +       it will be the first message sent by the client after it receives
4354 +       the server hello done message.
4355 +
4356 +   Meaning of this message:
4357 +       With this message, the premaster secret is set, either though
4358 +       direct transmission of the RSA-encrypted secret, or by the
4359 +       transmission of Diffie-Hellman parameters which will allow each
4360 +       side to agree upon the same premaster secret. When the key
4361 +       exchange method is DH_RSA or DH_DSS, client certification has
4362 +       been requested, and the client was able to respond with a
4363 +       certificate which contained a Diffie-Hellman public key whose
4364 +       parameters (group and generator) matched those specified by the
4365 +       server in its certificate, this message will not contain any
4366 +       data.
4367 +
4368 +   Structure of this message:
4369 +       The choice of messages depends on which key exchange method has
4370 +       been selected. See Section 7.4.3 for the KeyExchangeAlgorithm
4371 +       definition.
4372 +
4373 +       struct {
4374 +           select (KeyExchangeAlgorithm) {
4375 +               case rsa: EncryptedPreMasterSecret;
4376 +               case diffie_hellman: ClientDiffieHellmanPublic;
4377 +
4378 +
4379 +
4380 +Dierks & Allen              Standards Track                    [Page 43]
4381 +\f
4382 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4383 +
4384 +
4385 +           } exchange_keys;
4386 +       } ClientKeyExchange;
4387 +
4388 +7.4.7.1. RSA encrypted premaster secret message
4389 +
4390 +   Meaning of this message:
4391 +       If RSA is being used for key agreement and authentication, the
4392 +       client generates a 48-byte premaster secret, encrypts it using
4393 +       the public key from the server's certificate or the temporary RSA
4394 +       key provided in a server key exchange message, and sends the
4395 +       result in an encrypted premaster secret message. This structure
4396 +       is a variant of the client key exchange message, not a message in
4397 +       itself.
4398 +
4399 +   Structure of this message:
4400 +       struct {
4401 +           ProtocolVersion client_version;
4402 +           opaque random[46];
4403 +       } PreMasterSecret;
4404 +
4405 +       client_version
4406 +           The latest (newest) version supported by the client. This is
4407 +           used to detect version roll-back attacks. Upon receiving the
4408 +           premaster secret, the server should check that this value
4409 +           matches the value transmitted by the client in the client
4410 +           hello message.
4411 +
4412 +       random
4413 +           46 securely-generated random bytes.
4414 +
4415 +       struct {
4416 +           public-key-encrypted PreMasterSecret pre_master_secret;
4417 +       } EncryptedPreMasterSecret;
4418 +
4419 + Note: An attack discovered by Daniel Bleichenbacher [BLEI] can be used
4420 +       to attack a TLS server which is using PKCS#1 encoded RSA. The
4421 +       attack takes advantage of the fact that by failing in different
4422 +       ways, a TLS server can be coerced into revealing whether a
4423 +       particular message, when decrypted, is properly PKCS#1 formatted
4424 +       or not.
4425 +
4426 +       The best way to avoid vulnerability to this attack is to treat
4427 +       incorrectly formatted messages in a manner indistinguishable from
4428 +       correctly formatted RSA blocks. Thus, when it receives an
4429 +       incorrectly formatted RSA block, a server should generate a
4430 +       random 48-byte value and proceed using it as the premaster
4431 +       secret. Thus, the server will act identically whether the
4432 +       received RSA block is correctly encoded or not.
4433 +
4434 +
4435 +
4436 +Dierks & Allen              Standards Track                    [Page 44]
4437 +\f
4438 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4439 +
4440 +
4441 +       pre_master_secret
4442 +           This random value is generated by the client and is used to
4443 +           generate the master secret, as specified in Section 8.1.
4444 +
4445 +7.4.7.2. Client Diffie-Hellman public value
4446 +
4447 +   Meaning of this message:
4448 +       This structure conveys the client's Diffie-Hellman public value
4449 +       (Yc) if it was not already included in the client's certificate.
4450 +       The encoding used for Yc is determined by the enumerated
4451 +       PublicValueEncoding. This structure is a variant of the client
4452 +       key exchange message, not a message in itself.
4453 +
4454 +   Structure of this message:
4455 +       enum { implicit, explicit } PublicValueEncoding;
4456 +
4457 +       implicit
4458 +           If the client certificate already contains a suitable
4459 +           Diffie-Hellman key, then Yc is implicit and does not need to
4460 +           be sent again. In this case, the Client Key Exchange message
4461 +           will be sent, but will be empty.
4462 +
4463 +       explicit
4464 +           Yc needs to be sent.
4465 +
4466 +       struct {
4467 +           select (PublicValueEncoding) {
4468 +               case implicit: struct { };
4469 +               case explicit: opaque dh_Yc<1..2^16-1>;
4470 +           } dh_public;
4471 +       } ClientDiffieHellmanPublic;
4472 +
4473 +       dh_Yc
4474 +           The client's Diffie-Hellman public value (Yc).
4475 +
4476 +7.4.8. Certificate verify
4477 +
4478 +   When this message will be sent:
4479 +       This message is used to provide explicit verification of a client
4480 +       certificate. This message is only sent following a client
4481 +       certificate that has signing capability (i.e. all certificates
4482 +       except those containing fixed Diffie-Hellman parameters). When
4483 +       sent, it will immediately follow the client key exchange message.
4484 +
4485 +   Structure of this message:
4486 +       struct {
4487 +            Signature signature;
4488 +       } CertificateVerify;
4489 +
4490 +
4491 +
4492 +Dierks & Allen              Standards Track                    [Page 45]
4493 +\f
4494 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4495 +
4496 +
4497 +       The Signature type is defined in 7.4.3.
4498 +
4499 +       CertificateVerify.signature.md5_hash
4500 +           MD5(handshake_messages);
4501 +
4502 +       Certificate.signature.sha_hash
4503 +           SHA(handshake_messages);
4504 +
4505 +   Here handshake_messages refers to all handshake messages sent or
4506 +   received starting at client hello up to but not including this
4507 +   message, including the type and length fields of the handshake
4508 +   messages. This is the concatenation of all the Handshake structures
4509 +   as defined in 7.4 exchanged thus far.
4510 +
4511 +7.4.9. Finished
4512 +
4513 +   When this message will be sent:
4514 +       A finished message is always sent immediately after a change
4515 +       cipher spec message to verify that the key exchange and
4516 +       authentication processes were successful. It is essential that a
4517 +       change cipher spec message be received between the other
4518 +       handshake messages and the Finished message.
4519 +
4520 +   Meaning of this message:
4521 +       The finished message is the first protected with the just-
4522 +       negotiated algorithms, keys, and secrets. Recipients of finished
4523 +       messages must verify that the contents are correct.  Once a side
4524 +       has sent its Finished message and received and validated the
4525 +       Finished message from its peer, it may begin to send and receive
4526 +       application data over the connection.
4527 +
4528 +       struct {
4529 +           opaque verify_data[12];
4530 +       } Finished;
4531 +
4532 +       verify_data
4533 +           PRF(master_secret, finished_label, MD5(handshake_messages) +
4534 +           SHA-1(handshake_messages)) [0..11];
4535 +
4536 +       finished_label
4537 +           For Finished messages sent by the client, the string "client
4538 +           finished". For Finished messages sent by the server, the
4539 +           string "server finished".
4540 +
4541 +       handshake_messages
4542 +           All of the data from all handshake messages up to but not
4543 +           including this message. This is only data visible at the
4544 +           handshake layer and does not include record layer headers.
4545 +
4546 +
4547 +
4548 +Dierks & Allen              Standards Track                    [Page 46]
4549 +\f
4550 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4551 +
4552 +
4553 +           This is the concatenation of all the Handshake structures as
4554 +           defined in 7.4 exchanged thus far.
4555 +
4556 +   It is a fatal error if a finished message is not preceded by a change
4557 +   cipher spec message at the appropriate point in the handshake.
4558 +
4559 +   The hash contained in finished messages sent by the server
4560 +   incorporate Sender.server; those sent by the client incorporate
4561 +   Sender.client. The value handshake_messages includes all handshake
4562 +   messages starting at client hello up to, but not including, this
4563 +   finished message. This may be different from handshake_messages in
4564 +   Section 7.4.8 because it would include the certificate verify message
4565 +   (if sent). Also, the handshake_messages for the finished message sent
4566 +   by the client will be different from that for the finished message
4567 +   sent by the server, because the one which is sent second will include
4568 +   the prior one.
4569 +
4570 + Note: Change cipher spec messages, alerts and any other record types
4571 +       are not handshake messages and are not included in the hash
4572 +       computations. Also, Hello Request messages are omitted from
4573 +       handshake hashes.
4574 +
4575 +8. Cryptographic computations
4576 +
4577 +   In order to begin connection protection, the TLS Record Protocol
4578 +   requires specification of a suite of algorithms, a master secret, and
4579 +   the client and server random values. The authentication, encryption,
4580 +   and MAC algorithms are determined by the cipher_suite selected by the
4581 +   server and revealed in the server hello message. The compression
4582 +   algorithm is negotiated in the hello messages, and the random values
4583 +   are exchanged in the hello messages. All that remains is to calculate
4584 +   the master secret.
4585 +
4586 +8.1. Computing the master secret
4587 +
4588 +   For all key exchange methods, the same algorithm is used to convert
4589 +   the pre_master_secret into the master_secret. The pre_master_secret
4590 +   should be deleted from memory once the master_secret has been
4591 +   computed.
4592 +
4593 +       master_secret = PRF(pre_master_secret, "master secret",
4594 +                           ClientHello.random + ServerHello.random)
4595 +       [0..47];
4596 +
4597 +   The master secret is always exactly 48 bytes in length. The length of
4598 +   the premaster secret will vary depending on key exchange method.
4599 +
4600 +
4601 +
4602 +
4603 +
4604 +Dierks & Allen              Standards Track                    [Page 47]
4605 +\f
4606 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4607 +
4608 +
4609 +8.1.1. RSA
4610 +
4611 +   When RSA is used for server authentication and key exchange, a 48-
4612 +   byte pre_master_secret is generated by the client, encrypted under
4613 +   the server's public key, and sent to the server. The server uses its
4614 +   private key to decrypt the pre_master_secret. Both parties then
4615 +   convert the pre_master_secret into the master_secret, as specified
4616 +   above.
4617 +
4618 +   RSA digital signatures are performed using PKCS #1 [PKCS1] block type
4619 +   1. RSA public key encryption is performed using PKCS #1 block type 2.
4620 +
4621 +8.1.2. Diffie-Hellman
4622 +
4623 +   A conventional Diffie-Hellman computation is performed. The
4624 +   negotiated key (Z) is used as the pre_master_secret, and is converted
4625 +   into the master_secret, as specified above.
4626 +
4627 + Note: Diffie-Hellman parameters are specified by the server, and may
4628 +       be either ephemeral or contained within the server's certificate.
4629 +
4630 +9. Mandatory Cipher Suites
4631 +
4632 +   In the absence of an application profile standard specifying
4633 +   otherwise, a TLS compliant application MUST implement the cipher
4634 +   suite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA.
4635 +
4636 +10. Application data protocol
4637 +
4638 +   Application data messages are carried by the Record Layer and are
4639 +   fragmented, compressed and encrypted based on the current connection
4640 +   state. The messages are treated as transparent data to the record
4641 +   layer.
4642 +
4643 +
4644 +
4645 +
4646 +
4647 +
4648 +
4649 +
4650 +
4651 +
4652 +
4653 +
4654 +
4655 +
4656 +
4657 +
4658 +
4659 +
4660 +Dierks & Allen              Standards Track                    [Page 48]
4661 +\f
4662 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4663 +
4664 +
4665 +A. Protocol constant values
4666 +
4667 +   This section describes protocol types and constants.
4668 +
4669 +A.1. Record layer
4670 +
4671 +    struct {
4672 +        uint8 major, minor;
4673 +    } ProtocolVersion;
4674 +
4675 +    ProtocolVersion version = { 3, 1 };     /* TLS v1.0 */
4676 +
4677 +    enum {
4678 +        change_cipher_spec(20), alert(21), handshake(22),
4679 +        application_data(23), (255)
4680 +    } ContentType;
4681 +
4682 +    struct {
4683 +        ContentType type;
4684 +        ProtocolVersion version;
4685 +        uint16 length;
4686 +        opaque fragment[TLSPlaintext.length];
4687 +    } TLSPlaintext;
4688 +
4689 +    struct {
4690 +        ContentType type;
4691 +        ProtocolVersion version;
4692 +        uint16 length;
4693 +        opaque fragment[TLSCompressed.length];
4694 +    } TLSCompressed;
4695 +
4696 +    struct {
4697 +        ContentType type;
4698 +        ProtocolVersion version;
4699 +        uint16 length;
4700 +        select (CipherSpec.cipher_type) {
4701 +            case stream: GenericStreamCipher;
4702 +            case block:  GenericBlockCipher;
4703 +        } fragment;
4704 +    } TLSCiphertext;
4705 +
4706 +    stream-ciphered struct {
4707 +        opaque content[TLSCompressed.length];
4708 +        opaque MAC[CipherSpec.hash_size];
4709 +    } GenericStreamCipher;
4710 +
4711 +    block-ciphered struct {
4712 +        opaque content[TLSCompressed.length];
4713 +
4714 +
4715 +
4716 +Dierks & Allen              Standards Track                    [Page 49]
4717 +\f
4718 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4719 +
4720 +
4721 +        opaque MAC[CipherSpec.hash_size];
4722 +        uint8 padding[GenericBlockCipher.padding_length];
4723 +        uint8 padding_length;
4724 +    } GenericBlockCipher;
4725 +
4726 +A.2. Change cipher specs message
4727 +
4728 +    struct {
4729 +        enum { change_cipher_spec(1), (255) } type;
4730 +    } ChangeCipherSpec;
4731 +
4732 +A.3. Alert messages
4733 +
4734 +    enum { warning(1), fatal(2), (255) } AlertLevel;
4735 +
4736 +        enum {
4737 +            close_notify(0),
4738 +            unexpected_message(10),
4739 +            bad_record_mac(20),
4740 +            decryption_failed(21),
4741 +            record_overflow(22),
4742 +            decompression_failure(30),
4743 +            handshake_failure(40),
4744 +            bad_certificate(42),
4745 +            unsupported_certificate(43),
4746 +            certificate_revoked(44),
4747 +            certificate_expired(45),
4748 +            certificate_unknown(46),
4749 +            illegal_parameter(47),
4750 +            unknown_ca(48),
4751 +            access_denied(49),
4752 +            decode_error(50),
4753 +            decrypt_error(51),
4754 +            export_restriction(60),
4755 +            protocol_version(70),
4756 +            insufficient_security(71),
4757 +            internal_error(80),
4758 +            user_canceled(90),
4759 +            no_renegotiation(100),
4760 +            (255)
4761 +        } AlertDescription;
4762 +
4763 +    struct {
4764 +        AlertLevel level;
4765 +        AlertDescription description;
4766 +    } Alert;
4767 +
4768 +
4769 +
4770 +
4771 +
4772 +Dierks & Allen              Standards Track                    [Page 50]
4773 +\f
4774 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4775 +
4776 +
4777 +A.4. Handshake protocol
4778 +
4779 +    enum {
4780 +        hello_request(0), client_hello(1), server_hello(2),
4781 +        certificate(11), server_key_exchange (12),
4782 +        certificate_request(13), server_hello_done(14),
4783 +        certificate_verify(15), client_key_exchange(16),
4784 +        finished(20), (255)
4785 +    } HandshakeType;
4786 +
4787 +    struct {
4788 +        HandshakeType msg_type;
4789 +        uint24 length;
4790 +        select (HandshakeType) {
4791 +            case hello_request:       HelloRequest;
4792 +            case client_hello:        ClientHello;
4793 +            case server_hello:        ServerHello;
4794 +            case certificate:         Certificate;
4795 +            case server_key_exchange: ServerKeyExchange;
4796 +            case certificate_request: CertificateRequest;
4797 +            case server_hello_done:   ServerHelloDone;
4798 +            case certificate_verify:  CertificateVerify;
4799 +            case client_key_exchange: ClientKeyExchange;
4800 +            case finished:            Finished;
4801 +        } body;
4802 +    } Handshake;
4803 +
4804 +A.4.1. Hello messages
4805 +
4806 +    struct { } HelloRequest;
4807 +
4808 +    struct {
4809 +        uint32 gmt_unix_time;
4810 +        opaque random_bytes[28];
4811 +    } Random;
4812 +
4813 +    opaque SessionID<0..32>;
4814 +
4815 +    uint8 CipherSuite[2];
4816 +
4817 +    enum { null(0), (255) } CompressionMethod;
4818 +
4819 +    struct {
4820 +        ProtocolVersion client_version;
4821 +        Random random;
4822 +        SessionID session_id;
4823 +        CipherSuite cipher_suites<2..2^16-1>;
4824 +        CompressionMethod compression_methods<1..2^8-1>;
4825 +
4826 +
4827 +
4828 +Dierks & Allen              Standards Track                    [Page 51]
4829 +\f
4830 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4831 +
4832 +
4833 +    } ClientHello;
4834 +
4835 +    struct {
4836 +        ProtocolVersion server_version;
4837 +        Random random;
4838 +        SessionID session_id;
4839 +        CipherSuite cipher_suite;
4840 +        CompressionMethod compression_method;
4841 +    } ServerHello;
4842 +
4843 +A.4.2. Server authentication and key exchange messages
4844 +
4845 +    opaque ASN.1Cert<2^24-1>;
4846 +
4847 +    struct {
4848 +        ASN.1Cert certificate_list<1..2^24-1>;
4849 +    } Certificate;
4850 +
4851 +    enum { rsa, diffie_hellman } KeyExchangeAlgorithm;
4852 +
4853 +    struct {
4854 +        opaque RSA_modulus<1..2^16-1>;
4855 +        opaque RSA_exponent<1..2^16-1>;
4856 +    } ServerRSAParams;
4857 +
4858 +    struct {
4859 +        opaque DH_p<1..2^16-1>;
4860 +        opaque DH_g<1..2^16-1>;
4861 +        opaque DH_Ys<1..2^16-1>;
4862 +    } ServerDHParams;
4863 +
4864 +    struct {
4865 +        select (KeyExchangeAlgorithm) {
4866 +            case diffie_hellman:
4867 +                ServerDHParams params;
4868 +                Signature signed_params;
4869 +            case rsa:
4870 +                ServerRSAParams params;
4871 +                Signature signed_params;
4872 +        };
4873 +    } ServerKeyExchange;
4874 +
4875 +    enum { anonymous, rsa, dsa } SignatureAlgorithm;
4876 +
4877 +    select (SignatureAlgorithm)
4878 +    {   case anonymous: struct { };
4879 +        case rsa:
4880 +            digitally-signed struct {
4881 +
4882 +
4883 +
4884 +Dierks & Allen              Standards Track                    [Page 52]
4885 +\f
4886 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4887 +
4888 +
4889 +                opaque md5_hash[16];
4890 +                opaque sha_hash[20];
4891 +            };
4892 +        case dsa:
4893 +            digitally-signed struct {
4894 +                opaque sha_hash[20];
4895 +            };
4896 +    } Signature;
4897 +
4898 +    enum {
4899 +        rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
4900 +        (255)
4901 +    } ClientCertificateType;
4902 +
4903 +    opaque DistinguishedName<1..2^16-1>;
4904 +
4905 +    struct {
4906 +        ClientCertificateType certificate_types<1..2^8-1>;
4907 +        DistinguishedName certificate_authorities<3..2^16-1>;
4908 +    } CertificateRequest;
4909 +
4910 +    struct { } ServerHelloDone;
4911 +
4912 +A.4.3. Client authentication and key exchange messages
4913 +
4914 +    struct {
4915 +        select (KeyExchangeAlgorithm) {
4916 +            case rsa: EncryptedPreMasterSecret;
4917 +            case diffie_hellman: DiffieHellmanClientPublicValue;
4918 +        } exchange_keys;
4919 +    } ClientKeyExchange;
4920 +
4921 +    struct {
4922 +        ProtocolVersion client_version;
4923 +        opaque random[46];
4924 +
4925 +    } PreMasterSecret;
4926 +
4927 +    struct {
4928 +        public-key-encrypted PreMasterSecret pre_master_secret;
4929 +    } EncryptedPreMasterSecret;
4930 +
4931 +    enum { implicit, explicit } PublicValueEncoding;
4932 +
4933 +    struct {
4934 +        select (PublicValueEncoding) {
4935 +            case implicit: struct {};
4936 +            case explicit: opaque DH_Yc<1..2^16-1>;
4937 +
4938 +
4939 +
4940 +Dierks & Allen              Standards Track                    [Page 53]
4941 +\f
4942 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4943 +
4944 +
4945 +        } dh_public;
4946 +    } ClientDiffieHellmanPublic;
4947 +
4948 +    struct {
4949 +        Signature signature;
4950 +    } CertificateVerify;
4951 +
4952 +A.4.4. Handshake finalization message
4953 +
4954 +    struct {
4955 +        opaque verify_data[12];
4956 +    } Finished;
4957 +
4958 +A.5. The CipherSuite
4959 +
4960 +   The following values define the CipherSuite codes used in the client
4961 +   hello and server hello messages.
4962 +
4963 +   A CipherSuite defines a cipher specification supported in TLS Version
4964 +   1.0.
4965 +
4966 +   TLS_NULL_WITH_NULL_NULL is specified and is the initial state of a
4967 +   TLS connection during the first handshake on that channel, but must
4968 +   not be negotiated, as it provides no more protection than an
4969 +   unsecured connection.
4970 +
4971 +    CipherSuite TLS_NULL_WITH_NULL_NULL                = { 0x00,0x00 };
4972 +
4973 +   The following CipherSuite definitions require that the server provide
4974 +   an RSA certificate that can be used for key exchange. The server may
4975 +   request either an RSA or a DSS signature-capable certificate in the
4976 +   certificate request message.
4977 +
4978 +    CipherSuite TLS_RSA_WITH_NULL_MD5                  = { 0x00,0x01 };
4979 +    CipherSuite TLS_RSA_WITH_NULL_SHA                  = { 0x00,0x02 };
4980 +    CipherSuite TLS_RSA_EXPORT_WITH_RC4_40_MD5         = { 0x00,0x03 };
4981 +    CipherSuite TLS_RSA_WITH_RC4_128_MD5               = { 0x00,0x04 };
4982 +    CipherSuite TLS_RSA_WITH_RC4_128_SHA               = { 0x00,0x05 };
4983 +    CipherSuite TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5     = { 0x00,0x06 };
4984 +    CipherSuite TLS_RSA_WITH_IDEA_CBC_SHA              = { 0x00,0x07 };
4985 +    CipherSuite TLS_RSA_EXPORT_WITH_DES40_CBC_SHA      = { 0x00,0x08 };
4986 +    CipherSuite TLS_RSA_WITH_DES_CBC_SHA               = { 0x00,0x09 };
4987 +    CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_SHA          = { 0x00,0x0A };
4988 +
4989 +   The following CipherSuite definitions are used for server-
4990 +   authenticated (and optionally client-authenticated) Diffie-Hellman.
4991 +   DH denotes cipher suites in which the server's certificate contains
4992 +   the Diffie-Hellman parameters signed by the certificate authority
4993 +
4994 +
4995 +
4996 +Dierks & Allen              Standards Track                    [Page 54]
4997 +\f
4998 +RFC 2246              The TLS Protocol Version 1.0          January 1999
4999 +
5000 +
5001 +   (CA). DHE denotes ephemeral Diffie-Hellman, where the Diffie-Hellman
5002 +   parameters are signed by a DSS or RSA certificate, which has been
5003 +   signed by the CA. The signing algorithm used is specified after the
5004 +   DH or DHE parameter. The server can request an RSA or DSS signature-
5005 +   capable certificate from the client for client authentication or it
5006 +   may request a Diffie-Hellman certificate. Any Diffie-Hellman
5007 +   certificate provided by the client must use the parameters (group and
5008 +   generator) described by the server.
5009 +
5010 +    CipherSuite TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA   = { 0x00,0x0B };
5011 +    CipherSuite TLS_DH_DSS_WITH_DES_CBC_SHA            = { 0x00,0x0C };
5012 +    CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA       = { 0x00,0x0D };
5013 +    CipherSuite TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA   = { 0x00,0x0E };
5014 +    CipherSuite TLS_DH_RSA_WITH_DES_CBC_SHA            = { 0x00,0x0F };
5015 +    CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA       = { 0x00,0x10 };
5016 +    CipherSuite TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA  = { 0x00,0x11 };
5017 +    CipherSuite TLS_DHE_DSS_WITH_DES_CBC_SHA           = { 0x00,0x12 };
5018 +    CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA      = { 0x00,0x13 };
5019 +    CipherSuite TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA  = { 0x00,0x14 };
5020 +    CipherSuite TLS_DHE_RSA_WITH_DES_CBC_SHA           = { 0x00,0x15 };
5021 +    CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA      = { 0x00,0x16 };
5022 +
5023 +   The following cipher suites are used for completely anonymous
5024 +   Diffie-Hellman communications in which neither party is
5025 +   authenticated. Note that this mode is vulnerable to man-in-the-middle
5026 +   attacks and is therefore deprecated.
5027 +
5028 +    CipherSuite TLS_DH_anon_EXPORT_WITH_RC4_40_MD5     = { 0x00,0x17 };
5029 +    CipherSuite TLS_DH_anon_WITH_RC4_128_MD5           = { 0x00,0x18 };
5030 +    CipherSuite TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA  = { 0x00,0x19 };
5031 +    CipherSuite TLS_DH_anon_WITH_DES_CBC_SHA           = { 0x00,0x1A };
5032 +    CipherSuite TLS_DH_anon_WITH_3DES_EDE_CBC_SHA      = { 0x00,0x1B };
5033 +
5034 + Note: All cipher suites whose first byte is 0xFF are considered
5035 +       private and can be used for defining local/experimental
5036 +       algorithms. Interoperability of such types is a local matter.
5037 +
5038 + Note: Additional cipher suites can be registered by publishing an RFC
5039 +       which specifies the cipher suites, including the necessary TLS
5040 +       protocol information, including message encoding, premaster
5041 +       secret derivation, symmetric encryption and MAC calculation and
5042 +       appropriate reference information for the algorithms involved.
5043 +       The RFC editor's office may, at its discretion, choose to publish
5044 +       specifications for cipher suites which are not completely
5045 +       described (e.g., for classified algorithms) if it finds the
5046 +       specification to be of technical interest and completely
5047 +       specified.
5048 +
5049 +
5050 +
5051 +
5052 +Dierks & Allen              Standards Track                    [Page 55]
5053 +\f
5054 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5055 +
5056 +
5057 + Note: The cipher suite values { 0x00, 0x1C } and { 0x00, 0x1D } are
5058 +       reserved to avoid collision with Fortezza-based cipher suites in
5059 +       SSL 3.
5060 +
5061 +A.6. The Security Parameters
5062 +
5063 +   These security parameters are determined by the TLS Handshake
5064 +   Protocol and provided as parameters to the TLS Record Layer in order
5065 +   to initialize a connection state. SecurityParameters includes:
5066 +
5067 +       enum { null(0), (255) } CompressionMethod;
5068 +
5069 +       enum { server, client } ConnectionEnd;
5070 +
5071 +       enum { null, rc4, rc2, des, 3des, des40, idea }
5072 +       BulkCipherAlgorithm;
5073 +
5074 +       enum { stream, block } CipherType;
5075 +
5076 +       enum { true, false } IsExportable;
5077 +
5078 +       enum { null, md5, sha } MACAlgorithm;
5079 +
5080 +   /* The algorithms specified in CompressionMethod,
5081 +   BulkCipherAlgorithm, and MACAlgorithm may be added to. */
5082 +
5083 +       struct {
5084 +           ConnectionEnd entity;
5085 +           BulkCipherAlgorithm bulk_cipher_algorithm;
5086 +           CipherType cipher_type;
5087 +           uint8 key_size;
5088 +           uint8 key_material_length;
5089 +           IsExportable is_exportable;
5090 +           MACAlgorithm mac_algorithm;
5091 +           uint8 hash_size;
5092 +           CompressionMethod compression_algorithm;
5093 +           opaque master_secret[48];
5094 +           opaque client_random[32];
5095 +           opaque server_random[32];
5096 +       } SecurityParameters;
5097 +
5098 +
5099 +
5100 +
5101 +
5102 +
5103 +
5104 +
5105 +
5106 +
5107 +
5108 +Dierks & Allen              Standards Track                    [Page 56]
5109 +\f
5110 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5111 +
5112 +
5113 +B. Glossary
5114 +
5115 +   application protocol
5116 +       An application protocol is a protocol that normally layers
5117 +       directly on top of the transport layer (e.g., TCP/IP). Examples
5118 +       include HTTP, TELNET, FTP, and SMTP.
5119 +
5120 +   asymmetric cipher
5121 +       See public key cryptography.
5122 +
5123 +   authentication
5124 +       Authentication is the ability of one entity to determine the
5125 +       identity of another entity.
5126 +
5127 +   block cipher
5128 +       A block cipher is an algorithm that operates on plaintext in
5129 +       groups of bits, called blocks. 64 bits is a common block size.
5130 +
5131 +   bulk cipher
5132 +       A symmetric encryption algorithm used to encrypt large quantities
5133 +       of data.
5134 +
5135 +   cipher block chaining (CBC)
5136 +       CBC is a mode in which every plaintext block encrypted with a
5137 +       block cipher is first exclusive-ORed with the previous ciphertext
5138 +       block (or, in the case of the first block, with the
5139 +       initialization vector). For decryption, every block is first
5140 +       decrypted, then exclusive-ORed with the previous ciphertext block
5141 +       (or IV).
5142 +
5143 +   certificate
5144 +       As part of the X.509 protocol (a.k.a. ISO Authentication
5145 +       framework), certificates are assigned by a trusted Certificate
5146 +       Authority and provide a strong binding between a party's identity
5147 +       or some other attributes and its public key.
5148 +
5149 +   client
5150 +       The application entity that initiates a TLS connection to a
5151 +       server. This may or may not imply that the client initiated the
5152 +       underlying transport connection. The primary operational
5153 +       difference between the server and client is that the server is
5154 +       generally authenticated, while the client is only optionally
5155 +       authenticated.
5156 +
5157 +   client write key
5158 +       The key used to encrypt data written by the client.
5159 +
5160 +
5161 +
5162 +
5163 +
5164 +Dierks & Allen              Standards Track                    [Page 57]
5165 +\f
5166 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5167 +
5168 +
5169 +   client write MAC secret
5170 +       The secret data used to authenticate data written by the client.
5171 +
5172 +   connection
5173 +       A connection is a transport (in the OSI layering model
5174 +       definition) that provides a suitable type of service. For TLS,
5175 +       such connections are peer to peer relationships. The connections
5176 +       are transient. Every connection is associated with one session.
5177 +
5178 +   Data Encryption Standard
5179 +       DES is a very widely used symmetric encryption algorithm. DES is
5180 +       a block cipher with a 56 bit key and an 8 byte block size. Note
5181 +       that in TLS, for key generation purposes, DES is treated as
5182 +       having an 8 byte key length (64 bits), but it still only provides
5183 +       56 bits of protection. (The low bit of each key byte is presumed
5184 +       to be set to produce odd parity in that key byte.) DES can also
5185 +       be operated in a mode where three independent keys and three
5186 +       encryptions are used for each block of data; this uses 168 bits
5187 +       of key (24 bytes in the TLS key generation method) and provides
5188 +       the equivalent of 112 bits of security. [DES], [3DES]
5189 +
5190 +   Digital Signature Standard (DSS)
5191 +       A standard for digital signing, including the Digital Signing
5192 +       Algorithm, approved by the National Institute of Standards and
5193 +       Technology, defined in NIST FIPS PUB 186, "Digital Signature
5194 +       Standard," published May, 1994 by the U.S. Dept. of Commerce.
5195 +       [DSS]
5196 +
5197 +   digital signatures
5198 +       Digital signatures utilize public key cryptography and one-way
5199 +       hash functions to produce a signature of the data that can be
5200 +       authenticated, and is difficult to forge or repudiate.
5201 +
5202 +   handshake
5203 +       An initial negotiation between client and server that establishes
5204 +       the parameters of their transactions.
5205 +
5206 +   Initialization Vector (IV)
5207 +       When a block cipher is used in CBC mode, the initialization
5208 +       vector is exclusive-ORed with the first plaintext block prior to
5209 +       encryption.
5210 +
5211 +   IDEA
5212 +       A 64-bit block cipher designed by Xuejia Lai and James Massey.
5213 +       [IDEA]
5214 +
5215 +
5216 +
5217 +
5218 +
5219 +
5220 +Dierks & Allen              Standards Track                    [Page 58]
5221 +\f
5222 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5223 +
5224 +
5225 +   Message Authentication Code (MAC)
5226 +       A Message Authentication Code is a one-way hash computed from a
5227 +       message and some secret data. It is difficult to forge without
5228 +       knowing the secret data. Its purpose is to detect if the message
5229 +       has been altered.
5230 +
5231 +   master secret
5232 +       Secure secret data used for generating encryption keys, MAC
5233 +       secrets, and IVs.
5234 +
5235 +   MD5
5236 +       MD5 is a secure hashing function that converts an arbitrarily
5237 +       long data stream into a digest of fixed size (16 bytes). [MD5]
5238 +
5239 +   public key cryptography
5240 +       A class of cryptographic techniques employing two-key ciphers.
5241 +       Messages encrypted with the public key can only be decrypted with
5242 +       the associated private key. Conversely, messages signed with the
5243 +       private key can be verified with the public key.
5244 +
5245 +   one-way hash function
5246 +       A one-way transformation that converts an arbitrary amount of
5247 +       data into a fixed-length hash. It is computationally hard to
5248 +       reverse the transformation or to find collisions. MD5 and SHA are
5249 +       examples of one-way hash functions.
5250 +
5251 +   RC2
5252 +       A block cipher developed by Ron Rivest at RSA Data Security, Inc.
5253 +       [RSADSI] described in [RC2].
5254 +
5255 +   RC4
5256 +       A stream cipher licensed by RSA Data Security [RSADSI]. A
5257 +       compatible cipher is described in [RC4].
5258 +
5259 +   RSA
5260 +       A very widely used public-key algorithm that can be used for
5261 +       either encryption or digital signing. [RSA]
5262 +
5263 +   salt
5264 +       Non-secret random data used to make export encryption keys resist
5265 +       precomputation attacks.
5266 +
5267 +   server
5268 +       The server is the application entity that responds to requests
5269 +       for connections from clients. See also under client.
5270 +
5271 +
5272 +
5273 +
5274 +
5275 +
5276 +Dierks & Allen              Standards Track                    [Page 59]
5277 +\f
5278 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5279 +
5280 +
5281 +   session
5282 +       A TLS session is an association between a client and a server.
5283 +       Sessions are created by the handshake protocol. Sessions define a
5284 +       set of cryptographic security parameters, which can be shared
5285 +       among multiple connections. Sessions are used to avoid the
5286 +       expensive negotiation of new security parameters for each
5287 +       connection.
5288 +
5289 +   session identifier
5290 +       A session identifier is a value generated by a server that
5291 +       identifies a particular session.
5292 +
5293 +   server write key
5294 +       The key used to encrypt data written by the server.
5295 +
5296 +   server write MAC secret
5297 +       The secret data used to authenticate data written by the server.
5298 +
5299 +   SHA
5300 +       The Secure Hash Algorithm is defined in FIPS PUB 180-1. It
5301 +       produces a 20-byte output. Note that all references to SHA
5302 +       actually use the modified SHA-1 algorithm. [SHA]
5303 +
5304 +   SSL
5305 +       Netscape's Secure Socket Layer protocol [SSL3]. TLS is based on
5306 +       SSL Version 3.0
5307 +
5308 +   stream cipher
5309 +       An encryption algorithm that converts a key into a
5310 +       cryptographically-strong keystream, which is then exclusive-ORed
5311 +       with the plaintext.
5312 +
5313 +   symmetric cipher
5314 +       See bulk cipher.
5315 +
5316 +   Transport Layer Security (TLS)
5317 +       This protocol; also, the Transport Layer Security working group
5318 +       of the Internet Engineering Task Force (IETF). See "Comments" at
5319 +       the end of this document.
5320 +
5321 +
5322 +
5323 +
5324 +
5325 +
5326 +
5327 +
5328 +
5329 +
5330 +
5331 +
5332 +Dierks & Allen              Standards Track                    [Page 60]
5333 +\f
5334 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5335 +
5336 +
5337 +C. CipherSuite definitions
5338 +
5339 +CipherSuite                      Is       Key          Cipher      Hash
5340 +                             Exportable Exchange
5341 +
5342 +TLS_NULL_WITH_NULL_NULL               * NULL           NULL        NULL
5343 +TLS_RSA_WITH_NULL_MD5                 * RSA            NULL         MD5
5344 +TLS_RSA_WITH_NULL_SHA                 * RSA            NULL         SHA
5345 +TLS_RSA_EXPORT_WITH_RC4_40_MD5        * RSA_EXPORT     RC4_40       MD5
5346 +TLS_RSA_WITH_RC4_128_MD5                RSA            RC4_128      MD5
5347 +TLS_RSA_WITH_RC4_128_SHA                RSA            RC4_128      SHA
5348 +TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5    * RSA_EXPORT     RC2_CBC_40   MD5
5349 +TLS_RSA_WITH_IDEA_CBC_SHA               RSA            IDEA_CBC     SHA
5350 +TLS_RSA_EXPORT_WITH_DES40_CBC_SHA     * RSA_EXPORT     DES40_CBC    SHA
5351 +TLS_RSA_WITH_DES_CBC_SHA                RSA            DES_CBC      SHA
5352 +TLS_RSA_WITH_3DES_EDE_CBC_SHA           RSA            3DES_EDE_CBC SHA
5353 +TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA  * DH_DSS_EXPORT  DES40_CBC    SHA
5354 +TLS_DH_DSS_WITH_DES_CBC_SHA             DH_DSS         DES_CBC      SHA
5355 +TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA        DH_DSS         3DES_EDE_CBC SHA
5356 +TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA  * DH_RSA_EXPORT  DES40_CBC    SHA
5357 +TLS_DH_RSA_WITH_DES_CBC_SHA             DH_RSA         DES_CBC      SHA
5358 +TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA        DH_RSA         3DES_EDE_CBC SHA
5359 +TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA * DHE_DSS_EXPORT DES40_CBC    SHA
5360 +TLS_DHE_DSS_WITH_DES_CBC_SHA            DHE_DSS        DES_CBC      SHA
5361 +TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA       DHE_DSS        3DES_EDE_CBC SHA
5362 +TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA * DHE_RSA_EXPORT DES40_CBC    SHA
5363 +TLS_DHE_RSA_WITH_DES_CBC_SHA            DHE_RSA        DES_CBC      SHA
5364 +TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA       DHE_RSA        3DES_EDE_CBC SHA
5365 +TLS_DH_anon_EXPORT_WITH_RC4_40_MD5    * DH_anon_EXPORT RC4_40       MD5
5366 +TLS_DH_anon_WITH_RC4_128_MD5            DH_anon        RC4_128      MD5
5367 +TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA   DH_anon        DES40_CBC    SHA
5368 +TLS_DH_anon_WITH_DES_CBC_SHA            DH_anon        DES_CBC      SHA
5369 +TLS_DH_anon_WITH_3DES_EDE_CBC_SHA       DH_anon        3DES_EDE_CBC SHA
5370 +
5371 +
5372 +   * Indicates IsExportable is True
5373 +
5374 +      Key
5375 +      Exchange
5376 +      Algorithm       Description                        Key size limit
5377 +
5378 +      DHE_DSS         Ephemeral DH with DSS signatures   None
5379 +      DHE_DSS_EXPORT  Ephemeral DH with DSS signatures   DH = 512 bits
5380 +      DHE_RSA         Ephemeral DH with RSA signatures   None
5381 +      DHE_RSA_EXPORT  Ephemeral DH with RSA signatures   DH = 512 bits,
5382 +                                                         RSA = none
5383 +      DH_anon         Anonymous DH, no signatures        None
5384 +      DH_anon_EXPORT  Anonymous DH, no signatures        DH = 512 bits
5385 +
5386 +
5387 +
5388 +Dierks & Allen              Standards Track                    [Page 61]
5389 +\f
5390 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5391 +
5392 +
5393 +      DH_DSS          DH with DSS-based certificates     None
5394 +      DH_DSS_EXPORT   DH with DSS-based certificates     DH = 512 bits
5395 +      DH_RSA          DH with RSA-based certificates     None
5396 +      DH_RSA_EXPORT   DH with RSA-based certificates     DH = 512 bits,
5397 +                                                         RSA = none
5398 +      NULL            No key exchange                    N/A
5399 +      RSA             RSA key exchange                   None
5400 +      RSA_EXPORT      RSA key exchange                   RSA = 512 bits
5401 +
5402 +   Key size limit
5403 +       The key size limit gives the size of the largest public key that
5404 +       can be legally used for encryption in cipher suites that are
5405 +       exportable.
5406 +
5407 +                         Key      Expanded   Effective   IV    Block
5408 +    Cipher       Type  Material Key Material  Key Bits  Size   Size
5409 +
5410 +    NULL       * Stream   0          0           0        0     N/A
5411 +    IDEA_CBC     Block   16         16         128        8      8
5412 +    RC2_CBC_40 * Block    5         16          40        8      8
5413 +    RC4_40     * Stream   5         16          40        0     N/A
5414 +    RC4_128      Stream  16         16         128        0     N/A
5415 +    DES40_CBC  * Block    5          8          40        8      8
5416 +    DES_CBC      Block    8          8          56        8      8
5417 +    3DES_EDE_CBC Block   24         24         168        8      8
5418 +
5419 +   * Indicates IsExportable is true.
5420 +
5421 +   Type
5422 +       Indicates whether this is a stream cipher or a block cipher
5423 +       running in CBC mode.
5424 +
5425 +   Key Material
5426 +       The number of bytes from the key_block that are used for
5427 +       generating the write keys.
5428 +
5429 +   Expanded Key Material
5430 +       The number of bytes actually fed into the encryption algorithm
5431 +
5432 +   Effective Key Bits
5433 +       How much entropy material is in the key material being fed into
5434 +       the encryption routines.
5435 +
5436 +   IV Size
5437 +       How much data needs to be generated for the initialization
5438 +       vector. Zero for stream ciphers; equal to the block size for
5439 +       block ciphers.
5440 +
5441 +
5442 +
5443 +
5444 +Dierks & Allen              Standards Track                    [Page 62]
5445 +\f
5446 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5447 +
5448 +
5449 +   Block Size
5450 +       The amount of data a block cipher enciphers in one chunk; a
5451 +       block cipher running in CBC mode can only encrypt an even
5452 +       multiple of its block size.
5453 +
5454 +      Hash      Hash      Padding
5455 +    function    Size       Size
5456 +      NULL       0          0
5457 +      MD5        16         48
5458 +      SHA        20         40
5459 +
5460 +
5461 +
5462 +
5463 +
5464 +
5465 +
5466 +
5467 +
5468 +
5469 +
5470 +
5471 +
5472 +
5473 +
5474 +
5475 +
5476 +
5477 +
5478 +
5479 +
5480 +
5481 +
5482 +
5483 +
5484 +
5485 +
5486 +
5487 +
5488 +
5489 +
5490 +
5491 +
5492 +
5493 +
5494 +
5495 +
5496 +
5497 +
5498 +
5499 +
5500 +Dierks & Allen              Standards Track                    [Page 63]
5501 +\f
5502 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5503 +
5504 +
5505 +D. Implementation Notes
5506 +
5507 +   The TLS protocol cannot prevent many common security mistakes. This
5508 +   section provides several recommendations to assist implementors.
5509 +
5510 +D.1. Temporary RSA keys
5511 +
5512 +   US Export restrictions limit RSA keys used for encryption to 512
5513 +   bits, but do not place any limit on lengths of RSA keys used for
5514 +   signing operations. Certificates often need to be larger than 512
5515 +   bits, since 512-bit RSA keys are not secure enough for high-value
5516 +   transactions or for applications requiring long-term security. Some
5517 +   certificates are also designated signing-only, in which case they
5518 +   cannot be used for key exchange.
5519 +
5520 +   When the public key in the certificate cannot be used for encryption,
5521 +   the server signs a temporary RSA key, which is then exchanged. In
5522 +   exportable applications, the temporary RSA key should be the maximum
5523 +   allowable length (i.e., 512 bits). Because 512-bit RSA keys are
5524 +   relatively insecure, they should be changed often. For typical
5525 +   electronic commerce applications, it is suggested that keys be
5526 +   changed daily or every 500 transactions, and more often if possible.
5527 +   Note that while it is acceptable to use the same temporary key for
5528 +   multiple transactions, it must be signed each time it is used.
5529 +
5530 +   RSA key generation is a time-consuming process. In many cases, a
5531 +   low-priority process can be assigned the task of key generation.
5532 +
5533 +   Whenever a new key is completed, the existing temporary key can be
5534 +   replaced with the new one.
5535 +
5536 +D.2. Random Number Generation and Seeding
5537 +
5538 +   TLS requires a cryptographically-secure pseudorandom number generator
5539 +   (PRNG). Care must be taken in designing and seeding PRNGs.  PRNGs
5540 +   based on secure hash operations, most notably MD5 and/or SHA, are
5541 +   acceptable, but cannot provide more security than the size of the
5542 +   random number generator state. (For example, MD5-based PRNGs usually
5543 +   provide 128 bits of state.)
5544 +
5545 +   To estimate the amount of seed material being produced, add the
5546 +   number of bits of unpredictable information in each seed byte. For
5547 +   example, keystroke timing values taken from a PC compatible's 18.2 Hz
5548 +   timer provide 1 or 2 secure bits each, even though the total size of
5549 +   the counter value is 16 bits or more. To seed a 128-bit PRNG, one
5550 +   would thus require approximately 100 such timer values.
5551 +
5552 +
5553 +
5554 +
5555 +
5556 +Dierks & Allen              Standards Track                    [Page 64]
5557 +\f
5558 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5559 +
5560 +
5561 + Warning: The seeding functions in RSAREF and versions of BSAFE prior to
5562 +          3.0 are order-independent. For example, if 1000 seed bits are
5563 +          supplied, one at a time, in 1000 separate calls to the seed
5564 +          function, the PRNG will end up in a state which depends only
5565 +          on the number of 0 or 1 seed bits in the seed data (i.e.,
5566 +          there are 1001 possible final states). Applications using
5567 +          BSAFE or RSAREF must take extra care to ensure proper seeding.
5568 +          This may be accomplished by accumulating seed bits into a
5569 +          buffer and processing them all at once or by processing an
5570 +          incrementing counter with every seed bit; either method will
5571 +          reintroduce order dependence into the seeding process.
5572 +
5573 +D.3. Certificates and authentication
5574 +
5575 +   Implementations are responsible for verifying the integrity of
5576 +   certificates and should generally support certificate revocation
5577 +   messages. Certificates should always be verified to ensure proper
5578 +   signing by a trusted Certificate Authority (CA). The selection and
5579 +   addition of trusted CAs should be done very carefully. Users should
5580 +   be able to view information about the certificate and root CA.
5581 +
5582 +D.4. CipherSuites
5583 +
5584 +   TLS supports a range of key sizes and security levels, including some
5585 +   which provide no or minimal security. A proper implementation will
5586 +   probably not support many cipher suites. For example, 40-bit
5587 +   encryption is easily broken, so implementations requiring strong
5588 +   security should not allow 40-bit keys. Similarly, anonymous Diffie-
5589 +   Hellman is strongly discouraged because it cannot prevent man-in-
5590 +   the-middle attacks. Applications should also enforce minimum and
5591 +   maximum key sizes. For example, certificate chains containing 512-bit
5592 +   RSA keys or signatures are not appropriate for high-security
5593 +   applications.
5594 +
5595 +
5596 +
5597 +
5598 +
5599 +
5600 +
5601 +
5602 +
5603 +
5604 +
5605 +
5606 +
5607 +
5608 +
5609 +
5610 +
5611 +
5612 +Dierks & Allen              Standards Track                    [Page 65]
5613 +\f
5614 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5615 +
5616 +
5617 +E. Backward Compatibility With SSL
5618 +
5619 +   For historical reasons and in order to avoid a profligate consumption
5620 +   of reserved port numbers, application protocols which are secured by
5621 +   TLS 1.0, SSL 3.0, and SSL 2.0 all frequently share the same
5622 +   connection port: for example, the https protocol (HTTP secured by SSL
5623 +   or TLS) uses port 443 regardless of which security protocol it is
5624 +   using. Thus, some mechanism must be determined to distinguish and
5625 +   negotiate among the various protocols.
5626 +
5627 +   TLS version 1.0 and SSL 3.0 are very similar; thus, supporting both
5628 +   is easy. TLS clients who wish to negotiate with SSL 3.0 servers
5629 +   should send client hello messages using the SSL 3.0 record format and
5630 +   client hello structure, sending {3, 1} for the version field to note
5631 +   that they support TLS 1.0. If the server supports only SSL 3.0, it
5632 +   will respond with an SSL 3.0 server hello; if it supports TLS, with a
5633 +   TLS server hello. The negotiation then proceeds as appropriate for
5634 +   the negotiated protocol.
5635 +
5636 +   Similarly, a TLS server which wishes to interoperate with SSL 3.0
5637 +   clients should accept SSL 3.0 client hello messages and respond with
5638 +   an SSL 3.0 server hello if an SSL 3.0 client hello is received which
5639 +   has a version field of {3, 0}, denoting that this client does not
5640 +   support TLS.
5641 +
5642 +   Whenever a client already knows the highest protocol known to a
5643 +   server (for example, when resuming a session), it should initiate the
5644 +   connection in that native protocol.
5645 +
5646 +   TLS 1.0 clients that support SSL Version 2.0 servers must send SSL
5647 +   Version 2.0 client hello messages [SSL2]. TLS servers should accept
5648 +   either client hello format if they wish to support SSL 2.0 clients on
5649 +   the same connection port. The only deviations from the Version 2.0
5650 +   specification are the ability to specify a version with a value of
5651 +   three and the support for more ciphering types in the CipherSpec.
5652 +
5653 + Warning: The ability to send Version 2.0 client hello messages will be
5654 +          phased out with all due haste. Implementors should make every
5655 +          effort to move forward as quickly as possible. Version 3.0
5656 +          provides better mechanisms for moving to newer versions.
5657 +
5658 +   The following cipher specifications are carryovers from SSL Version
5659 +   2.0. These are assumed to use RSA for key exchange and
5660 +   authentication.
5661 +
5662 +       V2CipherSpec TLS_RC4_128_WITH_MD5          = { 0x01,0x00,0x80 };
5663 +       V2CipherSpec TLS_RC4_128_EXPORT40_WITH_MD5 = { 0x02,0x00,0x80 };
5664 +       V2CipherSpec TLS_RC2_CBC_128_CBC_WITH_MD5  = { 0x03,0x00,0x80 };
5665 +
5666 +
5667 +
5668 +Dierks & Allen              Standards Track                    [Page 66]
5669 +\f
5670 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5671 +
5672 +
5673 +       V2CipherSpec TLS_RC2_CBC_128_CBC_EXPORT40_WITH_MD5
5674 +                                                  = { 0x04,0x00,0x80 };
5675 +       V2CipherSpec TLS_IDEA_128_CBC_WITH_MD5     = { 0x05,0x00,0x80 };
5676 +       V2CipherSpec TLS_DES_64_CBC_WITH_MD5       = { 0x06,0x00,0x40 };
5677 +       V2CipherSpec TLS_DES_192_EDE3_CBC_WITH_MD5 = { 0x07,0x00,0xC0 };
5678 +
5679 +   Cipher specifications native to TLS can be included in Version 2.0
5680 +   client hello messages using the syntax below. Any V2CipherSpec
5681 +   element with its first byte equal to zero will be ignored by Version
5682 +   2.0 servers. Clients sending any of the above V2CipherSpecs should
5683 +   also include the TLS equivalent (see Appendix A.5):
5684 +
5685 +       V2CipherSpec (see TLS name) = { 0x00, CipherSuite };
5686 +
5687 +E.1. Version 2 client hello
5688 +
5689 +   The Version 2.0 client hello message is presented below using this
5690 +   document's presentation model. The true definition is still assumed
5691 +   to be the SSL Version 2.0 specification.
5692 +
5693 +       uint8 V2CipherSpec[3];
5694 +
5695 +       struct {
5696 +           uint8 msg_type;
5697 +           Version version;
5698 +           uint16 cipher_spec_length;
5699 +           uint16 session_id_length;
5700 +           uint16 challenge_length;
5701 +           V2CipherSpec cipher_specs[V2ClientHello.cipher_spec_length];
5702 +           opaque session_id[V2ClientHello.session_id_length];
5703 +           Random challenge;
5704 +       } V2ClientHello;
5705 +
5706 +   msg_type
5707 +       This field, in conjunction with the version field, identifies a
5708 +       version 2 client hello message. The value should be one (1).
5709 +
5710 +   version
5711 +       The highest version of the protocol supported by the client
5712 +       (equals ProtocolVersion.version, see Appendix A.1).
5713 +
5714 +   cipher_spec_length
5715 +       This field is the total length of the field cipher_specs. It
5716 +       cannot be zero and must be a multiple of the V2CipherSpec length
5717 +       (3).
5718 +
5719 +
5720 +
5721 +
5722 +
5723 +
5724 +Dierks & Allen              Standards Track                    [Page 67]
5725 +\f
5726 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5727 +
5728 +
5729 +   session_id_length
5730 +       This field must have a value of either zero or 16. If zero, the
5731 +       client is creating a new session. If 16, the session_id field
5732 +       will contain the 16 bytes of session identification.
5733 +
5734 +   challenge_length
5735 +       The length in bytes of the client's challenge to the server to
5736 +       authenticate itself. This value must be 32.
5737 +
5738 +   cipher_specs
5739 +       This is a list of all CipherSpecs the client is willing and able
5740 +       to use. There must be at least one CipherSpec acceptable to the
5741 +       server.
5742 +
5743 +   session_id
5744 +       If this field's length is not zero, it will contain the
5745 +       identification for a session that the client wishes to resume.
5746 +
5747 +   challenge
5748 +       The client challenge to the server for the server to identify
5749 +       itself is a (nearly) arbitrary length random. The TLS server will
5750 +       right justify the challenge data to become the ClientHello.random
5751 +       data (padded with leading zeroes, if necessary), as specified in
5752 +       this protocol specification. If the length of the challenge is
5753 +       greater than 32 bytes, only the last 32 bytes are used. It is
5754 +       legitimate (but not necessary) for a V3 server to reject a V2
5755 +       ClientHello that has fewer than 16 bytes of challenge data.
5756 +
5757 + Note: Requests to resume a TLS session should use a TLS client hello.
5758 +
5759 +E.2. Avoiding man-in-the-middle version rollback
5760 +
5761 +   When TLS clients fall back to Version 2.0 compatibility mode, they
5762 +   should use special PKCS #1 block formatting. This is done so that TLS
5763 +   servers will reject Version 2.0 sessions with TLS-capable clients.
5764 +
5765 +   When TLS clients are in Version 2.0 compatibility mode, they set the
5766 +   right-hand (least-significant) 8 random bytes of the PKCS padding
5767 +   (not including the terminal null of the padding) for the RSA
5768 +   encryption of the ENCRYPTED-KEY-DATA field of the CLIENT-MASTER-KEY
5769 +   to 0x03 (the other padding bytes are random). After decrypting the
5770 +   ENCRYPTED-KEY-DATA field, servers that support TLS should issue an
5771 +   error if these eight padding bytes are 0x03. Version 2.0 servers
5772 +   receiving blocks padded in this manner will proceed normally.
5773 +
5774 +
5775 +
5776 +
5777 +
5778 +
5779 +
5780 +Dierks & Allen              Standards Track                    [Page 68]
5781 +\f
5782 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5783 +
5784 +
5785 +F. Security analysis
5786 +
5787 +   The TLS protocol is designed to establish a secure connection between
5788 +   a client and a server communicating over an insecure channel. This
5789 +   document makes several traditional assumptions, including that
5790 +   attackers have substantial computational resources and cannot obtain
5791 +   secret information from sources outside the protocol. Attackers are
5792 +   assumed to have the ability to capture, modify, delete, replay, and
5793 +   otherwise tamper with messages sent over the communication channel.
5794 +   This appendix outlines how TLS has been designed to resist a variety
5795 +   of attacks.
5796 +
5797 +F.1. Handshake protocol
5798 +
5799 +   The handshake protocol is responsible for selecting a CipherSpec and
5800 +   generating a Master Secret, which together comprise the primary
5801 +   cryptographic parameters associated with a secure session. The
5802 +   handshake protocol can also optionally authenticate parties who have
5803 +   certificates signed by a trusted certificate authority.
5804 +
5805 +F.1.1. Authentication and key exchange
5806 +
5807 +   TLS supports three authentication modes: authentication of both
5808 +   parties, server authentication with an unauthenticated client, and
5809 +   total anonymity. Whenever the server is authenticated, the channel is
5810 +   secure against man-in-the-middle attacks, but completely anonymous
5811 +   sessions are inherently vulnerable to such attacks.  Anonymous
5812 +   servers cannot authenticate clients. If the server is authenticated,
5813 +   its certificate message must provide a valid certificate chain
5814 +   leading to an acceptable certificate authority.  Similarly,
5815 +   authenticated clients must supply an acceptable certificate to the
5816 +   server. Each party is responsible for verifying that the other's
5817 +   certificate is valid and has not expired or been revoked.
5818 +
5819 +   The general goal of the key exchange process is to create a
5820 +   pre_master_secret known to the communicating parties and not to
5821 +   attackers. The pre_master_secret will be used to generate the
5822 +   master_secret (see Section 8.1). The master_secret is required to
5823 +   generate the certificate verify and finished messages, encryption
5824 +   keys, and MAC secrets (see Sections 7.4.8, 7.4.9 and 6.3). By sending
5825 +   a correct finished message, parties thus prove that they know the
5826 +   correct pre_master_secret.
5827 +
5828 +F.1.1.1. Anonymous key exchange
5829 +
5830 +   Completely anonymous sessions can be established using RSA or
5831 +   Diffie-Hellman for key exchange. With anonymous RSA, the client
5832 +   encrypts a pre_master_secret with the server's uncertified public key
5833 +
5834 +
5835 +
5836 +Dierks & Allen              Standards Track                    [Page 69]
5837 +\f
5838 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5839 +
5840 +
5841 +   extracted from the server key exchange message. The result is sent in
5842 +   a client key exchange message. Since eavesdroppers do not know the
5843 +   server's private key, it will be infeasible for them to decode the
5844 +   pre_master_secret. (Note that no anonymous RSA Cipher Suites are
5845 +   defined in this document).
5846 +
5847 +   With Diffie-Hellman, the server's public parameters are contained in
5848 +   the server key exchange message and the client's are sent in the
5849 +   client key exchange message. Eavesdroppers who do not know the
5850 +   private values should not be able to find the Diffie-Hellman result
5851 +   (i.e. the pre_master_secret).
5852 +
5853 + Warning: Completely anonymous connections only provide protection
5854 +          against passive eavesdropping. Unless an independent tamper-
5855 +          proof channel is used to verify that the finished messages
5856 +          were not replaced by an attacker, server authentication is
5857 +          required in environments where active man-in-the-middle
5858 +          attacks are a concern.
5859 +
5860 +F.1.1.2. RSA key exchange and authentication
5861 +
5862 +   With RSA, key exchange and server authentication are combined. The
5863 +   public key may be either contained in the server's certificate or may
5864 +   be a temporary RSA key sent in a server key exchange message.  When
5865 +   temporary RSA keys are used, they are signed by the server's RSA or
5866 +   DSS certificate. The signature includes the current
5867 +   ClientHello.random, so old signatures and temporary keys cannot be
5868 +   replayed. Servers may use a single temporary RSA key for multiple
5869 +   negotiation sessions.
5870 +
5871 + Note: The temporary RSA key option is useful if servers need large
5872 +       certificates but must comply with government-imposed size limits
5873 +       on keys used for key exchange.
5874 +
5875 +   After verifying the server's certificate, the client encrypts a
5876 +   pre_master_secret with the server's public key. By successfully
5877 +   decoding the pre_master_secret and producing a correct finished
5878 +   message, the server demonstrates that it knows the private key
5879 +   corresponding to the server certificate.
5880 +
5881 +   When RSA is used for key exchange, clients are authenticated using
5882 +   the certificate verify message (see Section 7.4.8). The client signs
5883 +   a value derived from the master_secret and all preceding handshake
5884 +   messages. These handshake messages include the server certificate,
5885 +   which binds the signature to the server, and ServerHello.random,
5886 +   which binds the signature to the current handshake process.
5887 +
5888 +
5889 +
5890 +
5891 +
5892 +Dierks & Allen              Standards Track                    [Page 70]
5893 +\f
5894 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5895 +
5896 +
5897 +F.1.1.3. Diffie-Hellman key exchange with authentication
5898 +
5899 +   When Diffie-Hellman key exchange is used, the server can either
5900 +   supply a certificate containing fixed Diffie-Hellman parameters or
5901 +   can use the server key exchange message to send a set of temporary
5902 +   Diffie-Hellman parameters signed with a DSS or RSA certificate.
5903 +   Temporary parameters are hashed with the hello.random values before
5904 +   signing to ensure that attackers do not replay old parameters. In
5905 +   either case, the client can verify the certificate or signature to
5906 +   ensure that the parameters belong to the server.
5907 +
5908 +   If the client has a certificate containing fixed Diffie-Hellman
5909 +   parameters, its certificate contains the information required to
5910 +   complete the key exchange. Note that in this case the client and
5911 +   server will generate the same Diffie-Hellman result (i.e.,
5912 +   pre_master_secret) every time they communicate. To prevent the
5913 +   pre_master_secret from staying in memory any longer than necessary,
5914 +   it should be converted into the master_secret as soon as possible.
5915 +   Client Diffie-Hellman parameters must be compatible with those
5916 +   supplied by the server for the key exchange to work.
5917 +
5918 +   If the client has a standard DSS or RSA certificate or is
5919 +   unauthenticated, it sends a set of temporary parameters to the server
5920 +   in the client key exchange message, then optionally uses a
5921 +   certificate verify message to authenticate itself.
5922 +
5923 +F.1.2. Version rollback attacks
5924 +
5925 +   Because TLS includes substantial improvements over SSL Version 2.0,
5926 +   attackers may try to make TLS-capable clients and servers fall back
5927 +   to Version 2.0. This attack can occur if (and only if) two TLS-
5928 +   capable parties use an SSL 2.0 handshake.
5929 +
5930 +   Although the solution using non-random PKCS #1 block type 2 message
5931 +   padding is inelegant, it provides a reasonably secure way for Version
5932 +   3.0 servers to detect the attack. This solution is not secure against
5933 +   attackers who can brute force the key and substitute a new
5934 +   ENCRYPTED-KEY-DATA message containing the same key (but with normal
5935 +   padding) before the application specified wait threshold has expired.
5936 +   Parties concerned about attacks of this scale should not be using
5937 +   40-bit encryption keys anyway. Altering the padding of the least-
5938 +   significant 8 bytes of the PKCS padding does not impact security for
5939 +   the size of the signed hashes and RSA key lengths used in the
5940 +   protocol, since this is essentially equivalent to increasing the
5941 +   input block size by 8 bytes.
5942 +
5943 +
5944 +
5945 +
5946 +
5947 +
5948 +Dierks & Allen              Standards Track                    [Page 71]
5949 +\f
5950 +RFC 2246              The TLS Protocol Version 1.0          January 1999
5951 +
5952 +
5953 +F.1.3. Detecting attacks against the handshake protocol
5954 +
5955 +   An attacker might try to influence the handshake exchange to make the
5956 +   parties select different encryption algorithms than they would
5957 +   normally choose. Because many implementations will support 40-bit
5958 +   exportable encryption and some may even support null encryption or
5959 +   MAC algorithms, this attack is of particular concern.
5960 +
5961 +   For this attack, an attacker must actively change one or more
5962 +   handshake messages. If this occurs, the client and server will
5963 +   compute different values for the handshake message hashes. As a
5964 +   result, the parties will not accept each others' finished messages.
5965 +   Without the master_secret, the attacker cannot repair the finished
5966 +   messages, so the attack will be discovered.
5967 +
5968 +F.1.4. Resuming sessions
5969 +
5970 +   When a connection is established by resuming a session, new
5971 +   ClientHello.random and ServerHello.random values are hashed with the
5972 +   session's master_secret. Provided that the master_secret has not been
5973 +   compromised and that the secure hash operations used to produce the
5974 +   encryption keys and MAC secrets are secure, the connection should be
5975 +   secure and effectively independent from previous connections.
5976 +   Attackers cannot use known encryption keys or MAC secrets to
5977 +   compromise the master_secret without breaking the secure hash
5978 +   operations (which use both SHA and MD5).
5979 +
5980 +   Sessions cannot be resumed unless both the client and server agree.
5981 +   If either party suspects that the session may have been compromised,
5982 +   or that certificates may have expired or been revoked, it should
5983 +   force a full handshake. An upper limit of 24 hours is suggested for
5984 +   session ID lifetimes, since an attacker who obtains a master_secret
5985 +   may be able to impersonate the compromised party until the
5986 +   corresponding session ID is retired. Applications that may be run in
5987 +   relatively insecure environments should not write session IDs to
5988 +   stable storage.
5989 +
5990 +F.1.5. MD5 and SHA
5991 +
5992 +   TLS uses hash functions very conservatively. Where possible, both MD5
5993 +   and SHA are used in tandem to ensure that non-catastrophic flaws in
5994 +   one algorithm will not break the overall protocol.
5995 +
5996 +F.2. Protecting application data
5997 +
5998 +   The master_secret is hashed with the ClientHello.random and
5999 +   ServerHello.random to produce unique data encryption keys and MAC
6000 +   secrets for each connection.
6001 +
6002 +
6003 +
6004 +Dierks & Allen              Standards Track                    [Page 72]
6005 +\f
6006 +RFC 2246              The TLS Protocol Version 1.0          January 1999
6007 +
6008 +
6009 +   Outgoing data is protected with a MAC before transmission. To prevent
6010 +   message replay or modification attacks, the MAC is computed from the
6011 +   MAC secret, the sequence number, the message length, the message
6012 +   contents, and two fixed character strings. The message type field is
6013 +   necessary to ensure that messages intended for one TLS Record Layer
6014 +   client are not redirected to another. The sequence number ensures
6015 +   that attempts to delete or reorder messages will be detected. Since
6016 +   sequence numbers are 64-bits long, they should never overflow.
6017 +   Messages from one party cannot be inserted into the other's output,
6018 +   since they use independent MAC secrets. Similarly, the server-write
6019 +   and client-write keys are independent so stream cipher keys are used
6020 +   only once.
6021 +
6022 +   If an attacker does break an encryption key, all messages encrypted
6023 +   with it can be read. Similarly, compromise of a MAC key can make
6024 +   message modification attacks possible. Because MACs are also
6025 +   encrypted, message-alteration attacks generally require breaking the
6026 +   encryption algorithm as well as the MAC.
6027 +
6028 + Note: MAC secrets may be larger than encryption keys, so messages can
6029 +       remain tamper resistant even if encryption keys are broken.
6030 +
6031 +F.3. Final notes
6032 +
6033 +   For TLS to be able to provide a secure connection, both the client
6034 +   and server systems, keys, and applications must be secure. In
6035 +   addition, the implementation must be free of security errors.
6036 +
6037 +   The system is only as strong as the weakest key exchange and
6038 +   authentication algorithm supported, and only trustworthy
6039 +   cryptographic functions should be used. Short public keys, 40-bit
6040 +   bulk encryption keys, and anonymous servers should be used with great
6041 +   caution. Implementations and users must be careful when deciding
6042 +   which certificates and certificate authorities are acceptable; a
6043 +   dishonest certificate authority can do tremendous damage.
6044 +
6045 +
6046 +
6047 +
6048 +
6049 +
6050 +
6051 +
6052 +
6053 +
6054 +
6055 +
6056 +
6057 +
6058 +
6059 +
6060 +Dierks & Allen              Standards Track                    [Page 73]
6061 +\f
6062 +RFC 2246              The TLS Protocol Version 1.0          January 1999
6063 +
6064 +
6065 +G. Patent Statement
6066 +
6067 +   Some of the cryptographic algorithms proposed for use in this
6068 +   protocol have patent claims on them. In addition Netscape
6069 +   Communications Corporation has a patent claim on the Secure Sockets
6070 +   Layer (SSL) work that this standard is based on. The Internet
6071 +   Standards Process as defined in RFC 2026 requests that a statement be
6072 +   obtained from a Patent holder indicating that a license will be made
6073 +   available to applicants under reasonable terms and conditions.
6074 +
6075 +   The Massachusetts Institute of Technology has granted RSA Data
6076 +   Security, Inc., exclusive sub-licensing rights to the following
6077 +   patent issued in the United States:
6078 +
6079 +       Cryptographic Communications System and Method ("RSA"), No.
6080 +       4,405,829
6081 +
6082 +   Netscape Communications Corporation has been issued the following
6083 +   patent in the United States:
6084 +
6085 +       Secure Socket Layer Application Program Apparatus And Method
6086 +       ("SSL"), No. 5,657,390
6087 +
6088 +   Netscape Communications has issued the following statement:
6089 +
6090 +       Intellectual Property Rights
6091 +
6092 +       Secure Sockets Layer
6093 +
6094 +       The United States Patent and Trademark Office ("the PTO")
6095 +       recently issued U.S. Patent No. 5,657,390 ("the SSL Patent")  to
6096 +       Netscape for inventions described as Secure Sockets Layers
6097 +       ("SSL"). The IETF is currently considering adopting SSL as a
6098 +       transport protocol with security features.  Netscape encourages
6099 +       the royalty-free adoption and use of the SSL protocol upon the
6100 +       following terms and conditions:
6101 +
6102 +         * If you already have a valid SSL Ref license today which
6103 +           includes source code from Netscape, an additional patent
6104 +           license under the SSL patent is not required.
6105 +
6106 +         * If you don't have an SSL Ref license, you may have a royalty
6107 +           free license to build implementations covered by the SSL
6108 +           Patent Claims or the IETF TLS specification provided that you
6109 +           do not to assert any patent rights against Netscape or other
6110 +           companies for the implementation of SSL or the IETF TLS
6111 +           recommendation.
6112 +
6113 +
6114 +
6115 +
6116 +Dierks & Allen              Standards Track                    [Page 74]
6117 +\f
6118 +RFC 2246              The TLS Protocol Version 1.0          January 1999
6119 +
6120 +
6121 +       What are "Patent Claims":
6122 +
6123 +       Patent claims are claims in an issued foreign or domestic patent
6124 +       that:
6125 +
6126 +        1) must be infringed in order to implement methods or build
6127 +           products according to the IETF TLS specification;  or
6128 +
6129 +        2) patent claims which require the elements of the SSL patent
6130 +           claims and/or their equivalents to be infringed.
6131 +
6132 +   The Internet Society, Internet Architecture Board, Internet
6133 +   Engineering Steering Group and the Corporation for National Research
6134 +   Initiatives take no position on the validity or scope of the patents
6135 +   and patent applications, nor on the appropriateness of the terms of
6136 +   the assurance. The Internet Society and other groups mentioned above
6137 +   have not made any determination as to any other intellectual property
6138 +   rights which may apply to the practice of this standard.  Any further
6139 +   consideration of these matters is the user's own responsibility.
6140 +
6141 +Security Considerations
6142 +
6143 +   Security issues are discussed throughout this memo.
6144 +
6145 +References
6146 +
6147 +   [3DES]   W. Tuchman, "Hellman Presents No Shortcut Solutions To DES,"
6148 +            IEEE Spectrum, v. 16, n. 7, July 1979, pp40-41.
6149 +
6150 +   [BLEI]   Bleichenbacher D., "Chosen Ciphertext Attacks against
6151 +            Protocols Based on RSA Encryption Standard PKCS #1" in
6152 +            Advances in Cryptology -- CRYPTO'98, LNCS vol. 1462, pages:
6153 +            1--12, 1998.
6154 +
6155 +   [DES]    ANSI X3.106, "American National Standard for Information
6156 +            Systems-Data Link Encryption," American National Standards
6157 +            Institute, 1983.
6158 +
6159 +   [DH1]    W. Diffie and M. E. Hellman, "New Directions in
6160 +            Cryptography," IEEE Transactions on Information Theory, V.
6161 +            IT-22, n. 6, Jun 1977, pp. 74-84.
6162 +
6163 +   [DSS]    NIST FIPS PUB 186, "Digital Signature Standard," National
6164 +            Institute of Standards and Technology, U.S. Department of
6165 +            Commerce, May 18, 1994.
6166 +
6167 +   [FTP]    Postel J., and J. Reynolds, "File Transfer Protocol", STD 9,
6168 +            RFC 959, October 1985.
6169 +
6170 +
6171 +
6172 +Dierks & Allen              Standards Track                    [Page 75]
6173 +\f
6174 +RFC 2246              The TLS Protocol Version 1.0          January 1999
6175 +
6176 +
6177 +   [HTTP]   Berners-Lee, T., Fielding, R., and H. Frystyk, "Hypertext
6178 +            Transfer Protocol -- HTTP/1.0", RFC 1945, May 1996.
6179 +
6180 +   [HMAC]   Krawczyk, H., Bellare, M., and R. Canetti, "HMAC:  Keyed-
6181 +            Hashing for Message Authentication," RFC 2104, February
6182 +            1997.
6183 +
6184 +   [IDEA]   X. Lai, "On the Design and Security of Block Ciphers," ETH
6185 +            Series in Information Processing, v. 1, Konstanz: Hartung-
6186 +            Gorre Verlag, 1992.
6187 +
6188 +   [MD2]    Kaliski, B., "The MD2 Message Digest Algorithm", RFC 1319,
6189 +            April 1992.
6190 +
6191 +   [MD5]    Rivest, R., "The MD5 Message Digest Algorithm", RFC 1321,
6192 +            April 1992.
6193 +
6194 +   [PKCS1]  RSA Laboratories, "PKCS #1: RSA Encryption Standard,"
6195 +            version 1.5, November 1993.
6196 +
6197 +   [PKCS6]  RSA Laboratories, "PKCS #6: RSA Extended Certificate Syntax
6198 +            Standard," version 1.5, November 1993.
6199 +
6200 +   [PKCS7]  RSA Laboratories, "PKCS #7: RSA Cryptographic Message Syntax
6201 +            Standard," version 1.5, November 1993.
6202 +
6203 +   [PKIX]   Housley, R., Ford, W., Polk, W. and D. Solo, "Internet
6204 +            Public Key Infrastructure: Part I: X.509 Certificate and CRL
6205 +            Profile", RFC 2459, January 1999.
6206 +
6207 +   [RC2]    Rivest, R., "A Description of the RC2(r) Encryption
6208 +            Algorithm", RFC 2268, January 1998.
6209 +
6210 +   [RC4]    Thayer, R. and K. Kaukonen, A Stream Cipher Encryption
6211 +            Algorithm, Work in Progress.
6212 +
6213 +   [RSA]    R. Rivest, A. Shamir, and L. M. Adleman, "A Method for
6214 +            Obtaining Digital Signatures and Public-Key Cryptosystems,"
6215 +            Communications of the ACM, v. 21, n. 2, Feb 1978, pp. 120-
6216 +            126.
6217 +
6218 +   [RSADSI] Contact RSA Data Security, Inc., Tel: 415-595-8782
6219 +
6220 +   [SCH]    B. Schneier. Applied Cryptography: Protocols, Algorithms,
6221 +            and Source Code in C, Published by John Wiley & Sons, Inc.
6222 +            1994.
6223 +
6224 +
6225 +
6226 +
6227 +
6228 +Dierks & Allen              Standards Track                    [Page 76]
6229 +\f
6230 +RFC 2246              The TLS Protocol Version 1.0          January 1999
6231 +
6232 +
6233 +   [SHA]    NIST FIPS PUB 180-1, "Secure Hash Standard," National
6234 +            Institute of Standards and Technology, U.S. Department of
6235 +            Commerce, Work in Progress, May 31, 1994.
6236 +
6237 +   [SSL2]   Hickman, Kipp, "The SSL Protocol", Netscape Communications
6238 +            Corp., Feb 9, 1995.
6239 +
6240 +   [SSL3]   A. Frier, P. Karlton, and P. Kocher, "The SSL 3.0 Protocol",
6241 +            Netscape Communications Corp., Nov 18, 1996.
6242 +
6243 +   [TCP]    Postel, J., "Transmission Control Protocol," STD 7, RFC 793,
6244 +            September 1981.
6245 +
6246 +   [TEL]    Postel J., and J. Reynolds, "Telnet Protocol
6247 +            Specifications", STD 8, RFC 854, May 1993.
6248 +
6249 +   [TEL]    Postel J., and J. Reynolds, "Telnet Option Specifications",
6250 +            STD 8, RFC 855, May 1993.
6251 +
6252 +   [X509]   CCITT. Recommendation X.509: "The Directory - Authentication
6253 +            Framework". 1988.
6254 +
6255 +   [XDR]    R. Srinivansan, Sun Microsystems, RFC-1832: XDR: External
6256 +            Data Representation Standard, August 1995.
6257 +
6258 +Credits
6259 +
6260 +   Win Treese
6261 +   Open Market
6262 +
6263 +   EMail: treese@openmarket.com
6264 +
6265 +
6266 +   Editors
6267 +
6268 +   Christopher Allen                  Tim Dierks
6269 +   Certicom                           Certicom
6270 +
6271 +   EMail: callen@certicom.com         EMail: tdierks@certicom.com
6272 +
6273 +
6274 +   Authors' Addresses
6275 +
6276 +   Tim Dierks                         Philip L. Karlton
6277 +   Certicom                           Netscape Communications
6278 +
6279 +   EMail: tdierks@certicom.com
6280 +
6281 +
6282 +
6283 +
6284 +Dierks & Allen              Standards Track                    [Page 77]
6285 +\f
6286 +RFC 2246              The TLS Protocol Version 1.0          January 1999
6287 +
6288 +
6289 +   Alan O. Freier                     Paul C. Kocher
6290 +   Netscape Communications            Independent Consultant
6291 +
6292 +   EMail: freier@netscape.com         EMail: pck@netcom.com
6293 +
6294 +
6295 +   Other contributors
6296 +
6297 +   Martin Abadi                       Robert Relyea
6298 +   Digital Equipment Corporation      Netscape Communications
6299 +
6300 +   EMail: ma@pa.dec.com               EMail: relyea@netscape.com
6301 +
6302 +   Ran Canetti                        Jim Roskind
6303 +   IBM Watson Research Center         Netscape Communications
6304 +
6305 +   EMail: canetti@watson.ibm.com      EMail: jar@netscape.com
6306 +
6307 +
6308 +   Taher Elgamal                      Micheal J. Sabin, Ph. D.
6309 +   Securify                           Consulting Engineer
6310 +
6311 +   EMail: elgamal@securify.com        EMail: msabin@netcom.com
6312 +
6313 +
6314 +   Anil R. Gangolli                   Dan Simon
6315 +   Structured Arts Computing Corp.    Microsoft
6316 +
6317 +   EMail: gangolli@structuredarts.com EMail:  dansimon@microsoft.com
6318 +
6319 +
6320 +   Kipp E.B. Hickman                  Tom Weinstein
6321 +   Netscape Communications            Netscape Communications
6322 +
6323 +   EMail: kipp@netscape.com           EMail: tomw@netscape.com
6324 +
6325 +
6326 +   Hugo Krawczyk
6327 +   IBM Watson Research Center
6328 +
6329 +   EMail: hugo@watson.ibm.com
6330 +
6331 +Comments
6332 +
6333 +   The discussion list for the IETF TLS working group is located at the
6334 +   e-mail address <ietf-tls@lists.consensus.com>. Information on the
6335 +   group and information on how to subscribe to the list is at
6336 +   <http://lists.consensus.com/>.
6337 +
6338 +
6339 +
6340 +Dierks & Allen              Standards Track                    [Page 78]
6341 +\f
6342 +RFC 2246              The TLS Protocol Version 1.0          January 1999
6343 +
6344 +
6345 +   Archives of the list can be found at:
6346 +       <http://www.imc.org/ietf-tls/mail-archive/>
6347 +
6348 +
6349 +
6350 +
6351 +
6352 +
6353 +
6354 +
6355 +
6356 +
6357 +
6358 +
6359 +
6360 +
6361 +
6362 +
6363 +
6364 +
6365 +
6366 +
6367 +
6368 +
6369 +
6370 +
6371 +
6372 +
6373 +
6374 +
6375 +
6376 +
6377 +
6378 +
6379 +
6380 +
6381 +
6382 +
6383 +
6384 +
6385 +
6386 +
6387 +
6388 +
6389 +
6390 +
6391 +
6392 +
6393 +
6394 +
6395 +
6396 +Dierks & Allen              Standards Track                    [Page 79]
6397 +\f
6398 +RFC 2246              The TLS Protocol Version 1.0          January 1999
6399 +
6400 +
6401 +Full Copyright Statement
6402 +
6403 +   Copyright (C) The Internet Society (1999).  All Rights Reserved.
6404 +
6405 +   This document and translations of it may be copied and furnished to
6406 +   others, and derivative works that comment on or otherwise explain it
6407 +   or assist in its implementation may be prepared, copied, published
6408 +   and distributed, in whole or in part, without restriction of any
6409 +   kind, provided that the above copyright notice and this paragraph are
6410 +   included on all such copies and derivative works.  However, this
6411 +   document itself may not be modified in any way, such as by removing
6412 +   the copyright notice or references to the Internet Society or other
6413 +   Internet organizations, except as needed for the purpose of
6414 +   developing Internet standards in which case the procedures for
6415 +   copyrights defined in the Internet Standards process must be
6416 +   followed, or as required to translate it into languages other than
6417 +   English.
6418 +
6419 +   The limited permissions granted above are perpetual and will not be
6420 +   revoked by the Internet Society or its successors or assigns.
6421 +
6422 +   This document and the information contained herein is provided on an
6423 +   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
6424 +   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
6425 +   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
6426 +   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
6427 +   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
6428 +
6429 +
6430 +
6431 +
6432 +
6433 +
6434 +
6435 +
6436 +
6437 +
6438 +
6439 +
6440 +
6441 +
6442 +
6443 +
6444 +
6445 +
6446 +
6447 +
6448 +
6449 +
6450 +
6451 +
6452 +Dierks & Allen              Standards Track                    [Page 80]
6453 +\f
6454 diff -Nur snapshot-20010228-orig/html/ssl/rfc2487.txt snapshot-20010228/html/ssl/rfc2487.txt
6455 --- snapshot-20010228-orig/html/ssl/rfc2487.txt Thu Jan  1 01:00:00 1970
6456 +++ snapshot-20010228/html/ssl/rfc2487.txt      Wed Mar 21 13:38:29 2001
6457 @@ -0,0 +1,451 @@
6458 +
6459 +
6460 +
6461 +
6462 +
6463 +
6464 +Network Working Group                                     P. Hoffman
6465 +Request for Comments: 2487                  Internet Mail Consortium
6466 +Category: Standards Track                               January 1999
6467 +
6468 +
6469 +            SMTP Service Extension for Secure SMTP over TLS
6470 +
6471 +Status of this Memo
6472 +
6473 +   This document specifies an Internet standards track protocol for the
6474 +   Internet community, and requests discussion and suggestions for
6475 +   improvements.  Please refer to the current edition of the "Internet
6476 +   Official Protocol Standards" (STD 1) for the standardization state
6477 +   and status of this protocol.  Distribution of this memo is unlimited.
6478 +
6479 +Copyright Notice
6480 +
6481 +   Copyright (C) The Internet Society (1999).  All Rights Reserved.
6482 +
6483 +1. Abstract
6484 +
6485 +   This document describes an extension to the SMTP service that allows
6486 +   an SMTP server and client to use transport-layer security to provide
6487 +   private, authenticated communication over the Internet. This gives
6488 +   SMTP agents the ability to protect some or all of their
6489 +   communications from eavesdroppers and attackers.
6490 +
6491 +2. Introduction
6492 +
6493 +   SMTP [RFC-821] servers and clients normally communicate in the clear
6494 +   over the Internet. In many cases, this communication goes through one
6495 +   or more router that is not controlled or trusted by either entity.
6496 +   Such an untrusted router might allow a third party to monitor or
6497 +   alter the communications between the server and client.
6498 +
6499 +   Further, there is often a desire for two SMTP agents to be able to
6500 +   authenticate each others' identities. For example, a secure SMTP
6501 +   server might only allow communications from other SMTP agents it
6502 +   knows, or it might act differently for messages received from an
6503 +   agent it knows than from one it doesn't know.
6504 +
6505 +   TLS [TLS], more commonly known as SSL, is a popular mechanism for
6506 +   enhancing TCP communications with privacy and authentication. TLS is
6507 +   in wide use with the HTTP protocol, and is also being used for adding
6508 +   security to many other common protocols that run over TCP.
6509 +
6510 +
6511 +
6512 +
6513 +
6514 +
6515 +Hoffman                     Standards Track                     [Page 1]
6516 +\f
6517 +RFC 2487                 SMTP Service Extension             January 1999
6518 +
6519 +
6520 +2.1 Terminology
6521 +
6522 +   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
6523 +   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
6524 +   document are to be interpreted as described in [RFC-2119].
6525 +
6526 +3. STARTTLS Extension
6527 +
6528 +   The STARTTLS extension to SMTP is laid out as follows:
6529 +
6530 +   (1) the name of the SMTP service defined here is STARTTLS;
6531 +
6532 +   (2) the EHLO keyword value associated with the extension is STARTTLS;
6533 +
6534 +   (3) the STARTTLS keyword has no parameters;
6535 +
6536 +   (4) a new SMTP verb, "STARTTLS", is defined;
6537 +
6538 +   (5) no additional parameters are added to any SMTP command.
6539 +
6540 +4. The STARTTLS Keyword
6541 +
6542 +   The STARTTLS keyword is used to tell the SMTP client that the SMTP
6543 +   server allows use of TLS. It takes no parameters.
6544 +
6545 +5. The STARTTLS Command
6546 +
6547 +   The format for the STARTTLS command is:
6548 +
6549 +   STARTTLS
6550 +
6551 +   with no parameters.
6552 +
6553 +   After the client gives the STARTTLS command, the server responds with
6554 +   one of the following reply codes:
6555 +
6556 +   220 Ready to start TLS
6557 +   501 Syntax error (no parameters allowed)
6558 +   454 TLS not available due to temporary reason
6559 +
6560 +   A publicly-referenced SMTP server MUST NOT require use of the
6561 +   STARTTLS extension in order to deliver mail locally. This rule
6562 +   prevents the STARTTLS extension from damaging the interoperability of
6563 +   the Internet's SMTP infrastructure. A publicly-referenced SMTP server
6564 +   is an SMTP server which runs on port 25 of an Internet host listed in
6565 +   the MX record (or A record if an MX record is not present) for the
6566 +   domain name on the right hand side of an Internet mail address.
6567 +
6568 +
6569 +
6570 +
6571 +Hoffman                     Standards Track                     [Page 2]
6572 +\f
6573 +RFC 2487                 SMTP Service Extension             January 1999
6574 +
6575 +
6576 +   Any SMTP server may refuse to accept messages for relay based on
6577 +   authentication supplied during the TLS negotiation. An SMTP server
6578 +   that is not publicly referenced may refuse to accept any messages for
6579 +   relay or local delivery based on authentication supplied during the
6580 +   TLS negotiation.
6581 +
6582 +   A SMTP server that is not publicly referenced may choose to require
6583 +   that the client perform a TLS negotiation before accepting any
6584 +   commands. In this case, the server SHOULD return the reply code:
6585 +
6586 +   530 Must issue a STARTTLS command first
6587 +
6588 +   to every command other than NOOP, EHLO, STARTTLS, or QUIT. If the
6589 +   client and server are using the ENHANCEDSTATUSCODES ESMTP extension
6590 +   [RFC-2034], the status code to be returned SHOULD be 5.7.0.
6591 +
6592 +   After receiving a 220 response to a STARTTLS command, the client
6593 +   SHOULD start the TLS negotiation before giving any other SMTP
6594 +   commands.
6595 +
6596 +   If the SMTP client is using pipelining as defined in RFC 1854, the
6597 +   STARTTLS command must be the last command in a group.
6598 +
6599 +5.1 Processing After the STARTTLS Command
6600 +
6601 +   After the TLS handshake has been completed, both parties MUST
6602 +   immediately decide whether or not to continue based on the
6603 +   authentication and privacy achieved. The SMTP client and server may
6604 +   decide to move ahead even if the TLS negotiation ended with no
6605 +   authentication and/or no privacy because most SMTP services are
6606 +   performed with no authentication and no privacy, but some SMTP
6607 +   clients or servers may want to continue only if a particular level of
6608 +   authentication and/or privacy was achieved.
6609 +
6610 +   If the SMTP client decides that the level of authentication or
6611 +   privacy is not high enough for it to continue, it SHOULD issue an
6612 +   SMTP QUIT command immediately after the TLS negotiation is complete.
6613 +   If the SMTP server decides that the level of authentication or
6614 +   privacy is not high enough for it to continue, it SHOULD reply to
6615 +   every SMTP command from the client (other than a QUIT command) with
6616 +   the 554 reply code (with a possible text string such as "Command
6617 +   refused due to lack of security").
6618 +
6619 +   The decision of whether or not to believe the authenticity of the
6620 +   other party in a TLS negotiation is a local matter. However, some
6621 +   general rules for the decisions are:
6622 +
6623 +
6624 +
6625 +
6626 +
6627 +Hoffman                     Standards Track                     [Page 3]
6628 +\f
6629 +RFC 2487                 SMTP Service Extension             January 1999
6630 +
6631 +
6632 +    - A SMTP client would probably only want to authenticate an SMTP
6633 +      server whose server certificate has a domain name that is the
6634 +      domain name that the client thought it was connecting to.
6635 +    - A publicly-referenced  SMTP server would probably want to accept
6636 +      any certificate from an SMTP client, and would possibly want to
6637 +      put distinguishing information about the certificate in the
6638 +      Received header of messages that were relayed or submitted from
6639 +      the client.
6640 +
6641 +5.2 Result of the STARTTLS Command
6642 +
6643 +   Upon completion of the TLS handshake, the SMTP protocol is reset to
6644 +   the initial state (the state in SMTP after a server issues a 220
6645 +   service ready greeting). The server MUST discard any knowledge
6646 +   obtained from the client, such as the argument to the EHLO command,
6647 +   which was not obtained from the TLS negotiation itself. The client
6648 +   MUST discard any knowledge obtained from the server, such as the list
6649 +   of SMTP service extensions, which was not obtained from the TLS
6650 +   negotiation itself. The client SHOULD send an EHLO command as the
6651 +   first command after a successful TLS negotiation.
6652 +
6653 +   The list of SMTP service extensions returned in response to an EHLO
6654 +   command received after the TLS handshake MAY be different than the
6655 +   list returned before the TLS handshake. For example, an SMTP server
6656 +   might not want to advertise support for a particular SASL mechanism
6657 +   [SASL] unless a client has sent an appropriate client certificate
6658 +   during a TLS handshake.
6659 +
6660 +   Both the client and the server MUST know if there is a TLS session
6661 +   active.  A client MUST NOT attempt to start a TLS session if a TLS
6662 +   session is already active. A server MUST NOT return the TLS extension
6663 +   in response to an EHLO command received after a TLS handshake has
6664 +   completed.
6665 +
6666 +6. Usage Example
6667 +
6668 +   The following dialog illustrates how a client and server can start a
6669 +   TLS session:
6670 +
6671 +   S: <waits for connection on TCP port 25>
6672 +   C: <opens connection>
6673 +   S: 220 mail.imc.org SMTP service ready
6674 +   C: EHLO mail.ietf.org
6675 +   S: 250-mail.imc.org offers a warm hug of welcome
6676 +   S: 250 STARTTLS
6677 +   C: STARTTLS
6678 +   S: 220 Go ahead
6679 +   C: <starts TLS negotiation>
6680 +
6681 +
6682 +
6683 +Hoffman                     Standards Track                     [Page 4]
6684 +\f
6685 +RFC 2487                 SMTP Service Extension             January 1999
6686 +
6687 +
6688 +   C & S: <negotiate a TLS session>
6689 +   C & S: <check result of negotiation>
6690 +   C: <continues by sending an SMTP command>
6691 +   . . .
6692 +
6693 +7. Security Considerations
6694 +
6695 +   It should be noted that SMTP is not an end-to-end mechanism. Thus, if
6696 +   an SMTP client/server pair decide to add TLS privacy, they are not
6697 +   securing the transport from the originating mail user agent to the
6698 +   recipient.  Further, because delivery of a single piece of mail may
6699 +   go between more than two SMTP servers, adding TLS privacy to one pair
6700 +   of servers does not mean that the entire SMTP chain has been made
6701 +   private. Further, just because an SMTP server can authenticate an
6702 +   SMTP client, it does not mean that the mail from the SMTP client was
6703 +   authenticated by the SMTP client when the client received it.
6704 +
6705 +   Both the STMP client and server must check the result of the TLS
6706 +   negotiation to see whether acceptable authentication or privacy was
6707 +   achieved. Ignoring this step completely invalidates using TLS for
6708 +   security.  The decision about whether acceptable authentication or
6709 +   privacy was achieved is made locally, is implementation-dependant,
6710 +   and is beyond the scope of this document.
6711 +
6712 +   The SMTP client and server should note carefully the result of the
6713 +   TLS negotiation. If the negotiation results in no privacy, or if it
6714 +   results in privacy using algorithms or key lengths that are deemed
6715 +   not strong enough, or if the authentication is not good enough for
6716 +   either party, the client may choose to end the SMTP session with an
6717 +   immediate QUIT command, or the server may choose to not accept any
6718 +   more SMTP commands.
6719 +
6720 +   A server announcing in an EHLO response that it uses a particular TLS
6721 +   protocol should not pose any security issues, since any use of TLS
6722 +   will be at least as secure as no use of TLS.
6723 +
6724 +   A man-in-the-middle attack can be launched by deleting the "250
6725 +   STARTTLS" response from the server. This would cause the client not
6726 +   to try to start a TLS session. An SMTP client can protect against
6727 +   this attack by recording the fact that a particular SMTP server
6728 +   offers TLS during one session and generating an alarm if it does not
6729 +   appear in the EHLO response for a later session. The lack of TLS
6730 +   during a session SHOULD NOT result in the bouncing of email, although
6731 +   it could result in delayed processing.
6732 +
6733 +
6734 +
6735 +
6736 +
6737 +
6738 +
6739 +Hoffman                     Standards Track                     [Page 5]
6740 +\f
6741 +RFC 2487                 SMTP Service Extension             January 1999
6742 +
6743 +
6744 +   Before the TLS handshake has begun, any protocol interactions are
6745 +   performed in the clear and may be modified by an active attacker. For
6746 +   this reason, clients and servers MUST discard any knowledge obtained
6747 +   prior to the start of the TLS handshake upon completion of the TLS
6748 +   handshake.
6749 +
6750 +   The STARTTLS extension is not suitable for authenticating the author
6751 +   of an email message unless every hop in the delivery chain, including
6752 +   the submission to the first SMTP server, is authenticated. Another
6753 +   proposal [SMTP-AUTH] can be used to authenticate delivery and MIME
6754 +   security multiparts [MIME-SEC] can be used to authenticate the author
6755 +   of an email message. In addition, the [SMTP-AUTH] proposal offers
6756 +   simpler and more flexible options to authenticate an SMTP client and
6757 +   the SASL EXTERNAL mechanism [SASL] MAY be used in conjunction with
6758 +   the STARTTLS command to provide an authorization identity.
6759 +
6760 +
6761 +
6762 +
6763 +
6764 +
6765 +
6766 +
6767 +
6768 +
6769 +
6770 +
6771 +
6772 +
6773 +
6774 +
6775 +
6776 +
6777 +
6778 +
6779 +
6780 +
6781 +
6782 +
6783 +
6784 +
6785 +
6786 +
6787 +
6788 +
6789 +
6790 +
6791 +
6792 +
6793 +
6794 +
6795 +Hoffman                     Standards Track                     [Page 6]
6796 +\f
6797 +RFC 2487                 SMTP Service Extension             January 1999
6798 +
6799 +
6800 +A. References
6801 +
6802 +   [RFC-821]   Postel, J., "Simple Mail Transfer Protocol", RFC 821,
6803 +               August 1982.
6804 +
6805 +   [RFC-1869]  Klensin, J., Freed, N, Rose, M, Stefferud, E. and D.
6806 +               Crocker, "SMTP Service Extensions", STD 10, RFC 1869,
6807 +               November 1995.
6808 +
6809 +   [RFC-2034]  Freed, N., "SMTP Service Extension for Returning Enhanced
6810 +               Error Codes", RFC 2034, October 1996.
6811 +
6812 +   [RFC-2119]  Bradner, S., "Key words for use in RFCs to Indicate
6813 +               Requirement Levels", BCP 14, RFC 2119, March 1997.
6814 +
6815 +   [SASL]      Myers, J., "Simple Authentication and Security Layer
6816 +               (SASL)", RFC 2222, October 1997.
6817 +
6818 +   [SMTP-AUTH] "SMTP Service Extension for Authentication", Work in
6819 +               Progress.
6820 +
6821 +   [TLS]       Dierks, T. and C. Allen, "The TLS Protocol Version 1.0",
6822 +               RFC 2246, January 1999.
6823 +
6824 +B. Author's Address
6825 +
6826 +   Paul Hoffman
6827 +   Internet Mail Consortium
6828 +   127 Segre Place
6829 +   Santa Cruz, CA  95060
6830 +
6831 +   Phone: (831) 426-9827
6832 +   EMail: phoffman@imc.org
6833 +
6834 +
6835 +
6836 +
6837 +
6838 +
6839 +
6840 +
6841 +
6842 +
6843 +
6844 +
6845 +
6846 +
6847 +
6848 +
6849 +
6850 +
6851 +Hoffman                     Standards Track                     [Page 7]
6852 +\f
6853 +RFC 2487                 SMTP Service Extension             January 1999
6854 +
6855 +
6856 +C.  Full Copyright Statement
6857 +
6858 +   Copyright (C) The Internet Society (1999).  All Rights Reserved.
6859 +
6860 +   This document and translations of it may be copied and furnished to
6861 +   others, and derivative works that comment on or otherwise explain it
6862 +   or assist in its implementation may be prepared, copied, published
6863 +   and distributed, in whole or in part, without restriction of any
6864 +   kind, provided that the above copyright notice and this paragraph are
6865 +   included on all such copies and derivative works.  However, this
6866 +   document itself may not be modified in any way, such as by removing
6867 +   the copyright notice or references to the Internet Society or other
6868 +   Internet organizations, except as needed for the purpose of
6869 +   developing Internet standards in which case the procedures for
6870 +   copyrights defined in the Internet Standards process must be
6871 +   followed, or as required to translate it into languages other than
6872 +   English.
6873 +
6874 +   The limited permissions granted above are perpetual and will not be
6875 +   revoked by the Internet Society or its successors or assigns.
6876 +
6877 +   This document and the information contained herein is provided on an
6878 +   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
6879 +   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
6880 +   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
6881 +   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
6882 +   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
6883 +
6884 +
6885 +
6886 +
6887 +
6888 +
6889 +
6890 +
6891 +
6892 +
6893 +
6894 +
6895 +
6896 +
6897 +
6898 +
6899 +
6900 +
6901 +
6902 +
6903 +
6904 +
6905 +
6906 +
6907 +Hoffman                     Standards Track                     [Page 8]
6908 +\f
6909 diff -Nur snapshot-20010228-orig/html/ssl/security.html snapshot-20010228/html/ssl/security.html
6910 --- snapshot-20010228-orig/html/ssl/security.html       Thu Jan  1 01:00:00 1970
6911 +++ snapshot-20010228/html/ssl/security.html    Wed Mar 21 13:38:29 2001
6912 @@ -0,0 +1,78 @@
6913 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
6914 +<html>
6915 +<head>
6916 +<meta name="generator" content="HTML Tidy, see www.w3.org">
6917 +<title>Postfix/TLS - Security Considerations</title>
6918 +</head>
6919 +<body>
6920 +<h1>Postfix/TLS - Security Considerations</h1>
6921 +
6922 +The following sections cover some (possible) security issues with
6923 +regard to Postfix/TLS. 
6924 +
6925 +<h2>Server/Client private key file</h2>
6926 +
6927 +Postfix/TLS uses authentication for the server side (mandatory) and
6928 +the client side (optional). In order to authenticate itself, the
6929 +according process (smptd/smtp) must be able to access the private
6930 +key, which must however be kept secret. As these processes are
6931 +started from 'master' without the possibility of user interaction, it is not
6932 +possible to supply a password, so that the private key can not be
6933 +encrypted. 
6934 +
6935 +<p>The only protection can therefore come from filesystem access
6936 +rights, which should be set to 'owner root' and 'readable for owner
6937 +only':</p>
6938 +
6939 +<pre>
6940 +-rw-------   1 root       sys            887 Apr 29  1999 /etc/postfix/key.pem
6941 +</pre>
6942 +
6943 +<p>This protection is only as good as your host is protected
6944 +against root exploits.</p>
6945 +
6946 +<p>You also should be aware, that people having physical access to
6947 +your system might be able to 'steal' the private key if they can
6948 +boot into single user mode without password protection or can move
6949 +the disk to another computer, on which they have root rights. (Yes,
6950 +I know there are such things as encrypted filesystems, but they are
6951 +not in wide spread use today.)</p>
6952 +
6953 +<h2>Disk based session cache</h2>
6954 +
6955 +If you run disk based session caching (the default) people being
6956 +able to get hold of the files might be able to figure out security
6957 +relevant communication parameters. The security situation is
6958 +however not more dramatic than the private key issue explained
6959 +above, so I don't consider any additional danger coming from saving
6960 +session information to stable storage. 
6961 +
6962 +<p>As breaking the code with public key cryptography is just a
6963 +matter of time (even though it might be a very long time), sessions
6964 +should not be used for an infinite duration. The default value for
6965 +Postfix/TLS is 1h; RFC2246 (TLSv1) recommends to not use sessions
6966 +for more than 24h.</p>
6967 +
6968 +<h2>DNS issues</h2>
6969 +
6970 +One weak point in authentication is the use of the DNS to find out
6971 +the MX information. Since we do (E)SMTP, we must use the MX
6972 +information! 
6973 +
6974 +<p>As we have to authenticate the server retrieved via MX, somebody
6975 +able to spoof a wrong MX entry might be able to receive the email,
6976 +if his host can present a certificate issued by an acceptable CA.
6977 +The last part is not too difficult if 'standard' CAs like Verisign,
6978 +Thawte,... are included.</p>
6979 +
6980 +<p>The only way to protect against this problem is that for those
6981 +recipients, for which we want to <strong>enforce</strong>
6982 +encryption and authentication, the MX lookup must be overridden
6983 +with an appropriate entry in the /etc/postfix/transport table:</p>
6984 +
6985 +<pre>
6986 +important.dom.ain smtp:[mailserver.important.dom.ain]
6987 +</pre>
6988 +</body>
6989 +</html>
6990 +
6991 diff -Nur snapshot-20010228-orig/html/ssl/setup.html snapshot-20010228/html/ssl/setup.html
6992 --- snapshot-20010228-orig/html/ssl/setup.html  Thu Jan  1 01:00:00 1970
6993 +++ snapshot-20010228/html/ssl/setup.html       Wed Mar 21 13:38:29 2001
6994 @@ -0,0 +1,219 @@
6995 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
6996 +<html>
6997 +<head>
6998 +<meta name="generator" content="HTML Tidy, see www.w3.org">
6999 +<title>Postfix/TLS - Setting up the certificates</title>
7000 +</head>
7001 +<body>
7002 +<h1>Postfix/TLS - Setting up the certificates</h1>
7003 +
7004 +This section explains what kind of certificates are needed to run
7005 +postfix with TLS. The certificates (and maybe keys) can be obtained
7006 +from a third party, that might be a commercial certification
7007 +authority or your internet service provider. On the long run you do
7008 +need certificates that are accepted by other Internet parties, so
7009 +you have to agree with them on certification authorities, of which
7010 +type they might be. 
7011 +
7012 +<h2>Server certificate</h2>
7013 +
7014 +To run SMTP with TLS in server mode, your server <strong>
7015 +must</strong> have a pair of <em>private key</em> and <em>public
7016 +key</em>. 
7017 +
7018 +<p>As the public key must be distributed to the client somehow, it
7019 +is sent from the server to the client during the startup
7020 +negotiation. The client however cannot know from just the
7021 +negotiation, that the public key really belongs to the server and
7022 +is not faked. Therefore a third component is necessary, a <em>
7023 +certificate</em> from a certificate authority (CA), that is sent
7024 +combined with the public key. This <em>server certificate</em>
7025 +contains the <code>name.of.your.host</code>. The client will then
7026 +check the <em>signature</em> of the CA on the public key to decide,
7027 +whether the certificate (and public key) are authentic.</p>
7028 +
7029 +<p>So for the server we do need:</p>
7030 +
7031 +<ul>
7032 +<li>1 <em>server private key</em></li>
7033 +
7034 +<li>1 server public key signed by a CA, a <em>server
7035 +certificate</em>, certifying that the public key belongs to <code>
7036 +name.of.your.host</code>.</li>
7037 +
7038 +<li>1 <em>CA certificate</em> with the public key of the CA</li>
7039 +</ul>
7040 +
7041 +For this list I definitely want point out the number of components
7042 +used to be <strong>1</strong>, because you must have <strong>
7043 +1</strong>, you cannot have less, you cannot have more! 
7044 +
7045 +<h3>Server certificate policy</h3>
7046 +
7047 +At this point you have to decide about policy. The client which is
7048 +going to connect to your host will check the name in the <em>server
7049 +certificate</em>, the CN (Common Name), against the FQDN (Fully
7050 +Qualified Domain Name) of your server. If both agree, your server's
7051 +identity is proved. 
7052 +
7053 +<p>To see, whether the certificate itself is authentic, the client
7054 +itself <em>must have</em> the <em>CA certificate</em>. So, if you
7055 +want to make it easily accessible to other, unknown parties, you
7056 +should have your server certificate issued by a well known and well
7057 +trusted CA. Remember, that your server can only have one server
7058 +certificate at a time.</p>
7059 +
7060 +<p>There are commercial providers (Thawte, Verisign, just to name
7061 +some), the CA certificats of which are well distributed. Not
7062 +knowing of other countries, at least in Germany the CERT of the
7063 +Research Network (DFN) has started a program for universities [<a
7064 +href="references.html#dfncert">DFNCERT</a>].</p>
7065 +
7066 +<p>If you do not care about that for know (you can change that
7067 +later), you can just become your own CA and distribute your CA cert
7068 +to those parties who should know it, and you are set. It is not
7069 +difficult to do.<br>
7070 +<a href="myownca.html">Lutz's very short course on being your own
7071 +CA</a>.</p>
7072 +
7073 +<h3>Using the certificates with Postfix/TLS</h3>
7074 +
7075 +To make the key and certificates available to Postfix/TLS, they
7076 +must be in "PEM" format. Then you have to tell postfix in main.cf
7077 +where to find them: 
7078 +
7079 +<ul>
7080 +<li>The private key: 
7081 +
7082 +<pre>
7083 +smtp_tls_key_file = /etc/postfix/key.pem
7084 +</pre>
7085 +
7086 +As the public key is public including the certificate (everybody
7087 +can get a copy), everybody who has a copy of the private key can
7088 +fake your identity. It is not too easy, as he must be able to
7089 +redirect or intercept the IP packages sent to your server, but I
7090 +have seen a lot of things happening. So protect this key with: 
7091 +
7092 +<pre>
7093 +chown root /etc/postfix/key.pem ; chmod 400 /etc/postfix/key.pem
7094 +</pre>
7095 +
7096 +One more possibility for protection is a passphrase. This is
7097 +however a problem, as you have to enter it everytime the server has
7098 +to be started. This has to drawbacks: firstly you would have to
7099 +enter it to postfix everytime you restart it, which I find quite
7100 +impractical for an unattended server which might restart
7101 +automatically after a power outage. Secondly the smtpd processes
7102 +are independently started from master, so that master would have to
7103 +pass the passphrase to the clients somehow. Alltogether I think
7104 +this is impractical and so I don't support by software.</li>
7105 +
7106 +<li>The server certificate: This certificate is not secret, as it
7107 +will be presented to every client anyhow, so you just name it to
7108 +postfix: 
7109 +
7110 +<pre>
7111 +smtp_tls_cert_file = /etc/postfix/cert.pem
7112 +</pre>
7113 +
7114 +If you like, you can put private key and cert into one file.</li>
7115 +
7116 +<li>The CA certificate: To also have the CA certificate available,
7117 +you put it into a file and name it to Postfix/TLS. We will come
7118 +back to this file later. 
7119 +
7120 +<pre>
7121 +smtp_tls_CAfile = /etc/postfix/CAcert.pem
7122 +</pre>
7123 +</li>
7124 +</ul>
7125 +
7126 +With these certificates you should already have enough to get
7127 +Postfix/TLS running. 
7128 +
7129 +<h3>Postfix/TLS client mode</h3>
7130 +
7131 +When connecting to a server offering TLS, postfix can present a
7132 +client certificate of its own. As realized by now, only one
7133 +certificate can be managed, so it should be issued on your own
7134 +hostname. No default is supplied (no certificate is presented),
7135 +unless you explicitly set the certificate in the configuration. You
7136 +can use the same certificate as for the server side: 
7137 +
7138 +<pre>
7139 +smtp_tls_key_file = /etc/postfix/key.pem
7140 +chown root /etc/postfix/key.pem ; chmod 400 /etc/postfix/key.pem
7141 +</pre>
7142 +
7143 +<pre>
7144 +smtp_tls_cert_file = /etc/postfix/cert.pem
7145 +</pre>
7146 +
7147 +<pre>
7148 +smtp_tls_CAfile = /etc/postfix/CAcert.pem
7149 +</pre>
7150 +
7151 +<h2>Client certificates</h2>
7152 +
7153 +One reason to do all of this work is that I want to do relaying
7154 +based on client certificates. The clients present a certificate
7155 +from a CA, that is unique and cannot be faked. 
7156 +
7157 +<p>Some clients can have several certificates issued by different
7158 +CAs. Upon connection the server will pass the client the list of
7159 +CAs he knows (has the CA certificates) and the client can then pass
7160 +back a certificate of choice. With Netscape this means, a window is
7161 +opened and only those client certificates compatible with the
7162 +server are listed for selection.</p>
7163 +
7164 +<p>So if your clients already have certificates from trustable
7165 +sources, it is not necessary to create a lot of problems. You just
7166 +have to collect the CA certificates and make them available to
7167 +Postfix/TLS. If that is not enough, you can still become your own
7168 +CA to easily create client certificates for your users (which are
7169 +of course of no use outside your scope).</p>
7170 +
7171 +<h3>Listing CA certificates</h3>
7172 +
7173 +<p>You have two possibilities to perform this task.</p>
7174 +
7175 +<ol>
7176 +<li>You just add the CA certificates to the <code>
7177 +smtp[d]_tls_CAfile</code> you already have created, one after the
7178 +other. This file is probably not very readable, but it has the
7179 +advantage that it is read at smtpd before switching to chroot jail
7180 +and hence works in chroot mode.</li>
7181 +
7182 +<li>You can add the CA certificates in single files with adequate
7183 +names to a certificate directory specified in: 
7184 +
7185 +<pre>
7186 +smtpd_tls_CApath = /etc/postfix/certs
7187 +</pre>
7188 +
7189 +Please don't forget to issue a <code>$OPENSSL_HOME/bin/c_rehash
7190 +/etc/postfix/certs</code> after you have made changes, as the
7191 +hashes are use to find the right CA certificate. This method should
7192 +not work in chroot mode.</li>
7193 +</ol>
7194 +
7195 +<h3>Adding client certificates</h3>
7196 +
7197 +The client certificates are issued for a DN (Distinguished Name)
7198 +made up of company, department, name, email... As they may contain
7199 +blanks, @ signs and colons, it is quite difficult to handle them
7200 +with standard postfix tools. 
7201 +
7202 +<p>A quite practical thing is that every client certificate has a
7203 +"fingerprint" that is extremely difficult to fake (read this: from
7204 +my knowledge, it might take years even on fast computers). I have
7205 +to do some more research about the security of the fingerprint, but
7206 +at least for relaying it should be secure enough. I will much
7207 +easier find a host with worse security to send out my SPAM than to
7208 +fake a client certificate with a matching fingerprint (which I also
7209 +don't know to from the outside, even from the inside you might
7210 +protect the fingerprint data with a <code>chmod 400</code>).</p>
7211 +</body>
7212 +</html>
7213 +
7214 diff -Nur snapshot-20010228-orig/html/ssl/test.html snapshot-20010228/html/ssl/test.html
7215 --- snapshot-20010228-orig/html/ssl/test.html   Thu Jan  1 01:00:00 1970
7216 +++ snapshot-20010228/html/ssl/test.html        Wed Mar 21 13:38:29 2001
7217 @@ -0,0 +1,178 @@
7218 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
7219 +<html>
7220 +<head>
7221 +<meta name="generator" content="HTML Tidy, see www.w3.org">
7222 +<title>Postfix/TLS - Testing</title>
7223 +</head>
7224 +<body>
7225 +<h1>Postfix/TLS - Testing</h1>
7226 +
7227 +Testing the package is a little bit difficult, as the communication
7228 +is encrypted, so that you cannot "imitate" the conversation just by
7229 +telnetting to the SMTP port. You also cannot capture the packets
7230 +(well, you can, but if everything is working as advertised, it
7231 +won't help you :-). 
7232 +
7233 +<h2>Included debugging aids</h2>
7234 +
7235 +As all of the messages generated by Postfix are sent to the syslog
7236 +facility, debugging must be done using your normal system logfiles.
7237 +Postfix/TLS supports the logging levels 0 (very quiet) up to 4 (a
7238 +dump of the complete conversation, not recommended). 
7239 +
7240 +<p>As a first step set <code>smpt[d]_tls_loglevel=2</code> and
7241 +watch the logfile. Typically you will have problems with the access
7242 +to the keys or certificates, so you will find error messages
7243 +here.</p>
7244 +
7245 +<p>You can always try to send an email to <tt>
7246 +postfix_tls-bounce@serv01.aet.tu-cottbus.de</tt> with TLS enabled
7247 +at your side and watch, what is going to happen :-)</p>
7248 +
7249 +<p>While testing the interoperability with ZMailer we learned, that
7250 +an incorrect certificate type (must be server for the server :-)
7251 +can lead to connection failures without clear symptoms. It helps to
7252 +use Netscape 4.5x as a client and carefully study the message boxes
7253 +and certificate information. I have yet to find out how to identify
7254 +this problem from postfix to print a suitable warning to the
7255 +logfile. Hopefully it will be possible without changes in the
7256 +OpenSSL library.</p>
7257 +
7258 +<h2>Platforms</h2>
7259 +
7260 +<ul>
7261 +<li>Development Platform: 
7262 +
7263 +<ul>
7264 +<li>OS: HP-UX 10.20</li>
7265 +
7266 +<li>OS: Linux 2.x (SuSE Linux)</li>
7267 +</ul>
7268 +</li>
7269 +
7270 +<li>Reported Success: 
7271 +
7272 +<ul>
7273 +<li>OS: Solaris 2.5 - Walcir Fontanini
7274 +&lt;walcir@densis.fee.unicamp.br&gt;</li>
7275 +</ul>
7276 +</li>
7277 +
7278 +<li>Test Client: 
7279 +
7280 +<ul>
7281 +<li>Software: Netscape 4.5x, Netscape 4.6x, Netscape 4.7x</li>
7282 +
7283 +<li>OS: HP-UX 10.20, Linux 2.x, Win95</li>
7284 +</ul>
7285 +</li>
7286 +</ul>
7287 +
7288 +Please don't comment on the stability of Netscape, especially not
7289 +on HP-UX... 
7290 +
7291 +<h2>Interoperability</h2>
7292 +
7293 +Besides support by generic wrapper solutions, there exist specially
7294 +crafted extensions for other MTAs: 
7295 +
7296 +<ul>
7297 +<li><strong>Qmail</strong> There is an OpenSource patch available,
7298 +extending the Qmail [<a href="references.html#qmail">QMAIL</a>] MTA
7299 +to support RFC2487, written by Frederik Vermeulen [<a href=
7300 +"references.html#qmailtls">QMAILTLS</a>]. Sending and receiving is
7301 +working from both sides. 
7302 +
7303 +<p>Testing: send mail to <tt>ping@linux.student.kuleuven.ac.be</tt>
7304 +(will send back complete email including headers).</p>
7305 +</li>
7306 +
7307 +<li><strong>Zmailer</strong> The author/maintainer of ZMailer,
7308 +Matti Aarnio, has incorporated both server and client side TLS
7309 +support [<a href="references.html#zmailer">ZMAILER</a>]. 
7310 +
7311 +<p>Zmailer -&gt; Postfix works fine,<br>
7312 +Postfix -&gt; Zmailer does not work, since ESMTP is not recognized
7313 +(problem reported).</p>
7314 +
7315 +<p>Testing: send mail to <tt>autoanswer@mea.tmt.tele.fi</tt> (will
7316 +send back headers).</p>
7317 +</li>
7318 +
7319 +<li><strong>Sendmail</strong> The commercial verson of sendmail
7320 +supports client and server TLS, both sides interoperating with
7321 +Postfix/TLS. As of sendmail-8.11, TLS is also included with the
7322 +opensource version [<a href=
7323 +"references.html#sendmail">SENDMAIL</a>]. 
7324 +
7325 +<p>Testing: send mail to <tt>bounce@esmtp.org</tt> (will bounce
7326 +error message including old headers).</p>
7327 +</li>
7328 +
7329 +<li><strong>Postfix</strong> Can send emails to itself :-). 
7330 +
7331 +<p>Testing: send mail to <tt>
7332 +postfix_tls-bounce@serv01.aet.tu-cottbus.de</tt> (will bounce back,
7333 +includes old headers).</p>
7334 +</li>
7335 +</ul>
7336 +
7337 +Other reports are welcome. 
7338 +
7339 +<h2>Known bugs</h2>
7340 +
7341 +This software is just at the beginning, so please be patient. By
7342 +now I have these points: 
7343 +
7344 +<ul>
7345 +<li>Server side: Under Win95/NT I have some problems with the
7346 +client certificates. When opening the first connection (and
7347 +Netscape asks for the password to access the certificate database),
7348 +the connection hangs. This seems to be caused by Netscape: a dump
7349 +of the communication shows, that Netscape just does not resume the
7350 +TLS handshake.<br>
7351 +<strong>Remark:</strong>I could not reproduce this bug recently
7352 +after upgrading OpenSSL 0.9.4. I hope it has vanished, but maybe it
7353 +is just a consequence of playing around with Netscape's security
7354 +options. More testing required...<br>
7355 +Workarounds: kill this connection, the next one will work
7356 +immediately <strong>or</strong> use SSLv2 only (second workaround
7357 +not recommended). 
7358 +
7359 +<p><strong>Should finally be fixed with OpenSSL 0.9.5.</strong></p>
7360 +</li>
7361 +
7362 +<li>Server side: Outlook Express as of Internet Explorer 5 will
7363 +work with Postfix/TLS, but it will not present any client
7364 +certificate. So you can encrypt your email transfer but you cannot
7365 +authenticate (and relay) with client certificates. It only works on
7366 +port 25 (smtp); on other ports you must use smtpd_tls_wrappermode
7367 +instead. [<a href="references.html#oe_ssl">Microsoft
7368 +Knowledgebase</a>]</li>
7369 +
7370 +<li>Server side: Outlook Express as of Internet Explorer 4 does not
7371 +support RFC2487. Use smtpd_tls_wrappermode=yes on a different
7372 +port(!) instead.</li>
7373 +
7374 +<li>Server side: Outlook Express (Mac) seems not to support
7375 +RFC2487, you must use smtpd_tls_wrappermode on a different port(!)
7376 +instead.</li>
7377 +
7378 +<li>Client side: MS Exchange also in recent versions (5.5) offers
7379 +STARTTLS even if not configured (from the mailing list [<a href=
7380 +"references.html#imcorgappstls">IETF-APPS-TLS</a>]). I could not
7381 +test this without access to such server, so I cannot predict what
7382 +is going to happen.</li>
7383 +
7384 +<li>Client side: TLS connections to a CommunigatePro server fail
7385 +with a handshake error with older versions of CommunigatePro.
7386 +Reason is a protocol violation of the CommunigatePro server with
7387 +respect to SSL-protocol version numbering. The respective part of
7388 +the protocol is the specification of the client_version in section
7389 +7.4.7.1. of RFC2246.<br>
7390 +This problem has been fixed in CommunigatePro 3.3b?? (don't know
7391 +the exact numbering) around June 09, 2000.</li>
7392 +</ul>
7393 +</body>
7394 +</html>
7395 +
7396 diff -Nur snapshot-20010228-orig/man/man8/tlsmgr.8 snapshot-20010228/man/man8/tlsmgr.8
7397 --- snapshot-20010228-orig/man/man8/tlsmgr.8    Thu Jan  1 01:00:00 1970
7398 +++ snapshot-20010228/man/man8/tlsmgr.8 Wed Mar 21 13:32:23 2001
7399 @@ -0,0 +1,130 @@
7400 +.TH TLSMGR 8 
7401 +.ad
7402 +.fi
7403 +.SH NAME
7404 +tlsmgr
7405 +\-
7406 +Postfix TLS session cache and PRNG handling manager
7407 +.SH SYNOPSIS
7408 +.na
7409 +.nf
7410 +\fBtlsmgr\fR [generic Postfix daemon options]
7411 +.SH DESCRIPTION
7412 +.ad
7413 +.fi
7414 +The tlsmgr process does housekeeping on the session cache database
7415 +files. It runs through the databases and removes expired entries
7416 +and entries written by older (incompatible) versions.
7417 +
7418 +The tlsmgr is responsible for the PRNG handling. The used internal
7419 +OpenSSL PRNG has a pool size of 8192 bits (= 1024 bytes). The pool
7420 +is initially seeded at startup from an external source (EGD or
7421 +/dev/urandom) and additional seed is obtained later during program
7422 +run at a configurable period. The exact time of seed query is
7423 +using random information and is equally distributed in the range of
7424 +[0-\fBtls_random_reseed_period\fR] with a \fBtls_random_reseed_period\fR
7425 +having a default of 1 hour.
7426 +
7427 +Tlsmgr can be run chrooted and with dropped privileges, as it will
7428 +connect to the entropy source at startup.
7429 +
7430 +The PRNG is additionally seeded internally by the data found in the
7431 +session cache and timevalues.
7432 +
7433 +Tlsmgr reads the old value of the exchange file at startup to keep
7434 +entropy already collected during previous runs.
7435 +
7436 +From the PRNG random pool a cryptographically strong 1024 byte random
7437 +sequence is written into the PRNG exchange file. The file is updated
7438 +periodically with the time changing randomly from
7439 +[0-\fBtls_random_prng_update_period\fR].
7440 +.SH STANDARDS
7441 +.na
7442 +.nf
7443 +.SH SECURITY
7444 +.na
7445 +.nf
7446 +.ad
7447 +.fi
7448 +Tlsmgr is not security-sensitive. It only deals with external data
7449 +to be fed into the PRNG, the contents is never trusted. The session
7450 +cache housekeeping will only remove entries if expired and will never
7451 +touch the contents of the cached data.
7452 +.SH DIAGNOSTICS
7453 +.ad
7454 +.fi
7455 +Problems and transactions are logged to the syslog daemon.
7456 +.SH BUGS
7457 +.ad
7458 +.fi
7459 +There is no automatic means to limit the number of entries in the
7460 +session caches and/or the size of the session cache files.
7461 +.SH CONFIGURATION PARAMETERS
7462 +.na
7463 +.nf
7464 +.ad
7465 +.fi
7466 +The following \fBmain.cf\fR parameters are especially relevant to
7467 +this program. See the Postfix \fBmain.cf\fR file for syntax details
7468 +and for default values. Use the \fBpostfix reload\fR command after
7469 +a configuration change.
7470 +.SH Session Cache
7471 +.ad
7472 +.fi
7473 +.IP \fBsmtpd_tls_session_cache_database\fR
7474 +Name of the SDBM file (type sdbm:) containing the SMTP server session
7475 +cache. If the file does not exist, it is created.
7476 +.IP \fBsmtpd_tls_session_cache_timeout\fR
7477 +Expiry time of SMTP server session cache entries in seconds. Entries
7478 +older than this are removed from the session cache. A cleanup-run is
7479 +performed periodically every \fBsmtpd_tls_session_cache_timeout\fR
7480 +seconds. Default is 3600 (= 1 hour).
7481 +.IP \fBsmtp_tls_session_cache_database\fR
7482 +Name of the SDBM file (type sdbm:) containing the SMTP client session
7483 +cache. If the file does not exist, it is created.
7484 +.IP \fBsmtp_tls_session_cache_timeout\fR
7485 +Expiry time of SMTP client session cache entries in seconds. Entries
7486 +older than this are removed from the session cache. A cleanup-run is
7487 +performed periodically every \fBsmtp_tls_session_cache_timeout\fR
7488 +seconds. Default is 3600 (= 1 hour).
7489 +.SH Pseudo Random Number Generator
7490 +.ad
7491 +.fi
7492 +.IP \fBtls_random_source\fR
7493 +Name of the EGD socket or device or regular file to obtain entropy
7494 +from. The type of entropy source must be specified by preceding the
7495 +name with the appropriate type: egd:/path/to/egd_socket,
7496 +dev:/path/to/devicefile, or /path/to/regular/file.
7497 +tlsmgr opens \fBtls_random_source\fR and tries to read
7498 +\fBtls_random_bytes\fR from it.
7499 +.IP \fBtls_random_bytes\fR
7500 +Number of bytes to be read from \fBtls_random_source\fR.
7501 +Default value is 32 bytes. If using EGD, a maximum of 255 bytes is read.
7502 +.IP \fBtls_random_exchange_name\fR
7503 +Name of the file written by tlsmgr and read by smtp and smtpd at
7504 +startup. The length is 1024 bytes. Default value is
7505 +/etc/postfix/prng_exch.
7506 +.IP \fBtls_random_reseed_period\fR
7507 +Time in seconds until the next reseed from external sources is due.
7508 +This is the maximum value. The actual point in time is calculated
7509 +with a random factor equally distributed between 0 and this maximum
7510 +value. Default is 3600 (= 60 minutes).
7511 +.IP \fBtls_random_prng_update_period\fR
7512 +Time in seconds until the PRNG exchange file is updated with new
7513 +pseude random values. This is the maximum value. The actual point
7514 +in time is calculated with a random factor equally distributed
7515 +between 0 and this maximum value. Default is 60 (= 1 minute).
7516 +.SH SEE ALSO
7517 +.na
7518 +.nf
7519 +smtp(8) SMTP client
7520 +smtpd(8) SMTP server
7521 +.SH LICENSE
7522 +.na
7523 +.nf
7524 +.ad
7525 +.fi
7526 +The Secure Mailer license must be distributed with this software.
7527 +.SH AUTHOR(S)
7528 +.na
7529 +.nf
7530 diff -Nur snapshot-20010228-orig/src/global/Makefile.in snapshot-20010228/src/global/Makefile.in
7531 --- snapshot-20010228-orig/src/global/Makefile.in       Wed Mar 21 13:26:24 2001
7532 +++ snapshot-20010228/src/global/Makefile.in    Wed Mar 21 13:32:23 2001
7533 @@ -18,7 +18,8 @@
7534         sent.c smtp_stream.c split_addr.c string_list.c sys_exits.c \
7535         timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
7536         tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
7537 -       flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c
7538 +       flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
7539 +       pfixtls.c
7540  OBJS   = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
7541         debug_peer.o debug_process.o defer.o deliver_completed.o \
7542         deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \
7543 @@ -38,7 +39,8 @@
7544         sent.o smtp_stream.o split_addr.o string_list.o sys_exits.o \
7545         timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
7546         tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
7547 -       flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o
7548 +       flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
7549 +       pfixtls.o
7550  HDRS   = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
7551         config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
7552         deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \
7553 @@ -54,7 +56,7 @@
7554         recipient_list.h record.h resolve_clnt.h resolve_local.h \
7555         rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
7556         sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
7557 -       mbox_conf.h mbox_open.h abounce.h
7558 +       mbox_conf.h mbox_open.h abounce.h pfixtls.h
7559  TESTSRC        = rec2stream.c stream2rec.c recdump.c
7560  WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
7561         -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
7562 @@ -1039,3 +1041,14 @@
7563  xtext.o: ../../include/vbuf.h
7564  xtext.o: ../../include/vstring.h
7565  xtext.o: xtext.h
7566 +pfixtls.o: pfixtls.c
7567 +pfixtls.o: ../../include/sys_defs.h
7568 +pfixtls.o: ../../include/iostuff.h
7569 +pfixtls.o: ../../include/mymalloc.h
7570 +pfixtls.o: ../../include/vstring.h
7571 +pfixtls.o: ../../include/vstream.h
7572 +pfixtls.o: ../../include/dict.h
7573 +pfixtls.o: ../../include/myflock.h
7574 +pfixtls.o: ../../include/stringops.h
7575 +pfixtls.o: mail_params.h
7576 +pfixtls.o: pfixtls.h
7577 diff -Nur snapshot-20010228-orig/src/global/mail_params.c snapshot-20010228/src/global/mail_params.c
7578 --- snapshot-20010228-orig/src/global/mail_params.c     Wed Mar 21 13:26:24 2001
7579 +++ snapshot-20010228/src/global/mail_params.c  Wed Mar 21 13:32:23 2001
7580 @@ -174,6 +174,31 @@
7581  char   *var_fflush_domains;
7582  char   *var_def_transport;
7583  char   *var_mynetworks_style;
7584 +char   *var_tls_rand_exch_name;
7585 +char   *var_smtpd_tls_cert_file;
7586 +char   *var_smtpd_tls_key_file;
7587 +char   *var_smtpd_tls_dcert_file;
7588 +char   *var_smtpd_tls_dkey_file;
7589 +char   *var_smtpd_tls_CAfile;
7590 +char   *var_smtpd_tls_CApath;
7591 +char   *var_smtpd_tls_cipherlist;
7592 +char   *var_smtpd_tls_dh512_param_file;
7593 +char   *var_smtpd_tls_dh1024_param_file;
7594 +int     var_smtpd_tls_loglevel;
7595 +char   *var_smtpd_tls_scache_db;
7596 +int     var_smtpd_tls_scache_timeout;
7597 +char   *var_smtp_tls_cert_file;
7598 +char   *var_smtp_tls_key_file;
7599 +char   *var_smtp_tls_dcert_file;
7600 +char   *var_smtp_tls_dkey_file;
7601 +char   *var_smtp_tls_CAfile;
7602 +char   *var_smtp_tls_CApath;
7603 +char   *var_smtp_tls_cipherlist;
7604 +int     var_smtp_tls_loglevel;
7605 +char   *var_smtp_tls_scache_db;
7606 +int     var_smtp_tls_scache_timeout;
7607 +char   *var_tls_daemon_rand_source;
7608 +int     var_tls_daemon_rand_bytes;
7609  
7610  char   *var_import_environ;
7611  char   *var_export_environ;
7612 @@ -293,6 +318,26 @@
7613         VAR_IMPORT_ENVIRON, DEF_IMPORT_ENVIRON, &var_import_environ, 0, 0,
7614         VAR_DEF_TRANSPORT, DEF_DEF_TRANSPORT, &var_def_transport, 0, 0,
7615         VAR_MYNETWORKS_STYLE, DEF_MYNETWORKS_STYLE, &var_mynetworks_style, 1, 0,
7616 +       VAR_TLS_RAND_EXCH_NAME, DEF_TLS_RAND_EXCH_NAME, &var_tls_rand_exch_name, 0, 0,
7617 +       VAR_SMTPD_TLS_CERT_FILE, DEF_SMTPD_TLS_CERT_FILE, &var_smtpd_tls_cert_file, 0, 0,
7618 +       VAR_SMTPD_TLS_KEY_FILE, DEF_SMTPD_TLS_KEY_FILE, &var_smtpd_tls_key_file, 0, 0,
7619 +       VAR_SMTPD_TLS_DCERT_FILE, DEF_SMTPD_TLS_DCERT_FILE, &var_smtpd_tls_dcert_file, 0, 0,
7620 +       VAR_SMTPD_TLS_DKEY_FILE, DEF_SMTPD_TLS_DKEY_FILE, &var_smtpd_tls_dkey_file, 0, 0,
7621 +       VAR_SMTPD_TLS_CA_FILE, DEF_SMTPD_TLS_CA_FILE, &var_smtpd_tls_CAfile, 0, 0,
7622 +       VAR_SMTPD_TLS_CA_PATH, DEF_SMTPD_TLS_CA_PATH, &var_smtpd_tls_CApath, 0, 0,
7623 +       VAR_SMTPD_TLS_CLIST, DEF_SMTPD_TLS_CLIST, &var_smtpd_tls_cipherlist, 0, 0,
7624 +       VAR_SMTPD_TLS_512_FILE, DEF_SMTPD_TLS_512_FILE, &var_smtpd_tls_dh512_param_file, 0, 0,
7625 +       VAR_SMTPD_TLS_1024_FILE, DEF_SMTPD_TLS_1024_FILE, &var_smtpd_tls_dh1024_param_file, 0, 0,
7626 +       VAR_SMTPD_TLS_SCACHE_DB, DEF_SMTPD_TLS_SCACHE_DB, &var_smtpd_tls_scache_db, 0, 0,
7627 +       VAR_SMTP_TLS_CERT_FILE, DEF_SMTP_TLS_CERT_FILE, &var_smtp_tls_cert_file, 0, 0,
7628 +       VAR_SMTP_TLS_KEY_FILE, DEF_SMTP_TLS_KEY_FILE, &var_smtp_tls_key_file, 0, 0,
7629 +       VAR_SMTP_TLS_DCERT_FILE, DEF_SMTP_TLS_DCERT_FILE, &var_smtp_tls_dcert_file, 0, 0,
7630 +       VAR_SMTP_TLS_DKEY_FILE, DEF_SMTP_TLS_DKEY_FILE, &var_smtp_tls_dkey_file, 0, 0,
7631 +       VAR_SMTP_TLS_CA_FILE, DEF_SMTP_TLS_CA_FILE, &var_smtp_tls_CAfile, 0, 0,
7632 +       VAR_SMTP_TLS_CA_PATH, DEF_SMTP_TLS_CA_PATH, &var_smtp_tls_CApath, 0, 0,
7633 +       VAR_SMTP_TLS_CLIST, DEF_SMTP_TLS_CLIST, &var_smtp_tls_cipherlist, 0, 0,
7634 +       VAR_SMTP_TLS_SCACHE_DB, DEF_SMTP_TLS_SCACHE_DB, &var_smtp_tls_scache_db, 0, 0,
7635 +       VAR_TLS_DAEMON_RAND_SOURCE, DEF_TLS_DAEMON_RAND_SOURCE, &var_tls_daemon_rand_source, 0, 0,
7636         0,
7637      };
7638      static CONFIG_STR_FN_TABLE function_str_defaults_2[] = {
7639 @@ -307,6 +352,9 @@
7640         VAR_HASH_QUEUE_DEPTH, DEF_HASH_QUEUE_DEPTH, &var_hash_queue_depth, 1, 0,
7641         VAR_FORK_TRIES, DEF_FORK_TRIES, &var_fork_tries, 1, 0,
7642         VAR_FLOCK_TRIES, DEF_FLOCK_TRIES, &var_flock_tries, 1, 0,
7643 +       VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0,
7644 +       VAR_SMTP_TLS_LOGLEVEL, DEF_SMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0,
7645 +       VAR_TLS_DAEMON_RAND_BYTES, DEF_TLS_DAEMON_RAND_BYTES, &var_tls_daemon_rand_bytes, 0, 0,
7646         0,
7647      };
7648      static CONFIG_TIME_TABLE time_defaults[] = {
7649 @@ -317,6 +365,8 @@
7650         VAR_FORK_DELAY, DEF_FORK_DELAY, &var_fork_delay, 1, 0,
7651         VAR_FLOCK_DELAY, DEF_FLOCK_DELAY, &var_flock_delay, 1, 0,
7652         VAR_FLOCK_STALE, DEF_FLOCK_STALE, &var_flock_stale, 1, 0,
7653 +       VAR_SMTPD_TLS_SCACHTIME, DEF_SMTPD_TLS_SCACHTIME, &var_smtpd_tls_scache_timeout, 0, 0,
7654 +       VAR_SMTP_TLS_SCACHTIME, DEF_SMTP_TLS_SCACHTIME, &var_smtp_tls_scache_timeout, 0, 0,
7655         VAR_DAEMON_TIMEOUT, DEF_DAEMON_TIMEOUT, &var_daemon_timeout, 1, 0,
7656         0,
7657      };
7658 diff -Nur snapshot-20010228-orig/src/global/mail_params.h snapshot-20010228/src/global/mail_params.h
7659 --- snapshot-20010228-orig/src/global/mail_params.h     Wed Mar 21 13:26:24 2001
7660 +++ snapshot-20010228/src/global/mail_params.h  Wed Mar 21 13:32:23 2001
7661 @@ -430,6 +430,34 @@
7662  #define DEF_DUP_FILTER_LIMIT   1000
7663  extern int var_dup_filter_limit;
7664  
7665 +#define VAR_TLS_RAND_EXCH_NAME "tls_random_exchange_name"
7666 +#define DEF_TLS_RAND_EXCH_NAME "${config_directory}/prng_exch"
7667 +extern char *var_tls_rand_exch_name;
7668 +
7669 +#define VAR_TLS_RAND_SOURCE    "tls_random_source"
7670 +#define DEF_TLS_RAND_SOURCE    ""
7671 +extern char *var_tls_rand_source;
7672 +
7673 +#define VAR_TLS_RAND_BYTES     "tls_random_bytes"
7674 +#define DEF_TLS_RAND_BYTES     32
7675 +extern int var_tls_rand_bytes;
7676 +
7677 +#define VAR_TLS_DAEMON_RAND_SOURCE     "tls_daemon_random_source"
7678 +#define DEF_TLS_DAEMON_RAND_SOURCE     ""
7679 +extern char *var_tls_daemon_rand_source;
7680 +
7681 +#define VAR_TLS_DAEMON_RAND_BYTES      "tls_daemon_random_bytes"
7682 +#define DEF_TLS_DAEMON_RAND_BYTES      32
7683 +extern int var_tls_daemon_rand_bytes;
7684 +
7685 +#define VAR_TLS_RESEED_PERIOD  "tls_random_reseed_period"
7686 +#define DEF_TLS_RESEED_PERIOD  "3600s"
7687 +extern int var_tls_reseed_period;
7688 +
7689 +#define VAR_TLS_PRNG_UPD_PERIOD        "tls_random_prng_update_period"
7690 +#define DEF_TLS_PRNG_UPD_PERIOD "60s"
7691 +extern int var_tls_prng_upd_period;
7692 +
7693   /*
7694    * Queue manager: relocated databases.
7695    */
7696 @@ -647,6 +675,10 @@
7697  #define DEF_SMTP_HELO_TMOUT    "300s"
7698  extern int var_smtp_helo_tmout;
7699  
7700 +#define VAR_SMTP_STARTTLS_TMOUT        "smtp_starttls_timeout"
7701 +#define DEF_SMTP_STARTTLS_TMOUT        "300s"
7702 +extern int var_smtp_starttls_tmout;
7703 +
7704  #define VAR_SMTP_MAIL_TMOUT    "smtp_mail_timeout"
7705  #define DEF_SMTP_MAIL_TMOUT    "300s"
7706  extern int var_smtp_mail_tmout;
7707 @@ -699,6 +731,10 @@
7708  #define DEF_SMTP_BIND_ADDR     ""
7709  extern char *var_smtp_bind_addr;
7710  
7711 +#define VAR_SMTP_ALWAYS_EHLO   "smtp_always_send_ehlo"
7712 +#define DEF_SMTP_ALWAYS_EHLO   0
7713 +extern bool var_smtp_always_ehlo;
7714 +
7715   /*
7716    * SMTP server. The soft error limit determines how many errors an SMTP
7717    * client may make before we start to slow down; the hard error limit
7718 @@ -712,6 +748,10 @@
7719  #define DEF_SMTPD_TMOUT                "300s"
7720  extern int var_smtpd_tmout;
7721  
7722 +#define VAR_SMTPD_STARTTLS_TMOUT "smtpd_starttls_timeout"
7723 +#define DEF_SMTPD_STARTTLS_TMOUT "300s"
7724 +extern int var_smtpd_starttls_tmout;
7725 +
7726  #define VAR_SMTPD_RCPT_LIMIT   "smtpd_recipient_limit"
7727  #define DEF_SMTPD_RCPT_LIMIT   1000
7728  extern int var_smtpd_rcpt_limit;
7729 @@ -732,6 +772,146 @@
7730  #define DEF_SMTPD_JUNK_CMD     1000
7731  extern int var_smtpd_junk_cmd_limit;
7732  
7733 +#define VAR_SMTPD_TLS_WRAPPER  "smtpd_tls_wrappermode"
7734 +#define DEF_SMTPD_TLS_WRAPPER  0
7735 +extern bool var_smtpd_tls_wrappermode;
7736 +
7737 +#define VAR_SMTPD_USE_TLS      "smtpd_use_tls"
7738 +#define DEF_SMTPD_USE_TLS      0
7739 +extern bool var_smtpd_use_tls;
7740 +
7741 +#define VAR_SMTPD_ENFORCE_TLS  "smtpd_enforce_tls"
7742 +#define DEF_SMTPD_ENFORCE_TLS  0
7743 +extern bool var_smtpd_enforce_tls;
7744 +
7745 +#define VAR_SMTPD_TLS_ACERT    "smtpd_tls_ask_ccert"
7746 +#define DEF_SMTPD_TLS_ACERT    0
7747 +extern bool var_smtpd_tls_ask_ccert;
7748 +
7749 +#define VAR_SMTPD_TLS_RCERT    "smtpd_tls_req_ccert"
7750 +#define DEF_SMTPD_TLS_RCERT    0
7751 +extern bool var_smtpd_tls_req_ccert;
7752 +
7753 +#define VAR_SMTPD_TLS_CCERT_VD "smtpd_tls_ccert_verifydepth"
7754 +#define DEF_SMTPD_TLS_CCERT_VD 5
7755 +extern int var_smtpd_tls_ccert_vd;
7756 +
7757 +#define VAR_SMTPD_TLS_CERT_FILE        "smtpd_tls_cert_file"
7758 +#define DEF_SMTPD_TLS_CERT_FILE        ""
7759 +extern char *var_smtpd_tls_cert_file;
7760 +
7761 +#define VAR_SMTPD_TLS_KEY_FILE "smtpd_tls_key_file"
7762 +#define DEF_SMTPD_TLS_KEY_FILE "$smtpd_tls_cert_file"
7763 +extern char *var_smtpd_tls_key_file;
7764 +
7765 +#define VAR_SMTPD_TLS_DCERT_FILE "smtpd_tls_dcert_file"
7766 +#define DEF_SMTPD_TLS_DCERT_FILE ""
7767 +extern char *var_smtpd_tls_dcert_file;
7768 +
7769 +#define VAR_SMTPD_TLS_DKEY_FILE        "smtpd_tls_dkey_file"
7770 +#define DEF_SMTPD_TLS_DKEY_FILE        "$smtpd_tls_dcert_file"
7771 +extern char *var_smtpd_tls_dkey_file;
7772 +
7773 +#define VAR_SMTPD_TLS_CA_FILE  "smtpd_tls_CAfile"
7774 +#define DEF_SMTPD_TLS_CA_FILE  ""
7775 +extern char *var_smtpd_tls_CAfile;
7776 +
7777 +#define VAR_SMTPD_TLS_CA_PATH  "smtpd_tls_CApath"
7778 +#define DEF_SMTPD_TLS_CA_PATH  ""
7779 +extern char *var_smtpd_tls_CApath;
7780 +
7781 +#define VAR_SMTPD_TLS_CLIST    "smtpd_tls_cipherlist"
7782 +#define DEF_SMTPD_TLS_CLIST    ""
7783 +extern char *var_smtpd_tls_cipherlist;
7784 +
7785 +#define VAR_SMTPD_TLS_512_FILE "smtpd_tls_dh512_param_file"
7786 +#define DEF_SMTPD_TLS_512_FILE ""
7787 +extern char *var_smtpd_tls_dh512_param_file;
7788 +
7789 +#define VAR_SMTPD_TLS_1024_FILE        "smtpd_tls_dh1024_param_file"
7790 +#define DEF_SMTPD_TLS_1024_FILE        ""
7791 +extern char *var_smtpd_tls_dh1024_param_file;
7792 +
7793 +#define VAR_SMTPD_TLS_LOGLEVEL "smtpd_tls_loglevel"
7794 +#define DEF_SMTPD_TLS_LOGLEVEL 0
7795 +extern int var_smtpd_tls_loglevel;
7796 +
7797 +#define VAR_SMTPD_TLS_RECHEAD  "smtpd_tls_received_header"
7798 +#define DEF_SMTPD_TLS_RECHEAD  0
7799 +extern bool var_smtpd_tls_received_header;
7800 +
7801 +#define VAR_SMTPD_TLS_SCACHE_DB        "smtpd_tls_session_cache_database"
7802 +#define DEF_SMTPD_TLS_SCACHE_DB        ""
7803 +extern char *var_smtpd_tls_scache_db;
7804 +
7805 +#define VAR_SMTPD_TLS_SCACHTIME        "smtpd_tls_session_cache_timeout"
7806 +#define DEF_SMTPD_TLS_SCACHTIME        "3600s"
7807 +extern int var_smtpd_tls_scache_timeout;
7808 +
7809 +#define VAR_SMTP_TLS_PER_SITE  "smtp_tls_per_site"
7810 +#define DEF_SMTP_TLS_PER_SITE  ""
7811 +extern char *var_smtp_tls_per_site;
7812 +
7813 +#define VAR_SMTP_USE_TLS       "smtp_use_tls"
7814 +#define DEF_SMTP_USE_TLS       0
7815 +extern bool var_smtp_use_tls;
7816 +
7817 +#define VAR_SMTP_ENFORCE_TLS   "smtp_enforce_tls"
7818 +#define DEF_SMTP_ENFORCE_TLS   0
7819 +extern bool var_smtp_enforce_tls;
7820 +
7821 +#define VAR_SMTP_TLS_ENFORCE_PN        "smtp_tls_enforce_peername"
7822 +#define DEF_SMTP_TLS_ENFORCE_PN        1
7823 +extern bool var_smtp_tls_enforce_peername;
7824 +
7825 +#define VAR_SMTP_TLS_SCERT_VD  "smtp_tls_scert_verifydepth"
7826 +#define DEF_SMTP_TLS_SCERT_VD  5
7827 +extern int var_smtp_tls_scert_vd;
7828 +
7829 +#define VAR_SMTP_TLS_CERT_FILE "smtp_tls_cert_file"
7830 +#define DEF_SMTP_TLS_CERT_FILE ""
7831 +extern char *var_smtp_tls_cert_file;
7832 +
7833 +#define VAR_SMTP_TLS_KEY_FILE  "smtp_tls_key_file"
7834 +#define DEF_SMTP_TLS_KEY_FILE  "$smtp_tls_cert_file"
7835 +extern char *var_smtp_tls_key_file;
7836 +
7837 +#define VAR_SMTP_TLS_DCERT_FILE "smtp_tls_dcert_file"
7838 +#define DEF_SMTP_TLS_DCERT_FILE ""
7839 +extern char *var_smtp_tls_dcert_file;
7840 +
7841 +#define VAR_SMTP_TLS_DKEY_FILE "smtp_tls_dkey_file"
7842 +#define DEF_SMTP_TLS_DKEY_FILE "$smtp_tls_dcert_file"
7843 +extern char *var_smtp_tls_dkey_file;
7844 +
7845 +#define VAR_SMTP_TLS_CA_FILE   "smtp_tls_CAfile"
7846 +#define DEF_SMTP_TLS_CA_FILE   ""
7847 +extern char *var_smtp_tls_CAfile;
7848 +
7849 +#define VAR_SMTP_TLS_CA_PATH   "smtp_tls_CApath"
7850 +#define DEF_SMTP_TLS_CA_PATH   ""
7851 +extern char *var_smtp_tls_CApath;
7852 +
7853 +#define VAR_SMTP_TLS_CLIST     "smtp_tls_cipherlist"
7854 +#define DEF_SMTP_TLS_CLIST     ""
7855 +extern char *var_smtp_tls_cipherlist;
7856 +
7857 +#define VAR_SMTP_TLS_LOGLEVEL  "smtp_tls_loglevel"
7858 +#define DEF_SMTP_TLS_LOGLEVEL  0
7859 +extern int var_smtp_tls_loglevel;
7860 +
7861 +#define VAR_SMTP_TLS_NOTEOFFER "smtp_tls_note_starttls_offer"
7862 +#define DEF_SMTP_TLS_NOTEOFFER 0
7863 +extern bool var_smtp_tls_note_starttls_offer;
7864 +
7865 +#define VAR_SMTP_TLS_SCACHE_DB "smtp_tls_session_cache_database"
7866 +#define DEF_SMTP_TLS_SCACHE_DB ""
7867 +extern char *var_smtp_tls_scache_db;
7868 +
7869 +#define VAR_SMTP_TLS_SCACHTIME "smtp_tls_session_cache_timeout"
7870 +#define DEF_SMTP_TLS_SCACHTIME "3600s"
7871 +extern int var_smtp_tls_scache_timeout;
7872 +
7873   /*
7874    * SASL authentication support, SMTP server side.
7875    */
7876 @@ -1007,6 +1187,10 @@
7877  #define DEF_RELAY_DOMAINS      "$mydestination"
7878  extern char *var_relay_domains;
7879  
7880 +#define VAR_RELAY_CCERTS       "relay_clientcerts"
7881 +#define DEF_RELAY_CCERTS       ""
7882 +extern char *var_relay_ccerts;
7883 +
7884  #define VAR_CLIENT_CHECKS      "smtpd_client_restrictions"
7885  #define DEF_CLIENT_CHECKS      ""
7886  extern char *var_client_checks;
7887 @@ -1086,6 +1270,8 @@
7888  #define PERMIT_AUTH_DEST       "permit_auth_destination"
7889  #define REJECT_UNAUTH_DEST     "reject_unauth_destination"
7890  #define CHECK_RELAY_DOMAINS    "check_relay_domains"
7891 +#define PERMIT_TLS_CLIENTCERTS "permit_tls_clientcerts"
7892 +#define PERMIT_TLS_ALL_CLIENTCERTS     "permit_tls_all_clientcerts"
7893  #define VAR_RELAY_CODE         "relay_domains_reject_code"
7894  #define DEF_RELAY_CODE         554
7895  extern int var_relay_code;
7896 diff -Nur snapshot-20010228-orig/src/global/mail_proto.h snapshot-20010228/src/global/mail_proto.h
7897 --- snapshot-20010228-orig/src/global/mail_proto.h      Wed Mar 21 13:26:24 2001
7898 +++ snapshot-20010228/src/global/mail_proto.h   Wed Mar 21 13:32:23 2001
7899 @@ -33,6 +33,7 @@
7900  #define MAIL_SERVICE_LOCAL     "local"
7901  #define MAIL_SERVICE_PICKUP    "pickup"
7902  #define MAIL_SERVICE_QUEUE     "qmgr"
7903 +#define MAIL_SERVICE_TLSMGR    "tlsmgr"
7904  #define MAIL_SERVICE_RESOLVE   "resolve"
7905  #define MAIL_SERVICE_REWRITE   "rewrite"
7906  #define MAIL_SERVICE_VIRTUAL   "virtual"
7907 diff -Nur snapshot-20010228-orig/src/global/pfixtls.c snapshot-20010228/src/global/pfixtls.c
7908 --- snapshot-20010228-orig/src/global/pfixtls.c Thu Jan  1 01:00:00 1970
7909 +++ snapshot-20010228/src/global/pfixtls.c      Wed Mar 21 13:32:23 2001
7910 @@ -0,0 +1,2786 @@
7911 +/*++
7912 +/* NAME
7913 +/*     pfixtls
7914 +/* SUMMARY
7915 +/*     interface to openssl routines
7916 +/* SYNOPSIS
7917 +/*     #include <pfixtls.h>
7918 +/*
7919 +/*     const long scache_db_version;
7920 +/*     const long openssl_version;
7921 +/*
7922 +/*     int pfixtls_serverengine;
7923 +/*     int pfixtls_serveractive;
7924 +/*     int pfixtls_peer_verified;
7925 +/*     char *pfixtls_peer_subject;
7926 +/*     char *pfixtls_peer_issuer;
7927 +/*     char *pfixtls_peer_fingerprint;
7928 +/*
7929 +/*     int pfixtls_clientengine;
7930 +/*     int pfixtls_clientactive;
7931 +/*
7932 +/*     char *pfixtls_peer_CN;
7933 +/*     char *pfixtls_issuer_CN;
7934 +/*     char *pfixtls_protocol;
7935 +/*     const char *pfixtls_cipher_name;
7936 +/*     int pfixtls_cipher_usebits;
7937 +/*     int pfixtls_cipher_algbits;
7938 +/*
7939 +/*     int pfixtls_timed_read(fd, buf, len, timeout, unused_context)
7940 +/*     int fd;
7941 +/*     void *buf;
7942 +/*     unsigned len;
7943 +/*     int timeout;
7944 +/*     void *context;
7945 +/*
7946 +/*     int pfixtls_timed_write(fd, buf, len, timeout, unused_context);
7947 +/*     int fd;
7948 +/*     void *buf;
7949 +/*     unsigned len;
7950 +/*     int timeout;
7951 +/*     void *context;
7952 +/*
7953 +/*     int pfixtls_init_serverengine(verifydepth, askcert);
7954 +/*     int verifydepth;
7955 +/*     int askcert;
7956 +/*
7957 +/*     int pfixtls_start_servertls(stream, timeout, peername, peeraddr,
7958 +/*                                 tls_info, requirecert);
7959 +/*     VSTREAM *stream;
7960 +/*     int timeout;
7961 +/*     const char *peername;
7962 +/*     const char *peeraddr;
7963 +/*     tls_info_t *tls_info;
7964 +/*     int requirecert;
7965 +/*
7966 +/*     int pfixtls_stop_servertls(stream, failure, tls_info);
7967 +/*     VSTREAM *stream;
7968 +/*     int failure;
7969 +/*     tls_info_t *tls_info;
7970 +/*     
7971 +/*     int pfixtls_init_clientengine(verifydepth);
7972 +/*     int verifydepth;
7973 +/*
7974 +/*     int pfixtls_start_clienttls(stream, timeout, peername, peeraddr,
7975 +/*                                 tls_info);
7976 +/*     VSTREAM *stream;
7977 +/*     int timeout;
7978 +/*     const char *peername;
7979 +/*     const char *peeraddr;
7980 +/*     tls_info_t *tls_info;
7981 +/*
7982 +/*     int pfixtls_stop_clienttls(stream, failure, tls_info);
7983 +/*     VSTREAM *stream;
7984 +/*     int failure;
7985 +/*     tls_info_t *tls_info;
7986 +/*
7987 +/* DESCRIPTION
7988 +/*     This module is the interface between Postfix and the OpenSSL library.
7989 +/*
7990 +/*     pfixtls_timed_read() reads the requested number of bytes calling
7991 +/*     SSL_read(). pfixtls_time_read() will only be called indirect
7992 +/*     as a VSTREAM_FN function.
7993 +/*     pfixtls_timed_write() is the corresponding write function.
7994 +/*
7995 +/*     pfixtls_init_serverengine() is called once when smtpd is started
7996 +/*     in order to initialize as much of the TLS stuff as possible.
7997 +/*     The certificate handling is also decided during the setup phase,
7998 +/*     so that a peer specific handling is not possible.
7999 +/*
8000 +/*     pfixtls_init_clientengine() is the corresponding function called
8001 +/*     in smtp. Here we take the peer's (server's) certificate in any
8002 +/*     case.
8003 +/*
8004 +/*     pfixtls_start_servertls() activates the TLS feature for the VSTREAM
8005 +/*     passed as argument. We expect that all buffers are flushed and the
8006 +/*     TLS handshake can begin immediately. Information about the peer
8007 +/*     is stored into the tls_info structure passed as argument.
8008 +/*
8009 +/*     pfixtls_stop_servertls() sends the "close notify" alert via
8010 +/*     SSL_shutdown() to the peer and resets all connection specific
8011 +/*     TLS data. As RFC2487 does not specify a seperate shutdown, it
8012 +/*     is supposed that the underlying TCP connection is shut down
8013 +/*     immediately afterwards, so we don't care about additional data
8014 +/*     coming through the channel.
8015 +/*     If the failure flag is set, the session is cleared from the cache.
8016 +/*
8017 +/*     pfixtls_start_clienttls() and pfixtls_stop_clienttls() are the
8018 +/*     corresponding functions for smtp.
8019 +/*
8020 +/*     Once the TLS connection is initiated, information about the TLS
8021 +/*     state is available via the tls_info structure:
8022 +/*     protocol holds the protocol name (SSLv2, SSLv3, TLSv1),
8023 +/*     tls_info->cipher_name the cipher name (e.g. RC4/MD5),
8024 +/*     tls_info->cipher_usebits the number of bits actually used (e.g. 40),
8025 +/*     tls_info->cipher_algbits the number of bits the algorithm is based on
8026 +/*     (e.g. 128).
8027 +/*     The last two values may be different when talking to a crippled
8028 +/*     - ahem - export controled peer (e.g. 40/128).
8029 +/*
8030 +/*     The status of the peer certificate verification is available in
8031 +/*     pfixtls_peer_verified. It is set to 1, when the certificate could
8032 +/*     be verified.
8033 +/*     If the peer offered a certifcate, part of the certificate data are
8034 +/*     available as:
8035 +/*     tls_info->peer_subject X509v3-oneline with the DN of the peer
8036 +/*     tls_info->peer_CN extracted CommonName of the peer
8037 +/*     tls_info->peer_issuer  X509v3-oneline with the DN of the issuer
8038 +/*     tls_info->peer_CN extracted CommonName of the issuer
8039 +/*     tls_info->PEER_FINGERPRINT fingerprint of the certificate
8040 +/*
8041 +/* DESCRIPTION (SESSION CACHING)
8042 +/*     In order to achieve high performance when using a lot of connections
8043 +/*     with TLS, session caching is implemented. It reduces both the CPU load
8044 +/*     (less cryptograpic operations) and the network load (the amount of
8045 +/*     certificate data exchanged is reduced).
8046 +/*     Since postfix uses a setup of independent processes for receiving
8047 +/*     and sending email, the processes must exchange the session information.
8048 +/*     Several connections at the same time between the identical peers can
8049 +/*     occur, so uniqueness and race conditions have to be taken into
8050 +/*     account.
8051 +/*     I have checked both Apache-SSL (Ben Laurie), using a seperate "gcache"
8052 +/*     process and Apache mod_ssl (Ralf S. Engelshall), using shared memory
8053 +/*     between several identical processes spawned from one parent.
8054 +/*
8055 +/*     Postfix/TLS uses a database approach based on the internal "dict"
8056 +/*     interface. Since the session cache information is approximately
8057 +/*     1300 bytes binary data, it will not fit into the dbm/ndbm model.
8058 +/*     It also needs write access to the database, ruling out most other
8059 +/*     interface, leaving Berkeley DB, which however cannot handle concurrent
8060 +/*     access by several processes. Hence a modified SDBM (public domain DBM)
8061 +/*     with enhanced buffer size is used and concurrent write capability
8062 +/*     is used. SDBM is part of Postfix/TLS.
8063 +/*
8064 +/*     Realization:
8065 +/*     Both (client and server) session cache are realized by individual
8066 +/*     cache databases. A common database would not make sense, since the
8067 +/*     key criteria are different (session ID for server, peername for
8068 +/*     client).
8069 +/*
8070 +/*     Server side:
8071 +/*     Session created by OpenSSL have a 32 byte session id, yielding a
8072 +/*     64 char file name. I consider these sessions to be unique. If they
8073 +/*     are not, the last session will win, overwriting the older one in
8074 +/*     the database. Remember: everything that is lost is a temporary
8075 +/*     information and not more than a renegotiation will happen.
8076 +/*     Originating from the same client host, several sessions can come
8077 +/*     in (e.g. from several users sending mail with Netscape at the same
8078 +/*     time), so the session id is the correct identifier; the hostname
8079 +/*     is of no importance, here.
8080 +/*
8081 +/*     Client side:
8082 +/*     We cannot recall sessions based on their session id, because we would
8083 +/*     have to check every session on disk for a matching server name, so
8084 +/*     the lookup has to be done based on the FQDN of the peer (receiving
8085 +/*     host).
8086 +/*     With regard to uniqueness, we might experience several open connections
8087 +/*     to the same server at the same time. This is even very likely to
8088 +/*     happen, since we might have several mails for the same destination
8089 +/*     in the queue, when a queue run is started. So several smtp´s might
8090 +/*     negotiate sessions at the same time. We can however only save one
8091 +/*     session for one host.
8092 +/*     Like on the server side, the "last write" wins. The reason is
8093 +/*     quite simple. If we don´t want to overwrite old sessions, an old
8094 +/*     session file will just stay in place until it is expired. In the
8095 +/*     meantime we would lose "fresh" session however. So we will keep the
8096 +/*     fresh one instead to avoid unnecessary renegotiations.
8097 +/*
8098 +/*     Session lifetime:
8099 +/*     RFC2246 recommends a session lifetime of less than 24 hours. The
8100 +/*     default is 300 seconds (5 minutes) for OpenSSL and is also used
8101 +/*     this way in e.g. mod_ssl. The typical usage for emails might be
8102 +/*     humans typing in emails and sending them, which might take just
8103 +/*     a while, so I think 3600 seconds (1 hour) is a good compromise.
8104 +/*     If the environment is save (the cached session contains secret
8105 +/*     key data), one might even consider using a longer timeout. Anyway,
8106 +/*     since everlasting sessions must be avoided, the session timeout
8107 +/*     is done based on the creation date of the session and so each
8108 +/*     session will timeout eventually.
8109 +/*
8110 +/*     Connection failures:
8111 +/*     RFC2246 requires us to remove sessions if something went wrong.
8112 +/*     Since the in-memory session cache of other smtp[d] processes cannot
8113 +/*     be controlled by simple means, we completely rely on the disc
8114 +/*     based session caching and remove all sessions from memory after
8115 +/*     connection closure.
8116 +/*
8117 +/*     Cache cleanup:
8118 +/*     Since old entries have to be removed from the session cache, a
8119 +/*     cleanup process is needed that runs through the collected session
8120 +/*     files on regular basis. The task is performed by tlsmgr based on
8121 +/*     the timestamp created by pfixtls and included in the saved session,
8122 +/*     so that tlsmgr has not to care about the SSL_SESSION internal data.
8123 +/*
8124 +/* BUGS
8125 +/*     The memory allocation policy of the OpenSSL library is not well
8126 +/*     documented, especially when loading sessions from disc. Hence there
8127 +/*     might be memory leaks.
8128 +/*
8129 +/* LICENSE
8130 +/* AUTHOR(S)
8131 +/*     Lutz Jaenicke
8132 +/*     BTU Cottbus
8133 +/*     Allgemeine Elektrotechnik
8134 +/*     Universitaetsplatz 3-4
8135 +/*     D-03044 Cottbus, Germany
8136 +/*--*/
8137 +
8138 +/* System library. */
8139 +
8140 +#include <sys_defs.h>
8141 +#include <sys/types.h>
8142 +#include <sys/stat.h>
8143 +#include <sys/time.h>                  /* gettimeofday, not in POSIX */
8144 +#include <unistd.h>
8145 +#include <stdio.h>
8146 +#include <string.h>
8147 +#include <errno.h>
8148 +
8149 +/* Utility library. */
8150 +
8151 +#include <iostuff.h>
8152 +#include <mymalloc.h>
8153 +#include <vstring.h>
8154 +#include <vstream.h>
8155 +#include <dict.h>
8156 +#include <myflock.h>
8157 +#include <stringops.h>
8158 +
8159 +/* Application-specific. */
8160 +
8161 +#include "mail_params.h"
8162 +#include "pfixtls.h"
8163 +
8164 +#define STR    vstring_str
8165 +
8166 +const tls_info_t tls_info_zero = {
8167 +    0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0
8168 +};
8169 +
8170 +#ifdef HAS_SSL
8171 +
8172 +/* OpenSSL library. */
8173 +
8174 +#include <openssl/lhash.h>
8175 +#include <openssl/bn.h>
8176 +#include <openssl/err.h>
8177 +#include <openssl/pem.h>
8178 +#include <openssl/x509.h>
8179 +#include <openssl/ssl.h>
8180 +
8181 +/* We must keep some of the info available */
8182 +static const char hexcodes[] = "0123456789ABCDEF";
8183 +
8184 +/*
8185 + * When saving sessions, we want to make sure, that the lenght of the key
8186 + * is somehow limited. When saving client sessions, the hostname
8187 + * can be up to 64 bytes long.
8188 + * The length of the actual session id is however not defined in RFC2246.
8189 + * OpenSSL defines a SSL_MAX_SSL_SESSION_ID_LENGTH of 32, but nobody
8190 + * guarantees, that a client might not try to resume a session with a longer
8191 + * session id. So to make sure, we define an upper bound of 64.
8192 + */
8193 +static const int id_maxlength = 64;    /* Max ID length in bytes */
8194 +
8195 +/*
8196 + * The session_id_context is set, such that the client knows which services
8197 + * on a host share the same session information (on the postfix host may
8198 + * as well run a TLS-enabled webserver.
8199 + */
8200 +static char server_session_id_context[] = "Postfix/TLS"; /* anything will do */
8201 +static int TLScontext_index = -1;
8202 +static int do_dump = 0;
8203 +static DH *dh_512 = NULL, *dh_1024 = NULL;
8204 +static SSL_CTX *ctx = NULL;
8205 +
8206 +static rand_exch_fd = -1;
8207 +
8208 +static DICT *scache_db = NULL;
8209 +const long scache_db_version = 0x00000002L;
8210 +const long openssl_version = OPENSSL_VERSION_NUMBER;
8211 +
8212 +
8213 +int     pfixtls_serverengine = 0;
8214 +static int pfixtls_serveractive = 0;   /* available or not */
8215 +
8216 +int     pfixtls_clientengine = 0;
8217 +static int pfixtls_clientactive = 0;   /* available or not */
8218 +
8219 +/*
8220 + * Define a maxlength for certificate onelines. The length is checked by
8221 + * all routines when copying.
8222 + */
8223 +#define CCERT_BUFSIZ 256
8224 +
8225 +typedef struct {
8226 +  SSL *con;
8227 +  BIO *internal_bio;                   /* postfix/TLS side of pair */
8228 +  BIO *network_bio;                    /* netsork side of pair */
8229 +  char peer_subject[CCERT_BUFSIZ];
8230 +  char peer_issuer[CCERT_BUFSIZ];
8231 +  char peer_CN[CCERT_BUFSIZ];
8232 +  char issuer_CN[CCERT_BUFSIZ];
8233 +  unsigned char md[EVP_MAX_MD_SIZE];
8234 +  char fingerprint[EVP_MAX_MD_SIZE * 3];
8235 +  char peername_save[129];
8236 +  int enforce_verify_errors;
8237 +  int enforce_CN;
8238 +} TLScontext_t;
8239 +
8240 +typedef struct {
8241 +    int pid;
8242 +    struct timeval tv;
8243 +} randseed_t;
8244 +
8245 +static randseed_t randseed;
8246 +static struct stat seedfile_stat;
8247 +
8248 +/*
8249 + * Finally some "backup" DH-Parameters to be loaded, if no parameters are
8250 + * explicitely loaded from file.
8251 + */
8252 +static unsigned char dh512_p[] = {
8253 +    0x88, 0x3F, 0x00, 0xAF, 0xFC, 0x0C, 0x8A, 0xB8, 0x35, 0xCD, 0xE5, 0xC2,
8254 +    0x0F, 0x55, 0xDF, 0x06, 0x3F, 0x16, 0x07, 0xBF, 0xCE, 0x13, 0x35, 0xE4,
8255 +    0x1C, 0x1E, 0x03, 0xF3, 0xAB, 0x17, 0xF6, 0x63, 0x50, 0x63, 0x67, 0x3E,
8256 +    0x10, 0xD7, 0x3E, 0xB4, 0xEB, 0x46, 0x8C, 0x40, 0x50, 0xE6, 0x91, 0xA5,
8257 +    0x6E, 0x01, 0x45, 0xDE, 0xC9, 0xB1, 0x1F, 0x64, 0x54, 0xFA, 0xD9, 0xAB,
8258 +    0x4F, 0x70, 0xBA, 0x5B,
8259 +};
8260 +
8261 +static unsigned char dh512_g[] = {
8262 +    0x02,
8263 +};
8264 +
8265 +static unsigned char dh1024_p[] = {
8266 +    0xB0, 0xFE, 0xB4, 0xCF, 0xD4, 0x55, 0x07, 0xE7, 0xCC, 0x88, 0x59, 0x0D,
8267 +    0x17, 0x26, 0xC5, 0x0C, 0xA5, 0x4A, 0x92, 0x23, 0x81, 0x78, 0xDA, 0x88,
8268 +    0xAA, 0x4C, 0x13, 0x06, 0xBF, 0x5D, 0x2F, 0x9E, 0xBC, 0x96, 0xB8, 0x51,
8269 +    0x00, 0x9D, 0x0C, 0x0D, 0x75, 0xAD, 0xFD, 0x3B, 0xB1, 0x7E, 0x71, 0x4F,
8270 +    0x3F, 0x91, 0x54, 0x14, 0x44, 0xB8, 0x30, 0x25, 0x1C, 0xEB, 0xDF, 0x72,
8271 +    0x9C, 0x4C, 0xF1, 0x89, 0x0D, 0x68, 0x3F, 0x94, 0x8E, 0xA4, 0xFB, 0x76,
8272 +    0x89, 0x18, 0xB2, 0x91, 0x16, 0x90, 0x01, 0x99, 0x66, 0x8C, 0x53, 0x81,
8273 +    0x4E, 0x27, 0x3D, 0x99, 0xE7, 0x5A, 0x7A, 0xAF, 0xD5, 0xEC, 0xE2, 0x7E,
8274 +    0xFA, 0xED, 0x01, 0x18, 0xC2, 0x78, 0x25, 0x59, 0x06, 0x5C, 0x39, 0xF6,
8275 +    0xCD, 0x49, 0x54, 0xAF, 0xC1, 0xB1, 0xEA, 0x4A, 0xF9, 0x53, 0xD0, 0xDF,
8276 +    0x6D, 0xAF, 0xD4, 0x93, 0xE7, 0xBA, 0xAE, 0x9B,
8277 +};
8278 +
8279 +static unsigned char dh1024_g[] = {
8280 +    0x02,
8281 +};
8282 +
8283 +/*
8284 + * DESCRIPTION: Keeping control of the network interface using BIO-pairs.
8285 + *
8286 + * When the TLS layer is active, all input/output must be filtered through
8287 + * it. On the other hand to handle timeout conditions, full control over
8288 + * the network socket must be kept. This rules out the "normal way" of
8289 + * connecting the TLS layer directly to the socket.
8290 + * The TLS layer is realized with a BIO-pair:
8291 + *
8292 + *     postfix  |   TLS-engine
8293 + *       |      |
8294 + *       +--------> SSL_operations()
8295 + *              |     /\    ||
8296 + *              |     ||    \/
8297 + *              |   BIO-pair (internal_bio)
8298 + *       +--------< BIO-pair (network_bio)
8299 + *       |      |
8300 + *     socket   |
8301 + *
8302 + * The normal postfix operations connect to the SSL operations to send
8303 + * and retrieve (cleartext) data. Inside the TLS-engine the data are converted
8304 + * to/from TLS protocol. The TLS functionality itself is only connected to
8305 + * the internal_bio and hence only has status information about this internal
8306 + * interface.
8307 + * Thus, if the SSL_operations() return successfully (SSL_ERROR_NONE) or want
8308 + * to read (SSL_ERROR_WANT_READ) there may as well be data inside the buffering
8309 + * BIO-pair. So whenever an SSL_operation() returns without a fatal error,
8310 + * the BIO-pair internal buffer must be flushed to the network.
8311 + * NOTE: This is especially true in the SSL_ERROR_WANT_READ case: the TLS-layer
8312 + * might want to read handshake data, that will never come since its own
8313 + * written data will only reach the peer after flushing the buffer!
8314 + *
8315 + * The BIO-pair buffer size has been set to 8192 bytes, this is an arbitrary
8316 + * value that can hold more data than the typical PMTU, so that it does
8317 + * not force the generation of packets smaller than necessary.
8318 + * It is also larger than the default VSTREAM_BUFSIZE (4096, see vstream.h),
8319 + * so that large write operations could be handled within one call.
8320 + * The internal buffer in the network/network_bio handling layer has been
8321 + * set to the same value, since this seems to be reasonable. The code is
8322 + * however able to handle arbitrary values smaller or larger than the
8323 + * buffer size in the BIO-pair.
8324 + */
8325 +
8326 +const ssize_t BIO_bufsiz = 8192;
8327 +
8328 +/*
8329 + * The interface layer between network and BIO-pair. The BIO-pair buffers
8330 + * the data to/from the TLS layer. Hence, at any time, there may be data
8331 + * in the buffer that must be written to the network. This writing has
8332 + * highest priority because the handshake might fail otherwise.
8333 + * Only then a read_request can be satisfied.
8334 + */
8335 +static int network_biopair_interop(int fd, int timeout, BIO *network_bio)
8336 +{
8337 +    int want_write;
8338 +    int num_write;
8339 +    int write_pos;
8340 +    int from_bio;
8341 +    int want_read;
8342 +    int num_read;
8343 +    int to_bio;
8344 +#define NETLAYER_BUFFERSIZE 8192
8345 +    char buffer[8192];
8346 +
8347 +    while ((want_write = BIO_ctrl_pending(network_bio)) > 0) {
8348 +       if (want_write > NETLAYER_BUFFERSIZE)
8349 +           want_write = NETLAYER_BUFFERSIZE;
8350 +       from_bio = BIO_read(network_bio, buffer, want_write);
8351 +
8352 +       /*
8353 +        * Write the complete contents of the buffer. Since TLS performs
8354 +        * underlying handshaking, we cannot afford to leave the buffer
8355 +        * unflushed, as we could run into a deadlock trap (the peer
8356 +        * waiting for a final byte and we already waiting for his reply
8357 +        * in read position).
8358 +        */
8359 +        write_pos = 0;
8360 +       do {
8361 +           if (timeout > 0 && write_wait(fd, timeout) < 0)
8362 +               return (-1);
8363 +           num_write = write(fd, buffer + write_pos, from_bio - write_pos);
8364 +           if (num_write <= 0)
8365 +               return (-1);    /* something happened to the socket */
8366 +           write_pos += num_write;
8367 +       } while (write_pos < from_bio);
8368 +   }
8369 +
8370 +   while ((want_read = BIO_ctrl_get_read_request(network_bio)) > 0) {
8371 +       if (want_read > NETLAYER_BUFFERSIZE)
8372 +           want_read = NETLAYER_BUFFERSIZE;
8373 +       if (timeout > 0 && read_wait(fd, timeout) < 0)
8374 +           return (-1);
8375 +       num_read = read(fd, buffer, want_read);
8376 +       if (num_read <= 0)
8377 +           return (-1);        /* something happened to the socket */
8378 +       to_bio = BIO_write(network_bio, buffer, num_read);
8379 +       if (to_bio != num_read)
8380 +               msg_fatal("to_bio != num_read");
8381 +    }
8382 +
8383 +    return (0);
8384 +}
8385 +
8386 +static void pfixtls_print_errors(void);
8387 +
8388 + /*
8389 +  * Function to perform the handshake for SSL_accept(), SSL_connect(),
8390 +  * and SSL_shutdown() and perform the SSL_read(), SSL_write() operations.
8391 +  * Call the underlying network_biopair_interop-layer to make sure the
8392 +  * write buffer is flushed after every operation (that did not fail with
8393 +  * a fatal error).
8394 +  */
8395 +static int do_tls_operation(int fd, int timeout, TLScontext_t *TLScontext,
8396 +                       int (*hsfunc)(SSL *),
8397 +                       int (*rfunc)(SSL *, char *, int),
8398 +                       int (*wfunc)(SSL *, const char *, int),
8399 +                       char *buf, int num)
8400 +{
8401 +    int status;
8402 +    int err;
8403 +    int retval;
8404 +    int biop_retval;
8405 +    int done = 0;
8406 +
8407 +    while (!done) {
8408 +       if (hsfunc)
8409 +           status = hsfunc(TLScontext->con);
8410 +       else if (rfunc)
8411 +           status = rfunc(TLScontext->con, buf, num);
8412 +       else
8413 +           status = wfunc(TLScontext->con, (const char *)buf, num);
8414 +       err = SSL_get_error(TLScontext->con, status);
8415 +
8416 +#if (OPENSSL_VERSION_NUMBER <= 0x0090581fL)
8417 +       /*
8418 +        * There is a bug up to and including OpenSSL-0.9.5a: if an error
8419 +        * occurs while checking the peers certificate due to some certificate
8420 +        * error (e.g. as happend with a RSA-padding error), the error is put
8421 +        * onto the error stack. If verification is not enforced, this error
8422 +        * should be ignored, but the error-queue is not cleared, so we
8423 +        * can find this error here. The bug has been fixed on May 28, 2000.
8424 +        *
8425 +        * This bug so far has only manifested as
8426 +        * 4800:error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01:rsa_pk1.c:100:
8427 +        * 4800:error:04067072:rsa routines:RSA_EAY_PUBLIC_DECRYPT:padding check failed:rsa_eay.c:396:
8428 +        * 4800:error:0D079006:asn1 encoding routines:ASN1_verify:bad get asn1 object call:a_verify.c:109:
8429 +        * so that we specifically test for this error. We print the errors
8430 +        * to the logfile and automatically clear the error queue. Then we
8431 +        * retry to get another error code. We cannot do better, since we
8432 +        * can only retrieve the last entry of the error-queue without
8433 +        * actually cleaning it on the way.
8434 +        *
8435 +        * This workaround is secure, as verify_result is set to "failed"
8436 +        * anyway.
8437 +        */
8438 +       if (err == SSL_ERROR_SSL) {
8439 +           if (ERR_peek_error() == 0x0407006AL) {
8440 +               pfixtls_print_errors(); /* Keep information for the logfile */
8441 +               msg_info("OpenSSL <= 0.9.5a workaround called: certificate errors ignored");
8442 +               err = SSL_get_error(TLScontext->con, status);
8443 +           }
8444 +       }
8445 +#endif
8446 +
8447 +       switch (err) {
8448 +       case SSL_ERROR_NONE:            /* success */
8449 +           retval = status;
8450 +           done = 1;                   /* no break, flush buffer before */
8451 +                                       /* leaving */
8452 +       case SSL_ERROR_WANT_WRITE:
8453 +       case SSL_ERROR_WANT_READ:
8454 +           biop_retval = network_biopair_interop(fd, timeout,
8455 +               TLScontext->network_bio);
8456 +           if (biop_retval < 0)
8457 +               return (-1);            /* fatal network error */
8458 +           break;
8459 +       case SSL_ERROR_ZERO_RETURN:     /* connection was closed cleanly */
8460 +       case SSL_ERROR_SYSCALL:         
8461 +       case SSL_ERROR_SSL:
8462 +       default:
8463 +           retval = status;
8464 +           done = 1;
8465 +           ;
8466 +       }
8467 +    };
8468 +    return retval;
8469 +}
8470 +
8471 +int pfixtls_timed_read(int fd, void *buf, unsigned buf_len, int timeout, 
8472 +                      void *context)
8473 +{
8474 +    int     i;
8475 +    int     ret;
8476 +    char    mybuf[40];
8477 +    char   *mybuf2;
8478 +    TLScontext_t *TLScontext;
8479 +
8480 +    TLScontext = (TLScontext_t *)context;
8481 +    if (!TLScontext)
8482 +      msg_fatal("Called tls_timed_read() without TLS-context");
8483
8484 +    ret = do_tls_operation(fd, timeout, TLScontext, NULL, SSL_read, NULL,
8485 +                         (char *)buf, buf_len);
8486 +    if ((pfixtls_serveractive && var_smtpd_tls_loglevel >= 4) ||
8487 +        (pfixtls_clientactive && var_smtp_tls_loglevel >= 4)) {
8488 +       mybuf2 = (char *) buf;
8489 +       if (ret > 0) {
8490 +           i = 0;
8491 +           while ((i < 39) && (i < ret) && (mybuf2[i] != 0)) {
8492 +               mybuf[i] = mybuf2[i];
8493 +               i++;
8494 +           }
8495 +           mybuf[i] = '\0';
8496 +           msg_info("Read %d chars: %s", ret, mybuf);
8497 +       }
8498 +    }
8499 +    return (ret);
8500 +}
8501 +
8502 +int pfixtls_timed_write(int fd, void *buf, unsigned len, int timeout,
8503 +                       void *context)
8504 +{
8505 +    int     i;
8506 +    char    mybuf[40];
8507 +    char   *mybuf2;
8508 +    TLScontext_t *TLScontext;
8509 +
8510 +    TLScontext = (TLScontext_t *)context;
8511 +    if (!TLScontext)
8512 +      msg_fatal("Called tls_timed_write() without TLS-context");
8513 +
8514 +    if ((pfixtls_serveractive && var_smtpd_tls_loglevel >= 4) ||
8515 +       (pfixtls_clientactive && var_smtp_tls_loglevel >= 4)) {
8516 +       mybuf2 = (char *) buf;
8517 +       if (len > 0) {
8518 +           i = 0;
8519 +           while ((i < 39) && (i < len) && (mybuf2[i] != 0)) {
8520 +               mybuf[i] = mybuf2[i];
8521 +               i++;
8522 +           }
8523 +           mybuf[i] = '\0';
8524 +           msg_info("Write %d chars: %s", len, mybuf);
8525 +       }
8526 +    }
8527 +    return (do_tls_operation(fd, timeout, TLScontext, NULL, NULL, SSL_write,
8528 +                            buf, len));
8529 +}
8530 +
8531 +/* Add some more entropy to the pool by adding the actual time */
8532 +
8533 +static void pfixtls_stir_seed(void)
8534 +{
8535 +    GETTIMEOFDAY(&randseed.tv);
8536 +    RAND_seed(&randseed, sizeof(randseed_t));
8537 +}
8538 +
8539 +/*
8540 + * Skeleton taken from OpenSSL crypto/err/err_prn.c.
8541 + * Query the error stack and print the error string into the logging facility.
8542 + * Clear the error stack on the way.
8543 + */
8544 +
8545 +static void pfixtls_print_errors(void)
8546 +{
8547 +    unsigned long l;
8548 +    char    buf[256];
8549 +    const char   *file;
8550 +    const char   *data;
8551 +    int     line;
8552 +    int     flags;
8553 +    unsigned long es;
8554 +
8555 +    es = CRYPTO_thread_id();
8556 +    while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
8557 +       if (flags & ERR_TXT_STRING)
8558 +           msg_info("%lu:%s:%s:%d:%s:", es, ERR_error_string(l, buf),
8559 +                    file, line, data);
8560 +       else
8561 +           msg_info("%lu:%s:%s:%d:", es, ERR_error_string(l, buf),
8562 +                    file, line);
8563 +    }
8564 +}
8565 +
8566 + /*
8567 +  * Set up the cert things on the server side. We do need both the
8568 +  * private key (in key_file) and the cert (in cert_file).
8569 +  * Both files may be identical.
8570 +  *
8571 +  * This function is taken from OpenSSL apps/s_cb.c
8572 +  */
8573 +
8574 +static int set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file)
8575 +{
8576 +    if (cert_file != NULL) {
8577 +       if (SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) {
8578 +           msg_info("unable to get certificate from '%s'", cert_file);
8579 +           pfixtls_print_errors();
8580 +           return (0);
8581 +       }
8582 +       if (key_file == NULL)
8583 +           key_file = cert_file;
8584 +       if (SSL_CTX_use_PrivateKey_file(ctx, key_file,
8585 +                                       SSL_FILETYPE_PEM) <= 0) {
8586 +           msg_info("unable to get private key from '%s'", key_file);
8587 +           pfixtls_print_errors();
8588 +           return (0);
8589 +       }
8590 +       /* Now we know that a key and cert have been set against
8591 +         * the SSL context */
8592 +       if (!SSL_CTX_check_private_key(ctx)) {
8593 +           msg_info("Private key does not match the certificate public key");
8594 +           return (0);
8595 +       }
8596 +    }
8597 +    return (1);
8598 +}
8599 +
8600 +/* taken from OpenSSL apps/s_cb.c */
8601 +
8602 +static RSA *tmp_rsa_cb(SSL * s, int export, int keylength)
8603 +{
8604 +    static RSA *rsa_tmp = NULL;
8605 +
8606 +    if (rsa_tmp == NULL) {
8607 +       rsa_tmp = RSA_generate_key(keylength, RSA_F4, NULL, NULL);
8608 +    }
8609 +    return (rsa_tmp);
8610 +}
8611 +
8612 +
8613 +static DH *get_dh512(void)
8614 +{
8615 +    DH *dh;
8616 +
8617 +    if (dh_512 == NULL) {
8618 +       /* No parameter file loaded, use the compiled in parameters */
8619 +       if ((dh = DH_new()) == NULL) return(NULL);
8620 +       dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
8621 +       dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
8622 +       if ((dh->p == NULL) || (dh->g == NULL))
8623 +           return(NULL);
8624 +       else
8625 +           dh_512 = dh;
8626 +    }
8627 +    return (dh_512);
8628 +}
8629 +
8630 +static DH *get_dh1024(void)
8631 +{
8632 +    DH *dh;
8633 +
8634 +    if (dh_1024 == NULL) {
8635 +       /* No parameter file loaded, use the compiled in parameters */
8636 +       if ((dh = DH_new()) == NULL) return(NULL);
8637 +       dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
8638 +       dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
8639 +       if ((dh->p == NULL) || (dh->g == NULL))
8640 +           return(NULL);
8641 +       else
8642 +           dh_1024 = dh;
8643 +    }
8644 +    return (dh_1024);
8645 +}
8646 +
8647 +/* partly inspired by mod_ssl */
8648 +
8649 +static DH *tmp_dh_cb(SSL *s, int export, int keylength)
8650 +{
8651 +    DH *dh_tmp = NULL;
8652 +   
8653 +    if (export) {
8654 +       if (keylength == 512)
8655 +           dh_tmp = get_dh512();       /* export cipher */
8656 +       else if (keylength == 1024)
8657 +           dh_tmp = get_dh1024();      /* normal */
8658 +       else
8659 +           dh_tmp = get_dh1024();      /* not on-the-fly (too expensive) */
8660 +                                       /* so use the 1024bit instead */
8661 +    }
8662 +    else {
8663 +       dh_tmp = get_dh1024();          /* sign-only certificate */
8664 +    }
8665 +    return (dh_tmp);
8666 +}
8667 +
8668 +
8669 +/*
8670 + * Skeleton taken from OpenSSL apps/s_cb.c
8671 + *
8672 + * The verify_callback is called several times (directly or indirectly) from
8673 + * crypto/x509/x509_vfy.c. It is called as a last check for several issues,
8674 + * so this verify_callback() has the famous "last word". If it does return "0",
8675 + * the handshake is immediately shut down and the connection fails.
8676 + *
8677 + * Postfix/TLS has two modes, the "use" mode and the "enforce" mode:
8678 + *
8679 + * In the "use" mode we never want the connection to fail just because there is
8680 + * something wrong with the certificate (as we would have sent happily without
8681 + * TLS).  Therefore the return value is always "1".
8682 + *
8683 + * In the "enforce" mode we can shut down the connection as soon as possible.
8684 + * In server mode TLS itself may be enforced (e.g. to protect passwords),
8685 + * but certificates are optional. In this case the handshake must not fail
8686 + * if we are unhappy with the certificate and return "1" in any case.
8687 + * Only if a certificate is required the certificate must pass the verification
8688 + * and failure to do so will result in immediate termination (return 0).
8689 + * In the client mode the decision is made with respect to the peername
8690 + * enforcement. If we strictly enforce the matching of the expected peername
8691 + * the verification must fail immediatly on verification errors. We can also
8692 + * immediatly check the expected peername, as it is the CommonName at level 0.
8693 + * In all other cases, the problem is logged, so the SSL_get_verify_result()
8694 + * will inform about the verification failure, but the handshake (and SMTP
8695 + * connection will continue).
8696 + *
8697 + * The only error condition not handled inside the OpenSSL-Library is the
8698 + * case of a too-long certificate chain, so we check inside verify_callback().
8699 + * We only take care of this problem, if "ok = 1", because otherwise the
8700 + * verification already failed because of another problem and we don't want
8701 + * to overwrite the other error message. And if the verification failed,
8702 + * there is no such thing as "more failed", "most failed"... :-)
8703 + */
8704 +
8705 +static int verify_callback(int ok, X509_STORE_CTX * ctx)
8706 +{
8707 +    char    buf[256];
8708 +    char   *CN_lowercase;
8709 +    X509   *err_cert;
8710 +    int     err;
8711 +    int     depth;
8712 +    int     verify_depth;
8713 +    SSL    *con;
8714 +    TLScontext_t *TLScontext;
8715 +
8716 +    err_cert = X509_STORE_CTX_get_current_cert(ctx);
8717 +    err = X509_STORE_CTX_get_error(ctx);
8718 +    depth = X509_STORE_CTX_get_error_depth(ctx);
8719 +
8720 +    con = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
8721 +    TLScontext = SSL_get_ex_data(con, TLScontext_index);
8722 +
8723 +    X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
8724 +    if (((pfixtls_serverengine) && (var_smtpd_tls_loglevel >= 2)) ||
8725 +       ((pfixtls_clientengine) && (var_smtp_tls_loglevel >= 2)))
8726 +       msg_info("Peer cert verify depth=%d %s", depth, buf);
8727 +
8728 +    verify_depth = SSL_get_verify_depth(con);
8729 +    if (ok && (verify_depth >= 0) && (depth > verify_depth)) {
8730 +       ok = 0;
8731 +       err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
8732 +       X509_STORE_CTX_set_error(ctx, err);
8733 +    }
8734 +    if (!ok) {
8735 +       msg_info("verify error:num=%d:%s", err,
8736 +                X509_verify_cert_error_string(err));
8737 +    }
8738 +
8739 +    if (ok && (depth == 0) && TLScontext->enforce_verify_errors
8740 +                          && TLScontext->enforce_CN) {
8741 +       X509_NAME_get_text_by_NID(X509_get_subject_name(err_cert),
8742 +                          NID_commonName, buf, 256);
8743 +       CN_lowercase = lowercase(buf);
8744 +       if (strcmp(TLScontext->peername_save, CN_lowercase)) {
8745 +           err = X509_V_ERR_CERT_REJECTED;
8746 +           X509_STORE_CTX_set_error(ctx, err);
8747 +           msg_info("Verify failure: CommonName in certificate does not match: %s != %s", CN_lowercase, TLScontext->peername_save);
8748 +           ok = 0;
8749 +       }
8750 +    }
8751 +
8752 +    switch (ctx->error) {
8753 +    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
8754 +       X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
8755 +       msg_info("issuer= %s", buf);
8756 +       break;
8757 +    case X509_V_ERR_CERT_NOT_YET_VALID:
8758 +    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
8759 +       msg_info("cert not yet valid");
8760 +       break;
8761 +    case X509_V_ERR_CERT_HAS_EXPIRED:
8762 +    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
8763 +       msg_info("cert has expired");
8764 +       break;
8765 +    }
8766 +    if (((pfixtls_serverengine) && (var_smtpd_tls_loglevel >= 2)) ||
8767 +       ((pfixtls_clientengine) && (var_smtp_tls_loglevel >= 2)))
8768 +       msg_info("verify return:%d", ok);
8769 +
8770 +    if (TLScontext->enforce_verify_errors)
8771 +       return (ok); 
8772 +    else
8773 +       return (1);
8774 +}
8775 +
8776 +/* taken from OpenSSL apps/s_cb.c */
8777 +
8778 +static void apps_ssl_info_callback(SSL * s, int where, int ret)
8779 +{
8780 +    char   *str;
8781 +    int     w;
8782 +
8783 +    w = where & ~SSL_ST_MASK;
8784 +
8785 +    if (w & SSL_ST_CONNECT)
8786 +       str = "SSL_connect";
8787 +    else if (w & SSL_ST_ACCEPT)
8788 +       str = "SSL_accept";
8789 +    else
8790 +       str = "undefined";
8791 +
8792 +    if (where & SSL_CB_LOOP) {
8793 +           msg_info("%s:%s", str, SSL_state_string_long(s));
8794 +    } else if (where & SSL_CB_ALERT) {
8795 +       str = (where & SSL_CB_READ) ? "read" : "write";
8796 +       if ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY)
8797 +       msg_info("SSL3 alert %s:%s:%s", str,
8798 +                SSL_alert_type_string_long(ret),
8799 +                SSL_alert_desc_string_long(ret));
8800 +    } else if (where & SSL_CB_EXIT) {
8801 +       if (ret == 0)
8802 +           msg_info("%s:failed in %s",
8803 +                    str, SSL_state_string_long(s));
8804 +       else if (ret < 0) {
8805 +           msg_info("%s:error in %s",
8806 +                    str, SSL_state_string_long(s));
8807 +       }
8808 +    }
8809 +}
8810 +
8811 +/*
8812 + * taken from OpenSSL crypto/bio/b_dump.c, modified to save a lot of strcpy
8813 + * and strcat by Matti Aarnio.
8814 + */
8815 +
8816 +#define TRUNCATE
8817 +#define DUMP_WIDTH     16
8818 +
8819 +static int pfixtls_dump(const char *s, int len)
8820 +{
8821 +    int     ret = 0;
8822 +    char    buf[160 + 1];
8823 +    char    *ss;
8824 +    int     i;
8825 +    int     j;
8826 +    int     rows;
8827 +    int     trunc;
8828 +    unsigned char ch;
8829 +
8830 +    trunc = 0;
8831 +
8832 +#ifdef TRUNCATE
8833 +    for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--)
8834 +       trunc++;
8835 +#endif
8836 +
8837 +    rows = (len / DUMP_WIDTH);
8838 +    if ((rows * DUMP_WIDTH) < len)
8839 +       rows++;
8840 +
8841 +    for (i = 0; i < rows; i++) {
8842 +       buf[0] = '\0';                          /* start with empty string */
8843 +       ss = buf;
8844 +
8845 +       sprintf(ss, "%04x ", i * DUMP_WIDTH);
8846 +       ss += strlen(ss);
8847 +       for (j = 0; j < DUMP_WIDTH; j++) {
8848 +           if (((i * DUMP_WIDTH) + j) >= len) {
8849 +               strcpy(ss, "   ");
8850 +           } else {
8851 +               ch = ((unsigned char) *((char *) (s) + i * DUMP_WIDTH + j))
8852 +                   & 0xff;
8853 +               sprintf(ss, "%02x%c", ch, j == 7 ? '|' : ' ');
8854 +               ss += 3;
8855 +           }
8856 +       }
8857 +       ss += strlen(ss);
8858 +       *ss++ = ' ';
8859 +       for (j = 0; j < DUMP_WIDTH; j++) {
8860 +           if (((i * DUMP_WIDTH) + j) >= len)
8861 +               break;
8862 +           ch = ((unsigned char) *((char *) (s) + i * DUMP_WIDTH + j)) & 0xff;
8863 +           *ss++ = (((ch >= ' ') && (ch <= '~')) ? ch : '.');
8864 +           if (j == 7) *ss++ = ' ';
8865 +       }
8866 +       *ss = 0;
8867 +       /* 
8868 +        * if this is the last call then update the ddt_dump thing so that
8869 +         * we will move the selection point in the debug window
8870 +         */
8871 +       msg_info("%s", buf);
8872 +       ret += strlen(buf);
8873 +    }
8874 +#ifdef TRUNCATE
8875 +    if (trunc > 0) {
8876 +       sprintf(buf, "%04x - <SPACES/NULS>\n", len + trunc);
8877 +       msg_info("%s", buf);
8878 +       ret += strlen(buf);
8879 +    }
8880 +#endif
8881 +    return (ret);
8882 +}
8883 +
8884 +
8885 +
8886 +/* taken from OpenSSL apps/s_cb.c */
8887 +
8888 +static long bio_dump_cb(BIO * bio, int cmd, const char *argp, int argi,
8889 +                       long argl, long ret)
8890 +{
8891 +    if (!do_dump)
8892 +       return (ret);
8893 +
8894 +    if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
8895 +       msg_info("read from %08X [%08lX] (%d bytes => %ld (0x%X))", bio, argp,
8896 +                argi, ret, ret);
8897 +       pfixtls_dump(argp, (int) ret);
8898 +       return (ret);
8899 +    } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
8900 +       msg_info("write to %08X [%08lX] (%d bytes => %ld (0x%X))", bio, argp,
8901 +                argi, ret, ret);
8902 +       pfixtls_dump(argp, (int) ret);
8903 +    }
8904 +    return (ret);
8905 +}
8906 +
8907 +
8908 + /*
8909 +  * Callback to retrieve a session from the external session cache.
8910 +  */
8911 +static SSL_SESSION *get_session_cb(SSL *ssl, unsigned char *SessionID,
8912 +                                 int length, int *copy)
8913 +{
8914 +    SSL_SESSION *session;
8915 +    char *idstring;
8916 +    int n;
8917 +    int uselength;
8918 +    int hex_length;
8919 +    const char *session_hex;
8920 +    pfixtls_scache_info_t scache_info;
8921 +    unsigned char nibble, *data, *sess_data;
8922 +
8923 +    if (length > id_maxlength)
8924 +       uselength = id_maxlength;       /* Limit length of ID */
8925 +    else
8926 +       uselength = length;
8927 +
8928 +    idstring = (char *)mymalloc(2 * uselength + 1);
8929 +    if (!idstring) {
8930 +       msg_info("could not allocate memory for IDstring");
8931 +       return (NULL);
8932 +    }
8933 +
8934 +    for(n=0 ; n < uselength ; n++)
8935 +       sprintf(idstring + 2 * n, "%02x", SessionID[n]);
8936 +    if (var_smtpd_tls_loglevel >= 3)
8937 +       msg_info("Trying to reload Session from disc: %s", idstring);
8938 +
8939 +    session = NULL;
8940 +
8941 +    session_hex = dict_get(scache_db, idstring);
8942 +    if (session_hex) {
8943 +       hex_length = strlen(session_hex);
8944 +       data = (unsigned char *)mymalloc(hex_length / 2);
8945 +       if (!data) {
8946 +           msg_info("could not allocate memory for session reload");
8947 +           myfree(idstring);
8948 +           return(NULL);
8949 +       }
8950 +
8951 +       memset(data, 0, hex_length / 2);
8952 +       for (n = 0; n < hex_length; n++) {
8953 +           if ((session_hex[n] >= '0') && (session_hex[n] <= '9'))
8954 +               nibble = session_hex[n] - '0';
8955 +           else
8956 +               nibble = session_hex[n] - 'A' + 10;
8957 +           if (n % 2)
8958 +               data[n / 2] |= nibble;
8959 +           else
8960 +               data[n / 2] |= (nibble << 4);
8961 +       }
8962 +
8963 +       /*
8964 +        * First check the version numbers, since wrong session data might
8965 +        * hit us hard (SEGFAULT). We also have to check for expiry.
8966 +        */
8967 +       memcpy(&scache_info, data, sizeof(pfixtls_scache_info_t));
8968 +       if ((scache_info.scache_db_version != scache_db_version) ||
8969 +           (scache_info.openssl_version != openssl_version) ||
8970 +           (scache_info.timestamp + var_smtpd_tls_scache_timeout < time(NULL)))
8971 +           dict_del(scache_db, idstring);
8972 +       else {
8973 +           sess_data = data + sizeof(pfixtls_scache_info_t);
8974 +           session = d2i_SSL_SESSION(NULL, &sess_data,
8975 +                             hex_length / 2 - sizeof(pfixtls_scache_info_t));
8976 +           if (!session)
8977 +               pfixtls_print_errors();
8978 +       }
8979 +       myfree((char *)data);
8980 +    }
8981 +
8982 +    if (session && (var_smtpd_tls_loglevel >= 3))
8983 +       msg_info("Successfully reloaded session from disc");
8984 +
8985 +    myfree(idstring);
8986 +    return (session);
8987 +}
8988 +
8989 +
8990 +static SSL_SESSION *load_clnt_session(const char *hostname)
8991 +{
8992 +    SSL_SESSION *session = NULL;
8993 +    char *idstring;
8994 +    int n;
8995 +    int uselength;
8996 +    int length;
8997 +    int hex_length;
8998 +    const char *session_hex;
8999 +    pfixtls_scache_info_t scache_info;
9000 +    unsigned char nibble, *data, *sess_data;
9001 +
9002 +    length = strlen(hostname); 
9003 +    if (length > id_maxlength)
9004 +       uselength = id_maxlength;       /* Limit length of ID */
9005 +    else
9006 +       uselength = length;
9007 +
9008 +    idstring = (char *)mymalloc(uselength + 1);
9009 +    if (!idstring) {
9010 +       msg_info("could not allocate memory for IDstring");
9011 +       return (NULL);
9012 +    }
9013 +
9014 +    for(n=0 ; n < uselength ; n++)
9015 +       idstring[n] = tolower(hostname[n]);
9016 +    idstring[uselength] = '\0';
9017 +    if (var_smtp_tls_loglevel >= 3)
9018 +       msg_info("Trying to reload Session from disc: %s", idstring);
9019 +
9020 +    session_hex = dict_get(scache_db, idstring);
9021 +    if (session_hex) {
9022 +       hex_length = strlen(session_hex);
9023 +       data = (unsigned char *)mymalloc(hex_length / 2);
9024 +       if (!data) {
9025 +           msg_info("could not allocate memory for session reload");
9026 +           myfree(idstring);
9027 +           return(NULL);
9028 +       }
9029 +
9030 +       memset(data, 0, hex_length / 2);
9031 +       for (n = 0; n < hex_length; n++) {
9032 +           if ((session_hex[n] >= '0') && (session_hex[n] <= '9'))
9033 +               nibble = session_hex[n] - '0';
9034 +           else
9035 +               nibble = session_hex[n] - 'A' + 10;
9036 +           if (n % 2)
9037 +               data[n / 2] |= nibble;
9038 +           else
9039 +               data[n / 2] |= (nibble << 4);
9040 +       }
9041 +
9042 +       /*
9043 +        * First check the version numbers, since wrong session data might
9044 +        * hit us hard (SEGFAULT). We also have to check for expiry.
9045 +        */
9046 +       memcpy(&scache_info, data, sizeof(pfixtls_scache_info_t));
9047 +       if ((scache_info.scache_db_version != scache_db_version) ||
9048 +           (scache_info.openssl_version != openssl_version) ||
9049 +           (scache_info.timestamp + var_smtpd_tls_scache_timeout < time(NULL)))
9050 +           dict_del(scache_db, idstring);
9051 +       else {
9052 +           sess_data = data + sizeof(pfixtls_scache_info_t);
9053 +           session = d2i_SSL_SESSION(NULL, &sess_data,
9054 +                                     hex_length / 2 - sizeof(time_t));
9055 +           if (!session)
9056 +               pfixtls_print_errors();
9057 +       }
9058 +       myfree((char *)data);
9059 +    }
9060 +
9061 +    myfree(idstring);
9062 +
9063 +    if (session && (var_smtp_tls_loglevel >= 3))
9064 +        msg_info("Successfully reloaded session from disc");
9065 +
9066 +    return (session);
9067 +}
9068 +
9069 +
9070 +static void remove_srvr_session(unsigned char *SessionID, int length)
9071 +{
9072 +    VSTRING *buf;
9073 +    char *idstring;
9074 +    int n;
9075 +    int uselength;
9076 +
9077 +    if (length > id_maxlength)
9078 +       uselength = id_maxlength;       /* Limit length of ID */
9079 +    else
9080 +       uselength = length;
9081 +
9082 +    idstring = (char *)mymalloc(2 * uselength + 1);
9083 +    if (!idstring) {
9084 +       msg_info("could not allocate memory for IDstring");
9085 +       return;
9086 +    }
9087 +
9088 +    for(n=0 ; n < uselength ; n++)
9089 +       sprintf(idstring + 2 * n, "%02x", SessionID[n]);
9090 +    if (var_smtpd_tls_loglevel >= 3)
9091 +       msg_info("Trying to remove session from disc: %s", idstring);
9092 +
9093 +    if (scache_db)
9094 +       dict_del(scache_db, idstring);
9095 +
9096 +    myfree(idstring);
9097 +}
9098 +
9099 +
9100 +static void remove_clnt_session(const char *hostname)
9101 +{
9102 +    char *idstring;
9103 +    int n;
9104 +    int uselength;
9105 +    int length;
9106 +
9107 +    length = strlen(hostname);
9108 +    if (length > id_maxlength)
9109 +       uselength = id_maxlength;       /* Limit length of ID */
9110 +    else
9111 +       uselength = length;
9112 +
9113 +    idstring = (char *)mymalloc(uselength + 1);
9114 +    if (!idstring) {
9115 +       msg_info("could not allocate memory for IDstring");
9116 +       return;
9117 +    }
9118 +
9119 +    for(n=0 ; n < uselength ; n++)
9120 +       idstring[n] = tolower(hostname[n]);
9121 +    idstring[uselength] = '\0'; 
9122 +    if (var_smtp_tls_loglevel >= 3)
9123 +       msg_info("Trying to remove session from disc: %s", idstring);
9124 +    if (scache_db)
9125 +       dict_del(scache_db, idstring);
9126 +    myfree(idstring);
9127 +}
9128 +
9129 +
9130 + /*
9131 +  * Save a new session to the external cache
9132 +  */
9133 +static int new_session_cb(SSL *ssl, SSL_SESSION *session)
9134 +{
9135 +    char *idstring;
9136 +    int n;
9137 +    int uselength;
9138 +    int dsize;
9139 +    int len;
9140 +    unsigned char *data, *sess_data;
9141 +    pfixtls_scache_info_t scache_info;
9142 +    char *hexdata;
9143 +
9144 +    if (session->session_id_length > id_maxlength)
9145 +       uselength = id_maxlength;       /* Limit length of ID */
9146 +    else
9147 +       uselength = session->session_id_length;
9148 +
9149 +    idstring = (char *)mymalloc(2 * uselength + 1);
9150 +    if (!idstring) {
9151 +       msg_info("could not allocate memory for IDstring");
9152 +       return 0;
9153 +    }
9154 +
9155 +    for(n=0 ; n < uselength ; n++)
9156 +       sprintf(idstring + 2 * n, "%02x", session->session_id[n]);
9157 +
9158 +    if (var_smtpd_tls_loglevel >= 3)
9159 +       msg_info("Trying to save Session to disc: %s", idstring);
9160 +
9161 +    /*
9162 +     * Get the session and convert it into some "database" useable form.
9163 +     * First, get the length of the session to allocate the memory.
9164 +     */
9165 +    dsize = i2d_SSL_SESSION(session, NULL);
9166 +    if (dsize < 0) {
9167 +       msg_info("Could not access session");
9168 +       return 0;
9169 +    }
9170 +    data = (unsigned char *)mymalloc(dsize + sizeof(pfixtls_scache_info_t));
9171 +    if (!data) {
9172 +       msg_info("could not allocate memory for SSL session");
9173 +       myfree(idstring);
9174 +       return 0;
9175 +    }
9176 +
9177 +    /*
9178 +     * OpenSSL is not robust against wrong session data (might SEGFAULT),
9179 +     * so we secure it against version ids (session cache structure as well
9180 +     * as OpenSSL version).
9181 +     */
9182 +    scache_info.scache_db_version = scache_db_version;
9183 +    scache_info.openssl_version = openssl_version;
9184 +
9185 +    /*
9186 +     * Put a timestamp, so that expiration can be checked without
9187 +     * analyzing the session data itself. (We would need OpenSSL funtions,
9188 +     * since the SSL_SESSION is a private structure.)
9189 +     */
9190 +    scache_info.timestamp = time(NULL);
9191 +
9192 +    memcpy(data, &scache_info, sizeof(pfixtls_scache_info_t));
9193 +    sess_data = data + sizeof(pfixtls_scache_info_t);
9194 +
9195 +    /*
9196 +     * Now, obtain the session. Unfortunately, it is binary and dict_update
9197 +     * cannot handle binary data (it could contain '\0' in it) directly.
9198 +     * To save memory we could use base64 encoding. To make handling easier,
9199 +     * we simply use hex format.
9200 +     */
9201 +    len = i2d_SSL_SESSION(session, &sess_data);
9202 +    len += sizeof(pfixtls_scache_info_t);
9203 +
9204 +    hexdata = (char *)mymalloc(2 * len + 1);
9205 +
9206 +    if (!hexdata) {
9207 +       msg_info("could not allocate memory for SSL session (HEX)");
9208 +       myfree((char *)data);
9209 +       myfree(idstring);
9210 +       return 0;
9211 +    }
9212 +    for (n = 0; n < len; n++) {
9213 +       hexdata[n * 2] = hexcodes[(data[n] & 0xf0) >> 4];
9214 +       hexdata[(n * 2) + 1] = hexcodes[(data[n] & 0x0f)];
9215 +    }
9216 +    hexdata[len * 2] = '\0';
9217 +
9218 +    /*
9219 +     * The session id is a hex string, all uppercase. We are using SDBM as
9220 +     * compiled into Postfix with 8kB maximum entry size, so we set a limit
9221 +     * when caching. If the session is not cached, we have to renegotiate,
9222 +     * not more, not less. For a real session, this limit should never be
9223 +     * met
9224 +     */
9225 +    if (strlen(idstring) + strlen(hexdata) < 8000)
9226 +      dict_put(scache_db, idstring, hexdata);
9227 +
9228 +    myfree(hexdata);
9229 +    myfree((char *)data);
9230 +    myfree(idstring);
9231 +    return (0);
9232 +}
9233 +
9234 +
9235 + /*
9236 +  * Save the new session to the external cache. As the HostID is given
9237 +  * by the contacted peer, we may have several negotiations going on at
9238 +  * the same time for the same peer. This is not purely hypothetical but
9239 +  * quite likely if several jobs to the same recipient host are in the queue
9240 +  * and a queue run is started. So we have to take care of race conditions.
9241 +  * As I consider the TLS-SessionID to be unique, we will first try to
9242 +  * create a file with the actual SessionID. Once the writing is finished,
9243 +  * the file is closed and moved to its final name. This way we should be
9244 +  * able to deal with race conditions, since rename should be atomic.
9245 +  * If the rename fails for some reason, we will just silently remove
9246 +  * the temporary file and forget about the session.
9247 +  */
9248 +static void save_clnt_session(SSL_SESSION *session, const char *hostname)
9249 +{
9250 +    char *idstring;
9251 +    int length;
9252 +    int uselength;
9253 +    int n;
9254 +    int len;
9255 +    int dsize;
9256 +    unsigned char *data, *sess_data;
9257 +    pfixtls_scache_info_t scache_info;
9258 +    char *hexdata;
9259 +
9260 +    length = strlen(hostname);
9261 +    if (length > id_maxlength)
9262 +       uselength = id_maxlength;       /* Limit length of ID */
9263 +    else
9264 +       uselength = length;
9265 +
9266 +    idstring = (char *)mymalloc(uselength + 1);
9267 +    if (!idstring) {
9268 +       msg_info("could not allocate memory for IDstring");
9269 +       return;
9270 +    }
9271 +
9272 +    for(n=0 ; n < uselength ; n++)
9273 +       idstring[n] = tolower(hostname[n]);
9274 +    idstring[uselength] = '\0';
9275 +    if (var_smtp_tls_loglevel >= 3)
9276 +       msg_info("Trying to save session for hostID to disc: %s", idstring);
9277 +
9278 +    /*
9279 +     * Get the session and convert it into some "database" useable form.
9280 +     * First, get the length of the session to allocate the memory.
9281 +     */
9282 +    dsize = i2d_SSL_SESSION(session, NULL);
9283 +    if (dsize < 0) {
9284 +       msg_info("Could not access session");
9285 +       return;
9286 +    }
9287 +    data = (unsigned char *)mymalloc(dsize + sizeof(pfixtls_scache_info_t));
9288 +    if (!data) {
9289 +       msg_info("could not allocate memory for SSL session");
9290 +       myfree(idstring);
9291 +       return;
9292 +    }
9293 +
9294 +    /*
9295 +     * OpenSSL is not robust against wrong session data (might SEGFAULT),
9296 +     * so we secure it against version ids (session cache structure as well
9297 +     * as OpenSSL version).
9298 +     */
9299 +    scache_info.scache_db_version = scache_db_version;
9300 +    scache_info.openssl_version = openssl_version;
9301 +
9302 +    /*
9303 +     * Put a timestamp, so that expiration can be checked without
9304 +     * analyzing the session data itself. (We would need OpenSSL funtions,
9305 +     * since the SSL_SESSION is a private structure.)
9306 +     */
9307 +    scache_info.timestamp = time(NULL);
9308 +
9309 +    memcpy(data, &scache_info, sizeof(pfixtls_scache_info_t));
9310 +    sess_data = data + sizeof(pfixtls_scache_info_t);
9311 +
9312 +    /*
9313 +     * Now, obtain the session. Unfortunately, it is binary and dict_update
9314 +     * cannot handle binary data (it could contain '\0' in it) directly.
9315 +     * To save memory we could use base64 encoding. To make handling easier,
9316 +     * we simply use hex format.
9317 +     */
9318 +    len = i2d_SSL_SESSION(session, &sess_data);
9319 +    len += sizeof(pfixtls_scache_info_t);
9320 +
9321 +    hexdata = (char *)mymalloc(2 * len + 1);
9322 +
9323 +    if (!hexdata) {
9324 +       msg_info("could not allocate memory for SSL session (HEX)");
9325 +       myfree((char *)data);
9326 +       myfree(idstring);
9327 +       return;
9328 +    }
9329 +    for (n = 0; n < len; n++) {
9330 +       hexdata[n * 2] = hexcodes[(data[n] & 0xf0) >> 4];
9331 +       hexdata[(n * 2) + 1] = hexcodes[(data[n] & 0x0f)];
9332 +    }
9333 +    hexdata[len * 2] = '\0';
9334 +
9335 +    /*
9336 +     * The session id is a hex string, all uppercase. We are using SDBM as
9337 +     * compiled into Postfix with 8kB maximum entry size, so we set a limit
9338 +     * when caching. If the session is not cached, we have to renegotiate,
9339 +     * not more, not less. For a real session, this limit should never be
9340 +     * met
9341 +     */
9342 +    if (strlen(idstring) + strlen(hexdata) < 8000)
9343 +      dict_put(scache_db, idstring, hexdata);
9344 +
9345 +    myfree(hexdata);
9346 +    myfree((char *)data);
9347 +    myfree(idstring);
9348 +}
9349 +
9350 + /*
9351 +  * pfixtls_exchange_seed: read bytes from the seed exchange-file (expect
9352 +  * 1024 bytes)and immediately write back random bytes. Do so with EXCLUSIVE
9353 +  * lock, so * that each process will find a completely different (and
9354 +  * reseeded) file.
9355 +  */
9356 +static void pfixtls_exchange_seed(void)
9357 +{
9358 +    unsigned char buffer[1024];
9359 +
9360 +    if (rand_exch_fd == -1)
9361 +       return;
9362 +
9363 +    if (myflock(rand_exch_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) != 0)
9364 +        msg_info("Could not lock random exchange file: %s",
9365 +                  strerror(errno));
9366 +
9367 +    lseek(rand_exch_fd, 0, SEEK_SET);
9368 +    if (read(rand_exch_fd, buffer, 1024) < 0)
9369 +        msg_fatal("reading exchange file failed");
9370 +    RAND_seed(buffer, 1024);
9371 +
9372 +    RAND_bytes(buffer, 1024);
9373 +    lseek(rand_exch_fd, 0, SEEK_SET);
9374 +    if (write(rand_exch_fd, buffer, 1024) != 1024)
9375 +        msg_fatal("Writing exchange file failed");
9376 +
9377 +    if (myflock(rand_exch_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) != 0)
9378 +        msg_fatal("Could not unlock random exchange file: %s",
9379 +                  strerror(errno));
9380 +}
9381 +
9382 + /*
9383 +  * This is the setup routine for the SSL server. As smtpd might be called
9384 +  * more than once, we only want to do the initialization one time.
9385 +  *
9386 +  * The skeleton of this function is taken from OpenSSL apps/s_server.c.
9387 +  */
9388 +
9389 +int     pfixtls_init_serverengine(int verifydepth, int askcert)
9390 +{
9391 +    int     off = 0;
9392 +    int     verify_flags = SSL_VERIFY_NONE;
9393 +    int     rand_bytes;
9394 +    int     rand_source_dev_fd;
9395 +    int     rand_source_socket_fd;
9396 +    unsigned char buffer[255];
9397 +    char   *CApath;
9398 +    char   *CAfile;
9399 +    char   *s_cert_file;
9400 +    char   *s_key_file;
9401 +    char   *s_dcert_file;
9402 +    char   *s_dkey_file;
9403 +    FILE   *paramfile;
9404 +
9405 +    if (pfixtls_serverengine)
9406 +       return (0);                             /* already running */
9407 +
9408 +    if (var_smtpd_tls_loglevel >= 2)
9409 +       msg_info("starting TLS engine");
9410 +
9411 +    /*
9412 +     * Initialize the OpenSSL library by the book!
9413 +     * To start with, we must initialize the algorithms.
9414 +     * We want cleartext error messages instead of just error codes, so we
9415 +     * load the error_strings.
9416 +     */
9417 +    SSL_load_error_strings();
9418 +    OpenSSL_add_ssl_algorithms();
9419 +
9420 + /*
9421 +  * Side effect, call a non-existing function to disable TLS usage with an
9422 +  * outdated OpenSSL version. There is a security reason (verify_result
9423 +  * is not stored with the session data).
9424 +  */
9425 +#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
9426 +    needs_openssl_095_or_later();
9427 +#endif
9428 +
9429 +    /*
9430 +     * Initialize the PRNG Pseudo Random Number Generator with some seed.
9431 +     */
9432 +    randseed.pid = getpid();
9433 +    GETTIMEOFDAY(&randseed.tv);
9434 +    RAND_seed(&randseed, sizeof(randseed_t));
9435 +
9436 +    /*
9437 +     * Access the external sources for random seed. We will only query them
9438 +     * once, this should be sufficient and we will stir our entropy by using
9439 +     * the prng-exchange file anyway.
9440 +     * For reliability, we don't consider failure to access the additional
9441 +     * source fatal, as we can run happily without it (considering that we
9442 +     * still have the exchange-file). We also don't care how much entropy
9443 +     * we get back, as we must run anyway. We simply stir in the buffer
9444 +     * regardless how many bytes are actually in it.
9445 +     */
9446 +    if (*var_tls_daemon_rand_source) {
9447 +       if (!strncmp(var_tls_daemon_rand_source, "dev:", 4)) {
9448 +           /*
9449 +            * Source is a random device
9450 +            */
9451 +           rand_source_dev_fd = open(var_tls_daemon_rand_source + 4, 0, 0);
9452 +           if (rand_source_dev_fd == -1) 
9453 +               msg_info("Could not open entropy device %s",
9454 +                         var_tls_daemon_rand_source);
9455 +           else {
9456 +               if (var_tls_daemon_rand_bytes > 255)
9457 +                   var_tls_daemon_rand_bytes = 255;
9458 +               read(rand_source_dev_fd, buffer, var_tls_daemon_rand_bytes);
9459 +               RAND_seed(buffer, var_tls_daemon_rand_bytes);
9460 +               close(rand_source_dev_fd);
9461 +           }
9462 +       } else if (!strncmp(var_tls_daemon_rand_source, "egd:", 4)) {
9463 +           /*
9464 +            * Source is a EGD compatible socket
9465 +            */
9466 +           rand_source_socket_fd = unix_connect(var_tls_daemon_rand_source +4,
9467 +                                                BLOCKING, 10);
9468 +           if (rand_source_socket_fd == -1)
9469 +               msg_info("Could not connect to %s", var_tls_daemon_rand_source);
9470 +           else {
9471 +               if (var_tls_daemon_rand_bytes > 255)
9472 +                   var_tls_daemon_rand_bytes = 255;
9473 +               buffer[0] = 1;
9474 +               buffer[1] = var_tls_daemon_rand_bytes;
9475 +               if (write(rand_source_socket_fd, buffer, 2) != 2)
9476 +                   msg_info("Could not talk to %s",
9477 +                            var_tls_daemon_rand_source);
9478 +               else if (read(rand_source_socket_fd, buffer, 1) != 1)
9479 +                   msg_info("Could not read info from %s",
9480 +                            var_tls_daemon_rand_source);
9481 +               else {
9482 +                   rand_bytes = buffer[0];
9483 +                   read(rand_source_socket_fd, buffer, rand_bytes);
9484 +                   RAND_seed(buffer, rand_bytes);
9485 +               }
9486 +               close(rand_source_socket_fd);
9487 +           }
9488 +       } else {
9489 +           RAND_load_file(var_tls_daemon_rand_source,
9490 +                          var_tls_daemon_rand_bytes);
9491 +       }
9492 +    }
9493 +
9494 +    if (*var_tls_rand_exch_name) {
9495 +       rand_exch_fd = open(var_tls_rand_exch_name, O_RDWR | O_CREAT, 0600);
9496 +       if (rand_exch_fd != -1)
9497 +           pfixtls_exchange_seed();
9498 +    }
9499 +
9500 +    randseed.pid = getpid();
9501 +    GETTIMEOFDAY(&randseed.tv);
9502 +    RAND_seed(&randseed, sizeof(randseed_t));
9503 +
9504 +    /*
9505 +     * The SSL/TLS speficications require the client to send a message in
9506 +     * the oldest specification it understands with the highest level it
9507 +     * understands in the message.
9508 +     * Netscape communicator can still communicate with SSLv2 servers, so it
9509 +     * sends out a SSLv2 client hello. To deal with it, our server must be
9510 +     * SSLv2 aware (even if we don´t like SSLv2), so we need to have the
9511 +     * SSLv23 server here. If we want to limit the protocol level, we can
9512 +     * add an option to not use SSLv2/v3/TLSv1 later.
9513 +     */
9514 +    ctx = SSL_CTX_new(SSLv23_server_method());
9515 +    if (ctx == NULL) {
9516 +       pfixtls_print_errors();
9517 +       return (-1);
9518 +    };
9519 +
9520 +    /*
9521 +     * Here we might set SSL_OP_NO_SSLv2, SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1.
9522 +     * Of course, the last one would not make sense, since RFC2487 is only
9523 +     * defined for TLS, but we also want to accept Netscape communicator
9524 +     * requests, and it only supports SSLv3.
9525 +     */
9526 +    off |= SSL_OP_ALL;         /* Work around all known bugs */
9527 +    SSL_CTX_set_options(ctx, off);
9528 +
9529 +    /*
9530 +     * Set the info_callback, that will print out messages during
9531 +     * communication on demand.
9532 +     */
9533 +    if (var_smtpd_tls_loglevel >= 2)
9534 +       SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
9535 +
9536 +    /*
9537 +     * Set the list of ciphers, if explicitely given; otherwise the
9538 +     * (reasonable) default list is kept.
9539 +     */
9540 +    if (strlen(var_smtpd_tls_cipherlist) != 0)
9541 +       if (SSL_CTX_set_cipher_list(ctx, var_smtpd_tls_cipherlist) == 0) {
9542 +           pfixtls_print_errors();
9543 +           return (-1);
9544 +       }
9545 +
9546 +    /*
9547 +     * Now we must add the necessary certificate stuff: A server key, a
9548 +     * server certificate, and the CA certificates for both the server
9549 +     * cert and the verification of client certificates.
9550 +     * As provided by OpenSSL we support two types of CA certificate handling:
9551 +     * One possibility is to add all CA certificates to one large CAfile,
9552 +     * the other possibility is a directory pointed to by CApath, containing
9553 +     * seperate files for each CA pointed on by softlinks named by the hash
9554 +     * values of the certificate.
9555 +     * The first alternative has the advantage, that the file is opened and
9556 +     * read at startup time, so that you don´t have the hassle to maintain
9557 +     * another copy of the CApath directory for chroot-jail. On the other
9558 +     * hand, the file is not really readable.
9559 +     */
9560 +    if (strlen(var_smtpd_tls_CAfile) == 0)
9561 +       CAfile = NULL;
9562 +    else
9563 +       CAfile = var_smtpd_tls_CAfile;
9564 +    if (strlen(var_smtpd_tls_CApath) == 0)
9565 +       CApath = NULL;
9566 +    else
9567 +       CApath = var_smtpd_tls_CApath;
9568 +
9569 +    if (CAfile || CApath) {
9570 +       if (!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) {
9571 +           msg_info("TLS engine: cannot load CA data");
9572 +           pfixtls_print_errors();
9573 +           return (-1);
9574 +       }
9575 +       if (!SSL_CTX_set_default_verify_paths(ctx)) {
9576 +           msg_info("TLS engine: cannot set verify paths");
9577 +           pfixtls_print_errors();
9578 +           return (-1);
9579 +       }
9580 +    }
9581 +
9582 +    /*
9583 +     * Now we load the certificate and key from the files and check,
9584 +     * whether the cert matches the key (internally done by set_cert_stuff().
9585 +     * We cannot run without (we do not support ADH anonymous Diffie-Hellman
9586 +     * ciphers as of now).
9587 +     * We can use RSA certificates ("cert") and DSA certificates ("dcert"),
9588 +     * both can be made available at the same time. The CA certificates for
9589 +     * both are handled in the same setup already finished.
9590 +     * Which one is used depends on the cipher negotiated (that is: the first
9591 +     * cipher listed by the client which does match the server). A client with
9592 +     * RSA only (e.g. Netscape) will use the RSA certificate only.
9593 +     * A client with openssl-library will use RSA first if not especially
9594 +     * changed in the cipher setup.
9595 +     */
9596 +    if (strlen(var_smtpd_tls_cert_file) == 0)
9597 +       s_cert_file = NULL;
9598 +    else
9599 +       s_cert_file = var_smtpd_tls_cert_file;
9600 +    if (strlen(var_smtpd_tls_key_file) == 0)
9601 +       s_key_file = NULL;
9602 +    else
9603 +       s_key_file = var_smtpd_tls_key_file;
9604 +
9605 +    if (strlen(var_smtpd_tls_dcert_file) == 0)
9606 +       s_dcert_file = NULL;
9607 +    else
9608 +       s_dcert_file = var_smtpd_tls_dcert_file;
9609 +    if (strlen(var_smtpd_tls_dkey_file) == 0)
9610 +       s_dkey_file = NULL;
9611 +    else
9612 +       s_dkey_file = var_smtpd_tls_dkey_file;
9613 +
9614 +    if (s_cert_file) {
9615 +       if (!set_cert_stuff(ctx, s_cert_file, s_key_file)) {
9616 +           msg_info("TLS engine: cannot load RSA cert/key data");
9617 +           pfixtls_print_errors();
9618 +           return (-1);
9619 +       }
9620 +    }
9621 +    if (s_dcert_file) {
9622 +       if (!set_cert_stuff(ctx, s_dcert_file, s_dkey_file)) {
9623 +           msg_info("TLS engine: cannot load DSA cert/key data");
9624 +           pfixtls_print_errors();
9625 +           return (-1);
9626 +       }
9627 +    }
9628 +    if (!s_cert_file && !s_dcert_file) {
9629 +       msg_info("TLS engine: do need at least RSA _or_ DSA cert/key data");
9630 +       return (-1);
9631 +    }
9632 +
9633 +    /*
9634 +     * Sometimes a temporary RSA key might be needed by the OpenSSL
9635 +     * library. The OpenSSL doc indicates, that this might happen when
9636 +     * export ciphers are in use. We have to provide one, so well, we
9637 +     * just do it.
9638 +     */
9639 +    SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb);
9640 +
9641 +    /*
9642 +     * We might also need dh parameters, which can either be loaded from
9643 +     * file (preferred) or we simply take the compiled in values.
9644 +     * First, set the callback that will select the values when requested,
9645 +     * then load the (possibly) available DH parameters from files.
9646 +     * We are generous with the error handling, since we do have default
9647 +     * values compiled in, so we will not abort but just log the error message.
9648 +     */
9649 +    SSL_CTX_set_tmp_dh_callback(ctx, tmp_dh_cb);
9650 +    if (strlen(var_smtpd_tls_dh1024_param_file) != 0) {
9651 +       if ((paramfile = fopen(var_smtpd_tls_dh1024_param_file, "r")) != NULL) {
9652 +           dh_1024 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
9653 +           if (dh_1024 == NULL) {
9654 +               msg_info("TLS engine: cannot load 1024bit DH parameters");
9655 +               pfixtls_print_errors();
9656 +           }
9657 +       }
9658 +       else {
9659 +           msg_info("TLS engine: cannot load 1024bit DH parameters: %s: %s",
9660 +                    var_smtpd_tls_dh1024_param_file, strerror(errno));
9661 +       }
9662 +    }
9663 +    if (strlen(var_smtpd_tls_dh512_param_file) != 0) {
9664 +       if ((paramfile = fopen(var_smtpd_tls_dh512_param_file, "r")) != NULL) {
9665 +           dh_512 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
9666 +           if (dh_512 == NULL) {
9667 +               msg_info("TLS engine: cannot load 512bit DH parameters");
9668 +               pfixtls_print_errors();
9669 +           }
9670 +       }
9671 +       else {
9672 +           msg_info("TLS engine: cannot load 512bit DH parameters: %s: %s",
9673 +                    var_smtpd_tls_dh512_param_file, strerror(errno));
9674 +       }
9675 +    }
9676 +
9677 +    /*
9678 +     * If we want to check client certificates, we have to indicate it
9679 +     * in advance. By now we only allow to decide on a global basis.
9680 +     * If we want to allow certificate based relaying, we must ask the
9681 +     * client to provide one with SSL_VERIFY_PEER. The client now can
9682 +     * decide, whether it provides one or not. We can enforce a failure
9683 +     * of the negotiation with SSL_VERIFY_FAIL_IF_NO_PEER_CERT, if we
9684 +     * do not allow a connection without one.
9685 +     * In the "server hello" following the initialization by the "client hello"
9686 +     * the server must provide a list of CAs it is willing to accept.
9687 +     * Some clever clients will then select one from the list of available
9688 +     * certificates matching these CAs. Netscape Communicator will present
9689 +     * the list of certificates for selecting the one to be sent, or it will
9690 +     * issue a warning, if there is no certificate matching the available
9691 +     * CAs.
9692 +     *
9693 +     * With regard to the purpose of the certificate for relaying, we might
9694 +     * like a later negotiation, maybe relaying would already be allowed
9695 +     * for other reasons, but this would involve severe changes in the
9696 +     * internal postfix logic, so we have to live with it the way it is.
9697 +     */
9698 +    if (askcert)
9699 +       verify_flags = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
9700 +    SSL_CTX_set_verify(ctx, verify_flags, verify_callback);
9701 +    SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile));
9702 +
9703 +    /*
9704 +     * Initialize the session cache. We only want external caching to
9705 +     * synchronize between server sessions, so we set it to a minimum value
9706 +     * of 1. If the external cache is disabled, we won´t cache at all.
9707 +     * The recall of old sessions "get" and save to disk of just created
9708 +     * sessions "new" is handled by the appropriate callback functions.
9709 +     *
9710 +     * We must not forget to set a session id context to identify to which
9711 +     * kind of server process the session was related. In our case, the
9712 +     * context is just the name of the patchkit: "Postfix/TLS".
9713 +     */
9714 +    SSL_CTX_sess_set_cache_size(ctx, 1);
9715 +    SSL_CTX_set_timeout(ctx, var_smtpd_tls_scache_timeout);
9716 +    SSL_CTX_set_session_id_context(ctx, (void*)&server_session_id_context,
9717 +                sizeof(server_session_id_context));
9718 +
9719 +    /*
9720 +     * The session cache is realized by an external database file, that
9721 +     * must be opened before going to chroot jail. Since the session cache
9722 +     * data can become quite large, "[n]dbm" cannot be used as it has a
9723 +     * size limit that is by far to small.
9724 +     */
9725 +    if (*var_smtpd_tls_scache_db) {
9726 +       /*
9727 +        * Insert a test against other dbms here, otherwise while writing
9728 +        * a session (content to large), we will receive a fatal error!
9729 +        */
9730 +       if (strncmp(var_smtpd_tls_scache_db, "sdbm:", 5))
9731 +           msg_warn("Only sdbm: type allowed for %s",
9732 +                    var_smtpd_tls_scache_db);
9733 +       else
9734 +           scache_db = dict_open(var_smtpd_tls_scache_db, O_RDWR,
9735 +             DICT_FLAG_DUP_REPLACE | DICT_FLAG_LOCK | DICT_FLAG_SYNC_UPDATE);
9736 +       if (scache_db) {
9737 +           SSL_CTX_sess_set_get_cb(ctx, get_session_cb);
9738 +           SSL_CTX_sess_set_new_cb(ctx, new_session_cb);
9739 +       }
9740 +       else
9741 +           msg_warn("Could not open session cache %s",
9742 +                    var_smtpd_tls_scache_db);
9743 +    }
9744 +
9745 +    /*
9746 +     * Finally create the global index to access TLScontext information
9747 +     * inside verify_callback.
9748 +     */
9749 +    TLScontext_index = SSL_get_ex_new_index(0, "TLScontext ex_data index",
9750 +                                           NULL, NULL, NULL);
9751 +
9752 +    pfixtls_serverengine = 1;
9753 +    return (0);
9754 +}
9755 +
9756 + /*
9757 +  * This is the actual startup routine for the connection. We expect
9758 +  * that the buffers are flushed and the "220 Ready to start TLS" was
9759 +  * send to the client, so that we can immediately can start the TLS
9760 +  * handshake process.
9761 +  */
9762 +int     pfixtls_start_servertls(VSTREAM *stream, int timeout,
9763 +                               const char *peername, const char *peeraddr,
9764 +                               tls_info_t *tls_info, int requirecert)
9765 +{
9766 +    int     sts;
9767 +    int     j;
9768 +    int verify_flags;
9769 +    unsigned int n;
9770 +    TLScontext_t *TLScontext;
9771 +    SSL_SESSION *session;
9772 +    SSL_CIPHER *cipher;
9773 +    X509   *peer;
9774 +
9775 +    if (!pfixtls_serverengine) {               /* should never happen */
9776 +       msg_info("tls_engine not running");
9777 +       return (-1);
9778 +    }
9779 +    if (var_smtpd_tls_loglevel >= 1)
9780 +       msg_info("setting up TLS connection from %s[%s]", peername, peeraddr);
9781 +
9782 +    /*
9783 +     * Allocate a new TLScontext for the new connection and get an SSL
9784 +     * structure. Add the location of TLScontext to the SSL to later
9785 +     * retrieve the information inside the verify_callback().
9786 +     */
9787 +    TLScontext = (TLScontext_t *)mymalloc(sizeof(TLScontext_t));
9788 +    if (!TLScontext) {
9789 +       msg_fatal("Could not allocate 'TLScontext' with mymalloc");
9790 +    }
9791 +    if ((TLScontext->con = (SSL *) SSL_new(ctx)) == NULL) {
9792 +       msg_info("Could not allocate 'TLScontext->con' with SSL_new()");
9793 +       pfixtls_print_errors();
9794 +       myfree((char *)TLScontext);
9795 +       return (-1);
9796 +    }
9797 +    if (!SSL_set_ex_data(TLScontext->con, TLScontext_index, TLScontext)) {
9798 +       msg_info("Could not set application data for 'TLScontext->con'");
9799 +       pfixtls_print_errors();
9800 +       SSL_free(TLScontext->con);
9801 +       myfree((char *)TLScontext);
9802 +       return (-1);
9803 +    }
9804 +
9805 +    /*
9806 +     * Set the verification parameters to be checked in verify_callback().
9807 +     */
9808 +    if (requirecert) {
9809 +       verify_flags = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
9810 +       verify_flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
9811 +       TLScontext->enforce_verify_errors = 1;
9812 +        SSL_set_verify(TLScontext->con, verify_flags, verify_callback);
9813 +    }
9814 +    else {
9815 +       TLScontext->enforce_verify_errors = 0;
9816 +    }
9817 +    TLScontext->enforce_CN = 0;
9818 +
9819 +    /*
9820 +     * The TLS connection is realized by a BIO_pair, so obtain the pair.
9821 +     */
9822 +    if (!BIO_new_bio_pair(&TLScontext->internal_bio, BIO_bufsiz,
9823 +                         &TLScontext->network_bio, BIO_bufsiz)) {
9824 +       msg_info("Could not obtain BIO_pair");
9825 +       pfixtls_print_errors();
9826 +       SSL_free(TLScontext->con);
9827 +       myfree((char *)TLScontext);
9828 +       return (-1);
9829 +    }
9830 +
9831 +    /*
9832 +     * Before really starting anything, try to seed the PRNG a little bit
9833 +     * more.
9834 +     */
9835 +    pfixtls_stir_seed();
9836 +    pfixtls_exchange_seed();
9837 +
9838 +    /*
9839 +     * Initialize the SSL connection to accept state. This should not be
9840 +     * necessary anymore since 0.9.3, but the call is still in the library
9841 +     * and maintaining compatibility never hurts.
9842 +     */
9843 +    SSL_set_accept_state(TLScontext->con);
9844 +
9845 +    /*
9846 +     * Connect the SSL-connection with the postfix side of the BIO-pair for
9847 +     * reading and writing.
9848 +     */
9849 +     SSL_set_bio(TLScontext->con, TLScontext->internal_bio,
9850 +                TLScontext->internal_bio);
9851 +
9852 +    /*
9853 +     * If the debug level selected is high enough, all of the data is
9854 +     * dumped: 3 will dump the SSL negotiation, 4 will dump everything.
9855 +     *
9856 +     * We do have an SSL_set_fd() and now suddenly a BIO_ routine is called?
9857 +     * Well there is a BIO below the SSL routines that is automatically
9858 +     * created for us, so we can use it for debugging purposes.
9859 +     */
9860 +    if (var_smtpd_tls_loglevel >= 3)
9861 +       BIO_set_callback(SSL_get_rbio(TLScontext->con), bio_dump_cb);
9862 +
9863 +
9864 +    /* Dump the negotiation for loglevels 3 and 4 */
9865 +    if (var_smtpd_tls_loglevel >= 3)
9866 +       do_dump = 1;
9867 +
9868 +    /*
9869 +     * Now we expect the negotiation to begin. This whole process is like a
9870 +     * black box for us. We totally have to rely on the routines build into
9871 +     * the OpenSSL library. The only thing we can do we already have done
9872 +     * by choosing our own callbacks for session caching and certificate
9873 +     * verification.
9874 +     *
9875 +     * Error handling:
9876 +     * If the SSL handhake fails, we print out an error message and remove
9877 +     * everything that might be there. A session has to be removed anyway,
9878 +     * because RFC2246 requires it.
9879 +     */
9880 +    sts = do_tls_operation(vstream_fileno(stream), timeout, TLScontext,
9881 +                          SSL_accept, NULL, NULL, NULL, 0);
9882 +    if (sts <= 0) {
9883 +       msg_info("SSL_accept error from %s[%s]: %d", peername, peeraddr, sts);
9884 +       pfixtls_print_errors();
9885 +       session = SSL_get_session(TLScontext->con);
9886 +       if (session && scache_db) {
9887 +           remove_srvr_session(session->session_id,
9888 +                               session->session_id_length);
9889 +           SSL_CTX_remove_session(ctx, session);
9890 +           if (var_smtpd_tls_loglevel >= 2)
9891 +               msg_info("SSL session removed");
9892 +       }
9893 +       SSL_free(TLScontext->con);
9894 +       myfree((char *)TLScontext);
9895 +       return (-1);
9896 +    }
9897 +
9898 +    /* Only loglevel==4 dumps everything */
9899 +    if (var_smtpd_tls_loglevel < 4)
9900 +       do_dump = 0;
9901 +
9902 +    /*
9903 +     * Lets see, whether a peer certificate is available and what is
9904 +     * the actual information. We want to save it for later use.
9905 +     */
9906 +    peer = SSL_get_peer_certificate(TLScontext->con);
9907 +    if (peer != NULL) {
9908 +       if (SSL_get_verify_result(TLScontext->con) == X509_V_OK)
9909 +           tls_info->peer_verified = 1;
9910 +
9911 +       X509_NAME_oneline(X509_get_subject_name(peer),
9912 +                         TLScontext->peer_subject, CCERT_BUFSIZ);
9913 +       if (var_smtpd_tls_loglevel >= 2)
9914 +           msg_info("subject=%s", TLScontext->peer_subject);
9915 +       tls_info->peer_subject = TLScontext->peer_subject;
9916 +       X509_NAME_oneline(X509_get_issuer_name(peer),
9917 +                         TLScontext->peer_issuer, CCERT_BUFSIZ);
9918 +       if (var_smtpd_tls_loglevel >= 2)
9919 +           msg_info("issuer=%s", TLScontext->peer_issuer);
9920 +       tls_info->peer_issuer = TLScontext->peer_issuer;
9921 +       if (X509_digest(peer, EVP_md5(), TLScontext->md, &n)) {
9922 +           for (j = 0; j < (int) n; j++) {
9923 +               TLScontext->fingerprint[j * 3] =
9924 +                       hexcodes[(TLScontext->md[j] & 0xf0) >> 4];
9925 +               TLScontext->fingerprint[(j * 3) + 1] =
9926 +                       hexcodes[(TLScontext->md[j] & 0x0f)];
9927 +               if (j + 1 != (int) n)
9928 +                   TLScontext->fingerprint[(j * 3) + 2] = ':';
9929 +               else
9930 +                   TLScontext->fingerprint[(j * 3) + 2] = '\0';
9931 +           }
9932 +           if (var_smtpd_tls_loglevel >= 1)
9933 +               msg_info("fingerprint=%s", TLScontext->fingerprint);
9934 +           tls_info->peer_fingerprint = TLScontext->fingerprint;
9935 +       }
9936 +       X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
9937 +                         NID_commonName, TLScontext->peer_CN, CCERT_BUFSIZ);
9938 +       tls_info->peer_CN = TLScontext->peer_CN;
9939 +       X509_NAME_get_text_by_NID(X509_get_issuer_name(peer),
9940 +                         NID_commonName, TLScontext->issuer_CN, CCERT_BUFSIZ);
9941 +       if (var_smtpd_tls_loglevel >= 1) {
9942 +           if (tls_info->peer_verified)
9943 +               msg_info("Verified: subject_CN=%s, issuer_CN=%s",
9944 +                        TLScontext->peer_CN, TLScontext->issuer_CN);
9945 +           else
9946 +               msg_info("Unverified: subject_CN=%s, issuer_CN=%s",
9947 +                        TLScontext->peer_CN, TLScontext->issuer_CN);
9948 +       }
9949 +       tls_info->issuer_CN = TLScontext->issuer_CN;
9950 +       X509_free(peer);
9951 +    }
9952 +
9953 +    /*
9954 +     * At this point we should have a certificate when required.
9955 +     * We may however have a cached session, so the callback would never
9956 +     * be called. We therefore double-check to make sure and remove the
9957 +     * session, if applicable.
9958 +     */
9959 +    if (requirecert) {
9960 +       if (!tls_info->peer_verified || !tls_info->peer_CN) {
9961 +           msg_info("Re-used session without peer certificate removed");
9962 +           remove_srvr_session(session->session_id,
9963 +                                session->session_id_length);
9964 +           return (-1);
9965 +       }
9966 +    }
9967 +
9968 +    /*
9969 +     * Finally, collect information about protocol and cipher for logging
9970 +     */
9971 +    tls_info->protocol = SSL_get_version(TLScontext->con);
9972 +    cipher = SSL_get_current_cipher(TLScontext->con);
9973 +    tls_info->cipher_name = SSL_CIPHER_get_name(cipher);
9974 +    tls_info->cipher_usebits = SSL_CIPHER_get_bits(cipher,
9975 +                                                &(tls_info->cipher_algbits));
9976 +
9977 +    pfixtls_serveractive = 1;
9978 +
9979 +    /*
9980 +     * The TLS engine is active, switch to the pfixtls_timed_read/write()
9981 +     * functions and store the context.
9982 +     */
9983 +    vstream_control(stream,
9984 +                   VSTREAM_CTL_READ_FN, pfixtls_timed_read,
9985 +                   VSTREAM_CTL_WRITE_FN, pfixtls_timed_write,
9986 +                   VSTREAM_CTL_CONTEXT, (void *)TLScontext,
9987 +                   VSTREAM_CTL_END);
9988 +
9989 +    msg_info("TLS connection established from %s[%s]: %s with cipher %s (%d/%d bits)",
9990 +            peername, peeraddr,
9991 +            tls_info->protocol, tls_info->cipher_name,
9992 +            tls_info->cipher_usebits, tls_info->cipher_algbits);
9993 +    pfixtls_stir_seed();
9994 +
9995 +    return (0);
9996 +}
9997 +
9998 + /*
9999 +  * Shut down the TLS connection, that does mean: remove all the information
10000 +  * and reset the flags! This is needed if the actual running smtpd is to
10001 +  * be restarted. We do not give back any value, as there is nothing to
10002 +  * be reported.
10003 +  * Since our session cache is external, we will remove the session from
10004 +  * memory in any case. The SSL_CTX_flush_sessions might be redundant here,
10005 +  * I however want to make sure nothing is left.
10006 +  * RFC2246 requires us to remove sessions if something went wrong, as
10007 +  * indicated by the "failure" value, so we remove it from the external
10008 +  * cache, too. 
10009 +  */
10010 +int     pfixtls_stop_servertls(VSTREAM *stream, int timeout, int failure,
10011 +                              tls_info_t *tls_info)
10012 +{
10013 +    SSL_SESSION *session;
10014 +    TLScontext_t *TLScontext;
10015 +
10016 +    if (pfixtls_serveractive) {
10017 +       TLScontext = (TLScontext_t *)vstream_context(stream);
10018 +       session = SSL_get_session(TLScontext->con);
10019 +        do_tls_operation(vstream_fileno(stream), timeout, TLScontext,
10020 +                        SSL_shutdown, NULL, NULL, NULL, 0);
10021 +       if (session) {
10022 +           if (failure && scache_db) {
10023 +           remove_srvr_session(session->session_id,
10024 +                               session->session_id_length);
10025 +           if (var_smtpd_tls_loglevel >= 2)
10026 +               msg_info("SSL session removed");
10027 +           }
10028 +           SSL_CTX_remove_session(ctx, session);
10029 +       }
10030 +       /*
10031 +        * Free the SSL structure and the BIOs. Warning: the internal_bio is
10032 +        * connected to the SSL structure and is automatically freed with
10033 +        * it. Do not free it again (core dump)!!
10034 +        * Only free the network_bio.
10035 +        */
10036 +       SSL_free(TLScontext->con);
10037 +       BIO_free(TLScontext->network_bio);
10038 +       myfree((char *)TLScontext);
10039 +        vstream_control(stream,
10040 +                   VSTREAM_CTL_READ_FN, (VSTREAM_FN) NULL,
10041 +                   VSTREAM_CTL_WRITE_FN, (VSTREAM_FN) NULL,
10042 +                   VSTREAM_CTL_CONTEXT, (void *) NULL,
10043 +                   VSTREAM_CTL_END);
10044 +       SSL_CTX_flush_sessions(ctx,time(NULL));
10045 +
10046 +       pfixtls_stir_seed();
10047 +       pfixtls_exchange_seed();
10048 +
10049 +       *tls_info = tls_info_zero;
10050 +       pfixtls_serveractive = 0;
10051 +
10052 +    }
10053 +
10054 +    return (0);
10055 +}
10056 +
10057 +
10058 + /*
10059 +  * This is the setup routine for the SSL client. As smtpd might be called
10060 +  * more than once, we only want to do the initialization one time.
10061 +  *
10062 +  * The skeleton of this function is taken from OpenSSL apps/s_client.c.
10063 +  */
10064 +
10065 +int     pfixtls_init_clientengine(int verifydepth)
10066 +{
10067 +    int     off = 0;
10068 +    int     verify_flags = SSL_VERIFY_NONE;
10069 +    int     rand_bytes;
10070 +    int     rand_source_dev_fd;
10071 +    int     rand_source_socket_fd;
10072 +    unsigned char buffer[255];
10073 +    char   *CApath;
10074 +    char   *CAfile;
10075 +    char   *c_cert_file;
10076 +    char   *c_key_file;
10077 +
10078 +
10079 +    if (pfixtls_clientengine)
10080 +       return (0);                             /* already running */
10081 +
10082 +    if (var_smtp_tls_loglevel >= 2)
10083 +       msg_info("starting TLS engine");
10084 +
10085 +    /*
10086 +     * Initialize the OpenSSL library by the book!
10087 +     * To start with, we must initialize the algorithms.
10088 +     * We want cleartext error messages instead of just error codes, so we
10089 +     * load the error_strings.
10090 +     */ 
10091 +    SSL_load_error_strings();
10092 +    OpenSSL_add_ssl_algorithms();
10093 +
10094 + /*
10095 +  * Side effect, call a non-existing function to disable TLS usage with an
10096 +  * outdated OpenSSL version. There is a security reason (verify_result
10097 +  * is not stored with the session data).
10098 +  */
10099 +#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
10100 +    needs_openssl_095_or_later();
10101 +#endif
10102 +
10103 +    /*
10104 +     * Initialize the PRNG Pseudo Random Number Generator with some seed.
10105 +     */
10106 +    randseed.pid = getpid();
10107 +    GETTIMEOFDAY(&randseed.tv);
10108 +    RAND_seed(&randseed, sizeof(randseed_t));
10109 +
10110 +    /*
10111 +     * Access the external sources for random seed. We will only query them
10112 +     * once, this should be sufficient and we will stir our entropy by using
10113 +     * the prng-exchange file anyway.
10114 +     * For reliability, we don't consider failure to access the additional
10115 +     * source fatal, as we can run happily without it (considering that we
10116 +     * still have the exchange-file). We also don't care how much entropy
10117 +     * we get back, as we must run anyway. We simply stir in the buffer
10118 +     * regardless how many bytes are actually in it.
10119 +     */
10120 +    if (*var_tls_daemon_rand_source) {
10121 +       if (!strncmp(var_tls_daemon_rand_source, "dev:", 4)) {
10122 +           /*
10123 +            * Source is a random device
10124 +            */
10125 +           rand_source_dev_fd = open(var_tls_daemon_rand_source + 4, 0, 0);
10126 +           if (rand_source_dev_fd == -1) 
10127 +               msg_info("Could not open entropy device %s",
10128 +                         var_tls_daemon_rand_source);
10129 +           else {
10130 +               if (var_tls_daemon_rand_bytes > 255)
10131 +                   var_tls_daemon_rand_bytes = 255;
10132 +               read(rand_source_dev_fd, buffer, var_tls_daemon_rand_bytes);
10133 +               RAND_seed(buffer, var_tls_daemon_rand_bytes);
10134 +               close(rand_source_dev_fd);
10135 +           }
10136 +       } else if (!strncmp(var_tls_daemon_rand_source, "egd:", 4)) {
10137 +           /*
10138 +            * Source is a EGD compatible socket
10139 +            */
10140 +           rand_source_socket_fd = unix_connect(var_tls_daemon_rand_source +4,
10141 +                                                BLOCKING, 10);
10142 +           if (rand_source_socket_fd == -1)
10143 +               msg_info("Could not connect to %s", var_tls_daemon_rand_source);
10144 +           else {
10145 +               if (var_tls_daemon_rand_bytes > 255)
10146 +                   var_tls_daemon_rand_bytes = 255;
10147 +               buffer[0] = 1;
10148 +               buffer[1] = var_tls_daemon_rand_bytes;
10149 +               if (write(rand_source_socket_fd, buffer, 2) != 2)
10150 +                   msg_info("Could not talk to %s",
10151 +                            var_tls_daemon_rand_source);
10152 +               else if (read(rand_source_socket_fd, buffer, 1) != 1)
10153 +                   msg_info("Could not read info from %s",
10154 +                            var_tls_daemon_rand_source);
10155 +               else {
10156 +                   rand_bytes = buffer[0];
10157 +                   read(rand_source_socket_fd, buffer, rand_bytes);
10158 +                   RAND_seed(buffer, rand_bytes);
10159 +               }
10160 +               close(rand_source_socket_fd);
10161 +           }
10162 +       } else {
10163 +           RAND_load_file(var_tls_daemon_rand_source,
10164 +                          var_tls_daemon_rand_bytes);
10165 +       }
10166 +    }
10167 +
10168 +    if (*var_tls_rand_exch_name) {
10169 +       rand_exch_fd = open(var_tls_rand_exch_name, O_RDWR | O_CREAT, 0600);
10170 +       if (rand_exch_fd != -1)
10171 +           pfixtls_exchange_seed();
10172 +    }
10173 +
10174 +    randseed.pid = getpid();
10175 +    GETTIMEOFDAY(&randseed.tv);
10176 +    RAND_seed(&randseed, sizeof(randseed_t));
10177 +
10178 +    /*
10179 +     * The SSL/TLS speficications require the client to send a message in
10180 +     * the oldest specification it understands with the highest level it
10181 +     * understands in the message.
10182 +     * RFC2487 is only specified for TLSv1, but we want to be as compatible
10183 +     * as possible, so we will start off with a SSLv2 greeting allowing
10184 +     * the best we can offer: TLSv1.
10185 +     * We can restrict this with the options setting later, anyhow.
10186 +     */
10187 +    ctx = SSL_CTX_new(SSLv23_client_method());
10188 +    if (ctx == NULL) {
10189 +       pfixtls_print_errors();
10190 +       return (-1);
10191 +    };
10192 +
10193 +    /*
10194 +     * Here we might set SSL_OP_NO_SSLv2, SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1.
10195 +     * Of course, the last one would not make sense, since RFC2487 is only
10196 +     * defined for TLS, but we don´t know what is out there. So leave things
10197 +     * completely open, as of today.
10198 +     */
10199 +    off |= SSL_OP_ALL;         /* Work around all known bugs */
10200 +    SSL_CTX_set_options(ctx, off);
10201 +
10202 +    /*
10203 +     * Set the info_callback, that will print out messages during
10204 +     * communication on demand.
10205 +     */
10206 +    if (var_smtp_tls_loglevel >= 2)
10207 +       SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
10208 +
10209 +    /*
10210 +     * Set the list of ciphers, if explicitely given; otherwise the
10211 +     * (reasonable) default list is kept.
10212 +     */
10213 +    if (strlen(var_smtp_tls_cipherlist) != 0)
10214 +       if (SSL_CTX_set_cipher_list(ctx, var_smtp_tls_cipherlist) == 0) {
10215 +           pfixtls_print_errors();
10216 +           return (-1);
10217 +       }
10218 +
10219 +    /*
10220 +     * Now we must add the necessary certificate stuff: A client key, a
10221 +     * client certificate, and the CA certificates for both the client
10222 +     * cert and the verification of server certificates.
10223 +     * In fact, we do not need a client certificate,  so the certificates
10224 +     * are only loaded (and checked), if supplied. A clever client would
10225 +     * handle multiple client certificates and decide based on the list
10226 +     * of acceptable CAs, sent by the server, which certificate to submit.
10227 +     * OpenSSL does however not do this and also has no callback hoods to
10228 +     * easily realize it.
10229 +     *
10230 +     * As provided by OpenSSL we support two types of CA certificate handling:
10231 +     * One possibility is to add all CA certificates to one large CAfile,
10232 +     * the other possibility is a directory pointed to by CApath, containing
10233 +     * seperate files for each CA pointed on by softlinks named by the hash
10234 +     * values of the certificate.
10235 +     * The first alternative has the advantage, that the file is opened and
10236 +     * read at startup time, so that you don´t have the hassle to maintain
10237 +     * another copy of the CApath directory for chroot-jail. On the other
10238 +     * hand, the file is not really readable.
10239 +     */ 
10240 +    if (strlen(var_smtp_tls_CAfile) == 0)
10241 +       CAfile = NULL;
10242 +    else
10243 +       CAfile = var_smtp_tls_CAfile;
10244 +    if (strlen(var_smtp_tls_CApath) == 0)
10245 +       CApath = NULL;
10246 +    else
10247 +       CApath = var_smtp_tls_CApath;
10248 +    if (CAfile || CApath) {
10249 +       if (!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) {
10250 +           msg_info("TLS engine: cannot load CA data");
10251 +           pfixtls_print_errors();
10252 +           return (-1);
10253 +       }
10254 +       if (!SSL_CTX_set_default_verify_paths(ctx)) {
10255 +           msg_info("TLS engine: cannot set verify paths");
10256 +           pfixtls_print_errors();
10257 +           return (-1);
10258 +       }
10259 +    }
10260 +
10261 +    if (strlen(var_smtp_tls_cert_file) == 0)
10262 +       c_cert_file = NULL;
10263 +    else
10264 +       c_cert_file = var_smtp_tls_cert_file;
10265 +    if (strlen(var_smtp_tls_key_file) == 0)
10266 +       c_key_file = NULL;
10267 +    else
10268 +       c_key_file = var_smtp_tls_key_file;
10269 +    if (c_cert_file || c_key_file)
10270 +       if (!set_cert_stuff(ctx, c_cert_file, c_key_file)) {
10271 +           msg_info("TLS engine: cannot load cert/key data");
10272 +           pfixtls_print_errors();
10273 +           return (-1);
10274 +       }
10275 +
10276 +    /*
10277 +     * Sometimes a temporary RSA key might be needed by the OpenSSL
10278 +     * library. The OpenSSL doc indicates, that this might happen when
10279 +     * export ciphers are in use. We have to provide one, so well, we
10280 +     * just do it.
10281 +     */
10282 +    SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb);
10283 +
10284 +    /*
10285 +     * Finally, the setup for the server certificate checking, done
10286 +     * "by the book".
10287 +     */
10288 +    SSL_CTX_set_verify(ctx, verify_flags, verify_callback);
10289 +
10290 +    /*
10291 +     * Initialize the session cache. We only want external caching to
10292 +     * synchronize between server sessions, so we set it to a minimum value
10293 +     * of 1. If the external cache is disabled, we won´t cache at all.
10294 +     *
10295 +     * In case of the client, there is no callback used in OpenSSL, so
10296 +     * we must call the session cache functions manually during the process.
10297 +     */
10298 +    SSL_CTX_sess_set_cache_size(ctx, 1);
10299 +    SSL_CTX_set_timeout(ctx, var_smtp_tls_scache_timeout);
10300 +
10301 +    /*
10302 +     * The session cache is realized by an external database file, that
10303 +     * must be opened before going to chroot jail. Since the session cache
10304 +     * data can become quite large, "[n]dbm" cannot be used as it has a
10305 +     * size limit that is by far to small.
10306 +     */
10307 +    if (*var_smtp_tls_scache_db) {
10308 +       /*
10309 +        * Insert a test against other dbms here, otherwise while writing
10310 +        * a session (content to large), we will receive a fatal error!
10311 +        */
10312 +       if (strncmp(var_smtp_tls_scache_db, "sdbm:", 5))
10313 +           msg_warn("Only sdbm: type allowed for %s",
10314 +                    var_smtp_tls_scache_db);
10315 +       else
10316 +           scache_db = dict_open(var_smtp_tls_scache_db, O_RDWR,
10317 +             DICT_FLAG_DUP_REPLACE | DICT_FLAG_LOCK | DICT_FLAG_SYNC_UPDATE);
10318 +       if (!scache_db)
10319 +           msg_warn("Could not open session cache %s",
10320 +                    var_smtp_tls_scache_db);
10321 +    }
10322 +   
10323 +    /*
10324 +     * Finally create the global index to access TLScontext information
10325 +     * inside verify_callback.
10326 +     */
10327 +    TLScontext_index = SSL_get_ex_new_index(0, "TLScontext ex_data index",
10328 +                                           NULL, NULL, NULL);
10329 +
10330 +    pfixtls_clientengine = 1;
10331 +    return (0);
10332 +}
10333 +
10334 + /*
10335 +  * This is the actual startup routine for the connection. We expect
10336 +  * that the buffers are flushed and the "220 Ready to start TLS" was
10337 +  * received by us, so that we can immediately can start the TLS
10338 +  * handshake process.
10339 +  */
10340 +int     pfixtls_start_clienttls(VSTREAM *stream, int timeout,
10341 +                               int enforce_peername,
10342 +                               const char *peername,
10343 +                               tls_info_t *tls_info)
10344 +{
10345 +    int     sts;
10346 +    int     j;
10347 +    unsigned int n;
10348 +    SSL_SESSION *session, *old_session;
10349 +    SSL_CIPHER *cipher;
10350 +    X509   *peer;
10351 +    int     save_session;
10352 +    int            length;
10353 +    int     verify_flags;
10354 +    char   *lowercase_CN;
10355 +    unsigned char *old_session_id;
10356 +    TLScontext_t *TLScontext;
10357 +
10358 +    if (!pfixtls_clientengine) {               /* should never happen */
10359 +       msg_info("tls_engine not running");
10360 +       return (-1);
10361 +    }
10362 +    if (var_smtpd_tls_loglevel >= 1)
10363 +       msg_info("setting up TLS connection to %s", peername);
10364 +
10365 +    /*
10366 +     * Allocate a new TLScontext for the new connection and get an SSL
10367 +     * structure. Add the location of TLScontext to the SSL to later
10368 +     * retrieve the information inside the verify_callback().
10369 +     */
10370 +    TLScontext = (TLScontext_t *)mymalloc(sizeof(TLScontext_t));
10371 +    if (!TLScontext) {
10372 +       msg_fatal("Could not allocate 'TLScontext' with mymalloc");
10373 +    }
10374 +    if ((TLScontext->con = (SSL *) SSL_new(ctx)) == NULL) {
10375 +       msg_info("Could not allocate 'TLScontext->con' with SSL_new()");
10376 +       pfixtls_print_errors();
10377 +       myfree((char *)TLScontext);
10378 +       return (-1);
10379 +    }
10380 +    if (!SSL_set_ex_data(TLScontext->con, TLScontext_index, TLScontext)) {
10381 +       msg_info("Could not set application data for 'TLScontext->con'");
10382 +       pfixtls_print_errors();
10383 +       SSL_free(TLScontext->con);
10384 +       myfree((char *)TLScontext);
10385 +       return (-1);
10386 +    }
10387 +
10388 +    /*
10389 +     * Set the verification parameters to be checked in verify_callback().
10390 +     */
10391 +    if (enforce_peername) {
10392 +       verify_flags = SSL_VERIFY_PEER;
10393 +       TLScontext->enforce_verify_errors = 1;
10394 +       TLScontext->enforce_CN = 1;
10395 +        SSL_set_verify(TLScontext->con, verify_flags, verify_callback);
10396 +    }
10397 +    else {
10398 +       TLScontext->enforce_verify_errors = 0;
10399 +       TLScontext->enforce_CN = 0;
10400 +    }
10401 +
10402 +    /*
10403 +     * The TLS connection is realized by a BIO_pair, so obtain the pair.
10404 +     */
10405 +    if (!BIO_new_bio_pair(&TLScontext->internal_bio, BIO_bufsiz,
10406 +                         &TLScontext->network_bio, BIO_bufsiz)) {
10407 +       msg_info("Could not obtain BIO_pair");
10408 +       pfixtls_print_errors();
10409 +       SSL_free(TLScontext->con);
10410 +       myfree((char *)TLScontext);
10411 +       return (-1);
10412 +    }
10413 +
10414 +    old_session_id = NULL;     /* make sure no old info is kept */
10415 +    old_session = NULL;
10416 +
10417 +    /*
10418 +     * Find out the hashed HostID for the client cache and try to
10419 +     * load the session from the cache.
10420 +     * "old_session_id" holds the session ID of the reloaded session, so that
10421 +     * we can later check, whether it is really reused.
10422 +     */
10423 +    strncpy(TLScontext->peername_save, peername, 128);
10424 +    TLScontext->peername_save[128] = '\0';  /* in case name is too long */
10425 +    if (scache_db) {
10426 +       old_session = load_clnt_session(peername);
10427 +       if (old_session) {
10428 +          SSL_set_session(TLScontext->con, old_session);
10429 +          old_session_id =
10430 +               (unsigned char *)mymemdup((char *)old_session->session_id,
10431 +                                    old_session->session_id_length);
10432 +#if (OPENSSL_VERSION_NUMBER < 0x00906011L) || (OPENSSL_VERSION_NUMBER == 0x00907000L)
10433 +           /*
10434 +            * Ugly Hack: OpenSSL before 0.9.6a (if ever released) does not
10435 +            * store the verify result in sessions for the client side.
10436 +            * We modify the session directly which is version specific,
10437 +            * but this bug is version specific, too.
10438 +            *
10439 +            * READ: 0-09-06-01-1 = 0-9-6-a-beta1: all versions before
10440 +            * beta1 have this bug, it has been fixed during development
10441 +            * of 0.9.6a. The development version of 0.9.7 can have this
10442 +            * bug, too. It has been fixed on 2000/11/29.
10443 +            */
10444 +           SSL_set_verify_result(TLScontext->con, old_session->verify_result);
10445 +#endif
10446 +          
10447 +       }
10448 +    }
10449 +
10450 +    /*
10451 +     * Before really starting anything, try to seed the PRNG a little bit
10452 +     * more.
10453 +     */
10454 +    pfixtls_stir_seed();
10455 +    pfixtls_exchange_seed();
10456 +
10457 +    /*
10458 +     * Initialize the SSL connection to connect state. This should not be
10459 +     * necessary anymore since 0.9.3, but the call is still in the library
10460 +     * and maintaining compatibility never hurts.
10461 +     */
10462 +    SSL_set_connect_state(TLScontext->con);
10463 +
10464 +    /*
10465 +     * Connect the SSL-connection with the postfix side of the BIO-pair for
10466 +     * reading and writing.
10467 +     */
10468 +     SSL_set_bio(TLScontext->con, TLScontext->internal_bio,
10469 +                TLScontext->internal_bio);
10470 +
10471 +    /*
10472 +     * If the debug level selected is high enough, all of the data is
10473 +     * dumped: 3 will dump the SSL negotiation, 4 will dump everything.
10474 +     *
10475 +     * We do have an SSL_set_fd() and now suddenly a BIO_ routine is called?
10476 +     * Well there is a BIO below the SSL routines that is automatically
10477 +     * created for us, so we can use it for debugging purposes.
10478 +     */
10479 +    if (var_smtp_tls_loglevel >= 3)
10480 +       BIO_set_callback(SSL_get_rbio(TLScontext->con), bio_dump_cb);
10481 +
10482 +
10483 +    /* Dump the negotiation for loglevels 3 and 4 */
10484 +    if (var_smtp_tls_loglevel >= 3)
10485 +       do_dump = 1;
10486 +
10487 +    /*
10488 +     * Now we expect the negotiation to begin. This whole process is like a
10489 +     * black box for us. We totally have to rely on the routines build into
10490 +     * the OpenSSL library. The only thing we can do we already have done
10491 +     * by choosing our own callback certificate verification.
10492 +     *
10493 +     * Error handling:
10494 +     * If the SSL handhake fails, we print out an error message and remove
10495 +     * everything that might be there. A session has to be removed anyway,
10496 +     * because RFC2246 requires it. 
10497 +     */
10498 +    sts = do_tls_operation(vstream_fileno(stream), timeout, TLScontext,
10499 +                          SSL_connect, NULL, NULL, NULL, 0);
10500 +    if (sts <= 0) {
10501 +       msg_info("SSL_connect error to %s: %d", peername, sts);
10502 +       pfixtls_print_errors();
10503 +       session = SSL_get_session(TLScontext->con);
10504 +       if (session) {
10505 +           if (scache_db)
10506 +               remove_clnt_session(peername);
10507 +           SSL_CTX_remove_session(ctx, session);
10508 +           if (var_smtp_tls_loglevel >= 2)
10509 +               msg_info("SSL session removed");
10510 +       }
10511 +       if ((old_session) && (session != old_session))
10512 +           SSL_SESSION_free(old_session);      /* Must also be removed */
10513 +       SSL_free(TLScontext->con);
10514 +       myfree((char *)TLScontext);
10515 +       return (-1);
10516 +    }
10517 +
10518 +    /*
10519 +     * Now we must save the new session to disk, if necessary. If we had
10520 +     * an old session, its ID was saved in "old_session_id" for comparison.
10521 +     */
10522 +    session = SSL_get_session(TLScontext->con);
10523 +    if (session && scache_db) {
10524 +       save_session = 1;
10525 +       if (old_session_id) {
10526 +           if (memcmp(session->session_id, old_session_id,
10527 +                      session->session_id_length) == 0) {
10528 +               if (var_smtp_tls_loglevel >= 3)
10529 +                   msg_info("Reusing old session");
10530 +               save_session = 0;
10531 +           }
10532 +           myfree((char *)old_session_id);
10533 +       }
10534 +       if (save_session) {
10535 +#if (OPENSSL_VERSION_NUMBER < 0x00906011L) || (OPENSSL_VERSION_NUMBER == 0x00907000L)
10536 +           /*
10537 +            * Ugly Hack: OpenSSL before 0.9.6a (if ever released) does not
10538 +            * store the verify result in sessions for the client side.
10539 +            * We modify the session directly which is version specific,
10540 +            * but this bug is version specific, too.
10541 +            *
10542 +            * READ: 0-09-06-01-1 = 0-9-6-a-beta1: all versions before
10543 +            * beta1 have this bug, it has been fixed during development
10544 +            * of 0.9.6a. The development version of 0.9.7 can have this
10545 +            * bug, too. It has been fixed on 2000/11/29.
10546 +            */
10547 +           session->verify_result = SSL_get_verify_result(TLScontext->con);
10548 +#endif
10549 +           save_clnt_session(session, peername);
10550 +       }
10551 +    }
10552 +    if ((old_session) && (session != old_session))
10553 +       SSL_SESSION_free(old_session);  /* Remove unused session */
10554 +
10555 +    /* Only loglevel==4 dumps everything */
10556 +    if (var_smtp_tls_loglevel < 4)
10557 +       do_dump = 0;
10558 +
10559 +    /*
10560 +     * Lets see, whether a peer certificate is available and what is
10561 +     * the actual information. We want to save it for later use.
10562 +     */
10563 +    peer = SSL_get_peer_certificate(TLScontext->con);
10564 +    if (peer != NULL) {
10565 +       if (SSL_get_verify_result(TLScontext->con) == X509_V_OK)
10566 +           tls_info->peer_verified = 1;
10567 +
10568 +       X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
10569 +                         NID_commonName, TLScontext->peer_CN, CCERT_BUFSIZ);
10570 +       tls_info->peer_CN = TLScontext->peer_CN;
10571 +       X509_NAME_get_text_by_NID(X509_get_issuer_name(peer),
10572 +                         NID_commonName, TLScontext->issuer_CN, CCERT_BUFSIZ);
10573 +       if (var_smtp_tls_loglevel >= 1) {
10574 +           if (tls_info->peer_verified)
10575 +               msg_info("Verified: subject_CN=%s, issuer_CN=%s",
10576 +                        TLScontext->peer_CN, TLScontext->issuer_CN);
10577 +           else
10578 +               msg_info("Unverified: subject_CN=%s, issuer_CN=%s",
10579 +                        TLScontext->peer_CN, TLScontext->issuer_CN);
10580 +       }
10581 +       tls_info->issuer_CN = TLScontext->issuer_CN;
10582 +       X509_free(peer);
10583 +    }
10584 +
10585 +    /*
10586 +     * At this point the CN should already match the peername, if enforced.
10587 +     * We may however have a cached session, so the callback would never
10588 +     * be called. We therefore double-check to make sure and remove the
10589 +     * session, if applicable.
10590 +     */
10591 +    if (enforce_peername) {
10592 +       if (!tls_info->peer_verified || !tls_info->peer_CN) {
10593 +           msg_info("Removed session without verifiable peername");
10594 +           remove_clnt_session(peername);
10595 +           return (-1);
10596 +       }
10597 +       lowercase_CN = lowercase(mystrdup(tls_info->peer_CN));
10598 +       if (strcmp(peername, lowercase_CN)) {
10599 +           msg_info("Removed session without non-matching peername");
10600 +           remove_clnt_session(peername);
10601 +           myfree(lowercase_CN);
10602 +           return (-1);
10603 +       }
10604 +       myfree(lowercase_CN);
10605 +    }
10606 +
10607 +    /*
10608 +     * Finally, collect information about protocol and cipher for logging
10609 +     */ 
10610 +    tls_info->protocol = SSL_get_version(TLScontext->con);
10611 +    cipher = SSL_get_current_cipher(TLScontext->con);
10612 +    tls_info->cipher_name = SSL_CIPHER_get_name(cipher);
10613 +    tls_info->cipher_usebits = SSL_CIPHER_get_bits(cipher,
10614 +                                                &(tls_info->cipher_algbits));
10615 +
10616 +    pfixtls_clientactive = 1;
10617 +
10618 +    /*
10619 +     * The TLS engine is active, switch to the pfixtls_timed_read/write()
10620 +     * functions.
10621 +     */
10622 +    vstream_control(stream,
10623 +                   VSTREAM_CTL_READ_FN, pfixtls_timed_read,
10624 +                   VSTREAM_CTL_WRITE_FN, pfixtls_timed_write,
10625 +                   VSTREAM_CTL_CONTEXT, (void *)TLScontext,
10626 +                   VSTREAM_CTL_END);
10627 +
10628 +    msg_info("TLS connection established to %s: %s with cipher %s (%d/%d bits)",
10629 +            peername,
10630 +            tls_info->protocol, tls_info->cipher_name,
10631 +            tls_info->cipher_usebits, tls_info->cipher_algbits);
10632 +
10633 +    pfixtls_stir_seed();
10634 +
10635 +    return (0);
10636 +}
10637 +
10638 + /*
10639 +  * Shut down the TLS connection, that does mean: remove all the information
10640 +  * and reset the flags! This is needed if the actual running smtp is to
10641 +  * be restarted. We do not give back any value, as there is nothing to
10642 +  * be reported.
10643 +  * Since our session cache is external, we will remove the session from
10644 +  * memory in any case. The SSL_CTX_flush_sessions might be redundant here,
10645 +  * I however want to make sure nothing is left.
10646 +  * RFC2246 requires us to remove sessions if something went wrong, as
10647 +  * indicated by the "failure" value,so we remove it from the external
10648 +  * cache, too.
10649 +  */
10650 +int     pfixtls_stop_clienttls(VSTREAM *stream, int timeout, int failure,
10651 +                              tls_info_t *tls_info)
10652 +{
10653 +    SSL_SESSION *session;
10654 +    TLScontext_t *TLScontext;
10655 +
10656 +    if (pfixtls_clientactive) {
10657 +       TLScontext = (TLScontext_t *)vstream_context(stream);
10658 +       session = SSL_get_session(TLScontext->con);
10659 +        do_tls_operation(vstream_fileno(stream), timeout, TLScontext,
10660 +                        SSL_shutdown, NULL, NULL, NULL, 0);
10661 +       if (session) {
10662 +           if (failure && scache_db) {
10663 +               remove_clnt_session(TLScontext->peername_save);
10664 +               if (var_smtp_tls_loglevel >= 2)
10665 +                   msg_info("SSL session removed");
10666 +           }
10667 +       }
10668 +       /*
10669 +        * Free the SSL structure and the BIOs. Warning: the internal_bio is
10670 +        * connected to the SSL structure and is automatically freed with
10671 +        * it. Do not free it again (core dump)!!
10672 +        * Only free the network_bio.
10673 +        */
10674 +       SSL_free(TLScontext->con);
10675 +       BIO_free(TLScontext->network_bio);
10676 +       myfree((char *)TLScontext);
10677 +       vstream_control(stream,
10678 +                   VSTREAM_CTL_READ_FN, (VSTREAM_FN) NULL,
10679 +                   VSTREAM_CTL_WRITE_FN, (VSTREAM_FN) NULL,
10680 +                   VSTREAM_CTL_CONTEXT, (void *) NULL,
10681 +                   VSTREAM_CTL_END);
10682 +       SSL_CTX_flush_sessions(ctx,time(NULL));
10683 +
10684 +       pfixtls_stir_seed();
10685 +       pfixtls_exchange_seed();
10686 +
10687 +       *tls_info = tls_info_zero;
10688 +       pfixtls_clientactive = 0;
10689 +
10690 +    }
10691 +
10692 +    return (0);
10693 +}
10694 +
10695 +
10696 +#endif /* HAS_SSL */
10697 diff -Nur snapshot-20010228-orig/src/global/pfixtls.h snapshot-20010228/src/global/pfixtls.h
10698 --- snapshot-20010228-orig/src/global/pfixtls.h Thu Jan  1 01:00:00 1970
10699 +++ snapshot-20010228/src/global/pfixtls.h      Wed Mar 21 13:32:23 2001
10700 @@ -0,0 +1,76 @@
10701 +/*++
10702 +/* NAME
10703 +/*      pfixtls 3h
10704 +/* SUMMARY
10705 +/*      TLS routines
10706 +/* SYNOPSIS
10707 +/*      include "pfixtls.h"
10708 +/* DESCRIPTION
10709 +/* .nf
10710 +/*--*/
10711 +
10712 +#ifndef PFIXTLS_H_INCLUDED
10713 +#define PFIXTLS_H_INCLUDED
10714 +
10715 +typedef struct {
10716 +    int     peer_verified;
10717 +    char   *peer_subject;
10718 +    char   *peer_issuer;
10719 +    char   *peer_fingerprint;
10720 +    char   *peer_CN;
10721 +    char   *issuer_CN;
10722 +    char  **dNSName;
10723 +    const char *protocol;
10724 +    const char *cipher_name;
10725 +    int     cipher_usebits;
10726 +    int     cipher_algbits;
10727 +} tls_info_t;
10728 +
10729 +extern const tls_info_t tls_info_zero;
10730 +
10731 +#ifdef HAS_SSL
10732 +
10733 +typedef struct {
10734 +    long scache_db_version;
10735 +    long openssl_version;
10736 +    time_t timestamp;          /* We could add other info here... */
10737 +} pfixtls_scache_info_t;
10738 +
10739 +extern const long scache_db_version;
10740 +extern const long openssl_version;
10741 +
10742 +int     pfixtls_timed_read(int fd, void *buf, unsigned len, int timout,
10743 +                          void *unused_timeout);
10744 +int     pfixtls_timed_write(int fd, void *buf, unsigned len, int timeout,
10745 +                           void *unused_timeout);
10746 +
10747 +extern int pfixtls_serverengine;
10748 +int     pfixtls_init_serverengine(int verifydepth, int askcert);
10749 +int     pfixtls_start_servertls(VSTREAM *stream, int timeout,
10750 +                               const char *peername, const char *peeraddr,
10751 +                               tls_info_t *tls_info, int require_cert);
10752 +int     pfixtls_stop_servertls(VSTREAM *stream, int timeout, int failure,
10753 +                              tls_info_t *tls_info);
10754 +
10755 +extern int pfixtls_clientengine;
10756 +int     pfixtls_init_clientengine(int verifydepth);
10757 +int     pfixtls_start_clienttls(VSTREAM *stream, int timeout,
10758 +                               int enforce_peername,
10759 +                               const char *peername,
10760 +                               tls_info_t *tls_info);
10761 +int     pfixtls_stop_clienttls(VSTREAM *stream, int timeout, int failure,
10762 +                              tls_info_t *tls_info);
10763 +
10764 +#endif /* PFIXTLS_H_INCLUDED */
10765 +#endif
10766 +
10767 +/* LICENSE
10768 +/* .ad
10769 +/* .fi
10770 +/* AUTHOR(S)
10771 +/*     Lutz Jaenicke
10772 +/*     BTU Cottbus
10773 +/*     Allgemeine Elektrotechnik
10774 +/*     Universitaetsplatz 3-4
10775 +/*     D-03044 Cottbus, Germany
10776 +/*--*/
10777 diff -Nur snapshot-20010228-orig/src/smtp/Makefile.in snapshot-20010228/src/smtp/Makefile.in
10778 --- snapshot-20010228-orig/src/smtp/Makefile.in Wed Mar 21 13:26:25 2001
10779 +++ snapshot-20010228/src/smtp/Makefile.in      Wed Mar 21 13:32:23 2001
10780 @@ -81,6 +81,7 @@
10781  smtp.o: ../../include/mail_proto.h
10782  smtp.o: ../../include/iostuff.h
10783  smtp.o: ../../include/mail_server.h
10784 +smtp.o: ../../include/pfixtls.h
10785  smtp.o: smtp.h
10786  smtp.o: smtp_sasl.h
10787  smtp_addr.o: smtp_addr.c
10788 @@ -99,6 +100,7 @@
10789  smtp_addr.o: ../../include/argv.h
10790  smtp_addr.o: ../../include/deliver_request.h
10791  smtp_addr.o: ../../include/recipient_list.h
10792 +smtp_addr.o: ../../include/pfixtls.h
10793  smtp_addr.o: smtp_addr.h
10794  smtp_chat.o: smtp_chat.c
10795  smtp_chat.o: ../../include/sys_defs.h
10796 @@ -119,6 +121,7 @@
10797  smtp_chat.o: ../../include/cleanup_user.h
10798  smtp_chat.o: ../../include/mail_error.h
10799  smtp_chat.o: ../../include/name_mask.h
10800 +smtp_chat.o: ../../include/pfixtls.h
10801  smtp_chat.o: smtp.h
10802  smtp_connect.o: smtp_connect.c
10803  smtp_connect.o: ../../include/sys_defs.h
10804 @@ -139,6 +142,7 @@
10805  smtp_connect.o: ../../include/argv.h
10806  smtp_connect.o: ../../include/deliver_request.h
10807  smtp_connect.o: ../../include/recipient_list.h
10808 +smtp_connetc.o: ../../include/pfixtls.h
10809  smtp_connect.o: smtp_addr.h
10810  smtp_proto.o: smtp_proto.c
10811  smtp_proto.o: ../../include/sys_defs.h
10812 @@ -163,6 +167,7 @@
10813  smtp_proto.o: ../../include/off_cvt.h
10814  smtp_proto.o: ../../include/mark_corrupt.h
10815  smtp_proto.o: ../../include/quote_821_local.h
10816 +smtp_proto.o: ../../include/pfixtls.h
10817  smtp_proto.o: smtp.h
10818  smtp_proto.o: ../../include/argv.h
10819  smtp_proto.o: smtp_sasl.h
10820 @@ -206,9 +211,12 @@
10821  smtp_session.o: ../../include/stringops.h
10822  smtp_session.o: ../../include/vstring.h
10823  smtp_session.o: smtp.h
10824 +smtp_session.o: ../../include/mail_params.h
10825 +smtp_session.o: ../../include/pfixtls.h
10826  smtp_session.o: ../../include/argv.h
10827  smtp_session.o: ../../include/deliver_request.h
10828  smtp_session.o: ../../include/recipient_list.h
10829 +smtp_session.o: ../../include/maps.h
10830  smtp_state.o: smtp_state.c
10831  smtp_state.o: ../../include/sys_defs.h
10832  smtp_state.o: ../../include/mymalloc.h
10833 @@ -220,6 +228,7 @@
10834  smtp_state.o: ../../include/argv.h
10835  smtp_state.o: ../../include/deliver_request.h
10836  smtp_state.o: ../../include/recipient_list.h
10837 +smtp_state.o: ../../include/pfixtls.h
10838  smtp_state.o: smtp_sasl.h
10839  smtp_trouble.o: smtp_trouble.c
10840  smtp_trouble.o: ../../include/sys_defs.h
10841 @@ -239,6 +248,7 @@
10842  smtp_trouble.o: ../../include/name_mask.h
10843  smtp_trouble.o: smtp.h
10844  smtp_trouble.o: ../../include/argv.h
10845 +smtp_trouble.o: ../../include/pfixtls.h
10846  smtp_unalias.o: smtp_unalias.c
10847  smtp_unalias.o: ../../include/sys_defs.h
10848  smtp_unalias.o: ../../include/htable.h
10849 @@ -251,3 +261,4 @@
10850  smtp_unalias.o: ../../include/argv.h
10851  smtp_unalias.o: ../../include/deliver_request.h
10852  smtp_unalias.o: ../../include/recipient_list.h
10853 +smtp_unalias.o: ../../include/pfixtls.h
10854 diff -Nur snapshot-20010228-orig/src/smtp/smtp.c snapshot-20010228/src/smtp/smtp.c
10855 --- snapshot-20010228-orig/src/smtp/smtp.c      Wed Mar 21 13:26:25 2001
10856 +++ snapshot-20010228/src/smtp/smtp.c   Wed Mar 21 13:32:23 2001
10857 @@ -211,6 +211,7 @@
10858  #include <debug_peer.h>
10859  #include <mail_error.h>
10860  #include <deliver_pass.h>
10861 +#include <pfixtls.h>
10862  
10863  /* Single server skeleton. */
10864  
10865 @@ -227,6 +228,7 @@
10866    */
10867  int     var_smtp_conn_tmout;
10868  int     var_smtp_helo_tmout;
10869 +int     var_smtp_starttls_tmout;
10870  int     var_smtp_mail_tmout;
10871  int     var_smtp_rcpt_tmout;
10872  int     var_smtp_data0_tmout;
10873 @@ -250,6 +252,12 @@
10874  char   *var_smtp_sasl_passwd;
10875  bool    var_smtp_sasl_enable;
10876  char   *var_smtp_bind_addr;
10877 +int     var_smtp_use_tls;
10878 +int     var_smtp_enforce_tls;
10879 +int     var_smtp_tls_enforce_peername;
10880 +char   *var_smtp_tls_per_site;
10881 +int     var_smtp_tls_scert_vd;
10882 +int     var_smtp_tls_note_starttls_offer;
10883  
10884   /*
10885    * Global variables. smtp_errno is set by the address lookup routines and by
10886 @@ -367,6 +375,14 @@
10887         msg_warn("%s is true, but SASL support is not compiled in",
10888                  VAR_SMTP_SASL_ENABLE);
10889  #endif
10890 +    /*
10891 +     * Initialize the TLS data before entering the chroot jail
10892 +     */
10893 +#ifdef HAS_SSL
10894 +    if (var_smtp_use_tls || var_smtp_enforce_tls || var_smtp_tls_per_site[0])
10895 +       pfixtls_init_clientengine(var_smtp_tls_scert_vd);
10896 +    smtp_tls_list_init();
10897 +#endif
10898  }
10899  
10900  /* pre_accept - see if tables have changed */
10901 @@ -402,6 +418,7 @@
10902         VAR_SMTP_SASL_PASSWD, DEF_SMTP_SASL_PASSWD, &var_smtp_sasl_passwd, 0, 0,
10903         VAR_SMTP_SASL_OPTS, DEF_SMTP_SASL_OPTS, &var_smtp_sasl_opts, 0, 0,
10904         VAR_SMTP_BIND_ADDR, DEF_SMTP_BIND_ADDR, &var_smtp_bind_addr, 0, 0,
10905 +       VAR_SMTP_TLS_PER_SITE, DEF_SMTP_TLS_PER_SITE, &var_smtp_tls_per_site, 0, 0,
10906         0,
10907      };
10908      static CONFIG_TIME_TABLE time_table[] = {
10909 @@ -413,10 +430,12 @@
10910         VAR_SMTP_DATA1_TMOUT, DEF_SMTP_DATA1_TMOUT, &var_smtp_data1_tmout, 1, 0,
10911         VAR_SMTP_DATA2_TMOUT, DEF_SMTP_DATA2_TMOUT, &var_smtp_data2_tmout, 1, 0,
10912         VAR_SMTP_QUIT_TMOUT, DEF_SMTP_QUIT_TMOUT, &var_smtp_quit_tmout, 1, 0,
10913 +       VAR_SMTP_STARTTLS_TMOUT, DEF_SMTP_STARTTLS_TMOUT, &var_smtp_starttls_tmout, 1, 0,
10914         0,
10915      };
10916      static CONFIG_INT_TABLE int_table[] = {
10917         VAR_DEBUG_PEER_LEVEL, DEF_DEBUG_PEER_LEVEL, &var_debug_peer_level, 1, 0,
10918 +       VAR_SMTP_TLS_SCERT_VD, DEF_SMTP_TLS_SCERT_VD, &var_smtp_tls_scert_vd, 0, 0,
10919         0,
10920      };
10921      static CONFIG_BOOL_TABLE bool_table[] = {
10922 @@ -427,6 +446,10 @@
10923         VAR_SMTP_ALWAYS_EHLO, DEF_SMTP_ALWAYS_EHLO, &var_smtp_always_ehlo,
10924         VAR_SMTP_NEVER_EHLO, DEF_SMTP_NEVER_EHLO, &var_smtp_never_ehlo,
10925         VAR_SMTP_SASL_ENABLE, DEF_SMTP_SASL_ENABLE, &var_smtp_sasl_enable,
10926 +       VAR_SMTP_USE_TLS, DEF_SMTP_USE_TLS, &var_smtp_use_tls,
10927 +       VAR_SMTP_ENFORCE_TLS, DEF_SMTP_ENFORCE_TLS, &var_smtp_enforce_tls,
10928 +       VAR_SMTP_TLS_ENFORCE_PN, DEF_SMTP_TLS_ENFORCE_PN, &var_smtp_tls_enforce_peername,
10929 +       VAR_SMTP_TLS_NOTEOFFER, DEF_SMTP_TLS_NOTEOFFER, &var_smtp_tls_note_starttls_offer,
10930         0,
10931      };
10932  
10933 diff -Nur snapshot-20010228-orig/src/smtp/smtp.h snapshot-20010228/src/smtp/smtp.h
10934 --- snapshot-20010228-orig/src/smtp/smtp.h      Wed Mar 21 13:26:25 2001
10935 +++ snapshot-20010228/src/smtp/smtp.h   Wed Mar 21 13:32:23 2001
10936 @@ -27,6 +27,7 @@
10937    * Global library.
10938    */
10939  #include <deliver_request.h>
10940 +#include <pfixtls.h>
10941  
10942   /*
10943    * State information associated with each SMTP delivery. We're bundling the
10944 @@ -75,9 +76,14 @@
10945      char   *addr;                      /* mail exchanger */
10946      char   *namaddr;                   /* mail exchanger */
10947      int     best;                      /* most preferred host */
10948 +    int     tls_use_tls;               /* can do TLS */
10949 +    int     tls_enforce_tls;           /* must do TLS */
10950 +    int     tls_enforce_peername;      /* cert must match */
10951 +    tls_info_t tls_info;               /* TLS connection state */
10952  } SMTP_SESSION;
10953  
10954 -extern SMTP_SESSION *smtp_session_alloc(VSTREAM *, char *, char *);
10955 +extern void smtp_tls_list_init(void);
10956 +extern SMTP_SESSION *smtp_session_alloc(char *, VSTREAM *, char *, char *);
10957  extern void smtp_session_free(SMTP_SESSION *);
10958  
10959   /*
10960 diff -Nur snapshot-20010228-orig/src/smtp/smtp_connect.c snapshot-20010228/src/smtp/smtp_connect.c
10961 --- snapshot-20010228-orig/src/smtp/smtp_connect.c      Wed Mar 21 13:26:25 2001
10962 +++ snapshot-20010228/src/smtp/smtp_connect.c   Wed Mar 21 13:32:23 2001
10963 @@ -116,6 +116,7 @@
10964  
10965  #include <mail_params.h>
10966  #include <own_inet_addr.h>
10967 +#include <pfixtls.h>
10968  
10969  /* DNS library. */
10970  
10971 @@ -128,7 +129,7 @@
10972  
10973  /* smtp_connect_addr - connect to explicit address */
10974  
10975 -static SMTP_SESSION *smtp_connect_addr(DNS_RR *addr, unsigned port,
10976 +static SMTP_SESSION *smtp_connect_addr(char *dest, DNS_RR *addr, unsigned port,
10977                                                VSTRING *why)
10978  {
10979      char   *myname = "smtp_connect_addr";
10980 @@ -262,7 +263,7 @@
10981         vstream_fclose(stream);
10982         return (0);
10983      }
10984 -    return (smtp_session_alloc(stream, addr->name, inet_ntoa(sin.sin_addr)));
10985 +    return (smtp_session_alloc(dest, stream, addr->name, inet_ntoa(sin.sin_addr)));
10986  }
10987  
10988  /* smtp_connect_host - direct connection to host */
10989 @@ -280,7 +281,7 @@
10990       */
10991      addr_list = smtp_host_addr(host, why);
10992      for (addr = addr_list; addr; addr = addr->next) {
10993 -       if ((session = smtp_connect_addr(addr, port, why)) != 0) {
10994 +       if ((session = smtp_connect_addr(host, addr, port, why)) != 0) {
10995             session->best = 1;
10996             break;
10997         }
10998 @@ -309,7 +310,7 @@
10999       */
11000      addr_list = smtp_domain_addr(name, why, found_myself);
11001      for (addr = addr_list; addr; addr = addr->next) {
11002 -       if ((session = smtp_connect_addr(addr, port, why)) != 0) {
11003 +       if ((session = smtp_connect_addr(name, addr, port, why)) != 0) {
11004             session->best = (addr->pref == addr_list->pref);
11005             break;
11006         }
11007 diff -Nur snapshot-20010228-orig/src/smtp/smtp_proto.c snapshot-20010228/src/smtp/smtp_proto.c
11008 --- snapshot-20010228-orig/src/smtp/smtp_proto.c        Wed Mar 21 13:26:25 2001
11009 +++ snapshot-20010228/src/smtp/smtp_proto.c     Wed Mar 21 13:32:23 2001
11010 @@ -99,6 +99,7 @@
11011  #include <off_cvt.h>
11012  #include <mark_corrupt.h>
11013  #include <quote_821_local.h>
11014 +#include <pfixtls.h>
11015  
11016  /* Application-specific. */
11017  
11018 @@ -153,6 +154,8 @@
11019      char   *words;
11020      char   *word;
11021      int     n;
11022 +    int     oldfeatures;
11023 +    int     rval;
11024  
11025      /*
11026       * Prepare for disaster.
11027 @@ -206,7 +209,8 @@
11028                                    session->namaddr,
11029                                    translit(resp->str, "\n", " ")));
11030      }
11031 -
11032 +    if (var_smtp_always_ehlo)
11033 +       state->features |= SMTP_FEATURE_ESMTP;
11034      /*
11035       * Pick up some useful features offered by the SMTP server. XXX Until we
11036       * have a portable routine to convert from string to off_t with proper
11037 @@ -215,6 +219,7 @@
11038       * advertises a really huge message size limit.
11039       */
11040      lines = resp->str;
11041 +    oldfeatures = state->features;             /* remember */
11042      while ((words = mystrtok(&lines, "\n")) != 0) {
11043         if (mystrtok(&words, "- ") && (word = mystrtok(&words, " \t")) != 0) {
11044             if (strcasecmp(word, "8BITMIME") == 0)
11045 @@ -223,6 +228,8 @@
11046                 state->features |= SMTP_FEATURE_PIPELINING;
11047             else if (strcasecmp(word, "SIZE") == 0)
11048                 state->features |= SMTP_FEATURE_SIZE;
11049 +          else if (strcasecmp(word, "STARTTLS") == 0)
11050 +               state->features |= SMTP_FEATURE_STARTTLS;
11051  #ifdef USE_SASL_AUTH
11052             else if (var_smtp_sasl_enable && strcasecmp(word, "AUTH") == 0)
11053                 smtp_sasl_helo_auth(state, words);
11054 @@ -241,6 +248,129 @@
11055      if (msg_verbose)
11056         msg_info("server features: 0x%x", state->features);
11057  
11058 +#ifdef HAS_SSL
11059 +    if ((state->features & SMTP_FEATURE_STARTTLS) &&
11060 +       (var_smtp_tls_note_starttls_offer) &&
11061 +       (!(session->tls_enforce_tls || session->tls_use_tls)))
11062 +       msg_info("Host offered STARTTLS: [%s]", session->host);
11063 +    if ((session->tls_enforce_tls) &&
11064 +       !(state->features & SMTP_FEATURE_STARTTLS))
11065 +    {
11066 +       /*
11067 +        * We are enforced to use TLS but it is not offered, so we will give
11068 +        * up on this host. We won't even try STARTTLS, because we could
11069 +        * receive a "500 command unrecognized" which would bounce the
11070 +        * message. We instead want to delay until STARTTLS becomes
11071 +        * available.
11072 +        */
11073 +       return (smtp_site_fail(state, 450, "Could not start TLS: not offered"));
11074 +    }
11075 +    if ((session->tls_enforce_tls) && !pfixtls_clientengine) {
11076 +       /*
11077 +        * We would like to start client TLS, but our own TLS-engine is
11078 +        * not running.
11079 +        */
11080 +       return (smtp_site_fail(state, 450,
11081 +                "Could not start TLS: our TLS-engine not running"));
11082 +    }
11083 +    if ((state->features & SMTP_FEATURE_STARTTLS) &&
11084 +       ((session->tls_use_tls && pfixtls_clientengine) ||
11085 +        (session->tls_enforce_tls))) {
11086 +       /*
11087 +         * Try to use the TLS feature
11088 +         */
11089 +       smtp_chat_cmd(state, "STARTTLS");
11090 +       if ((resp = smtp_chat_resp(state))->code / 100 != 2) {
11091 +           state->features &= ~SMTP_FEATURE_STARTTLS;
11092 +           /*
11093 +            * At this point a political decision is necessary. If we
11094 +            * enforce usage of tls, we have to close the connection
11095 +            * now.
11096 +            */
11097 +           if (session->tls_enforce_tls)
11098 +               return (smtp_site_fail(state, resp->code,
11099 +                                        "host %s refused to start TLS: %s",
11100 +                                          session->host,
11101 +                                          translit(resp->str, "\n", " ")));
11102 +       } else {
11103 +           if (rval = pfixtls_start_clienttls(session->stream,
11104 +                                              var_smtp_starttls_tmout,
11105 +                                              session->tls_enforce_peername,
11106 +                                              session->host,
11107 +                                              &(session->tls_info)))
11108 +               return (smtp_site_fail(state, 450,
11109 +                                "Could not start TLS: client failure"));
11110 +
11111 +
11112 +           /*
11113 +            * Now the connection is established and maybe we do have a
11114 +            * validated cert with a CommonName in it. For logging, we
11115 +            * will check the CommonName against the name of the host.
11116 +            * In enforce_peername state, the handshake would already have
11117 +            * been terminated so the check here is for logging only!
11118 +            */
11119 +           if (session->tls_info.peer_CN != NULL) {
11120 +               if (!session->tls_info.peer_verified) {
11121 +                   msg_info("Peer certficate could not be verified");
11122 +                   if (session->tls_enforce_tls) {
11123 +                       pfixtls_stop_clienttls(session->stream,
11124 +                                              var_smtp_starttls_tmout, 1,
11125 +                                              &(session->tls_info));
11126 +                       return(smtp_site_fail(state, 450, "TLS-failure: Could not verify certificate"));
11127 +                   }
11128 +               }
11129 +               if (strcasecmp(session->tls_info.peer_CN, session->host)) {
11130 +                   msg_info("Hostname/Certificate mismatch: %s != %s",
11131 +                       session->host, session->tls_info.peer_CN);
11132 +               } else if (msg_verbose) {
11133 +                   msg_info("Match: %s == %s", session->tls_info.peer_CN,
11134 +                        session->host);
11135 +               }
11136 +           } else if (session->tls_enforce_tls) {
11137 +               pfixtls_stop_clienttls(session->stream,
11138 +                                      var_smtp_starttls_tmout, 1,
11139 +                                      &(session->tls_info));
11140 +               return (smtp_site_fail(state, 450, "TLS-failure: Cannot verify hostname"));
11141 +           }
11142 +
11143 +           /*
11144 +            * At this point we have to re-negotiate the "EHLO" to reget
11145 +            * the feature-list
11146 +            */
11147 +           state->features = oldfeatures;
11148 +           if (state->features & SMTP_FEATURE_ESMTP) {
11149 +               smtp_chat_cmd(state, "EHLO %s", var_myhostname);
11150 +               if ((resp = smtp_chat_resp(state))->code / 100 != 2)
11151 +                   state->features &= ~SMTP_FEATURE_ESMTP;
11152 +           }
11153 +           lines = resp->str;
11154 +           (void) mystrtok(&lines, "\n");
11155 +           while ((words = mystrtok(&lines, "\n")) != 0) {
11156 +               if (mystrtok(&words, "- ") &&
11157 +                   (word = mystrtok(&words, " \t")) != 0) {
11158 +                   if (strcasecmp(word, "8BITMIME") == 0)
11159 +                       state->features |= SMTP_FEATURE_8BITMIME;
11160 +                   else if (strcasecmp(word, "PIPELINING") == 0)
11161 +                       state->features |= SMTP_FEATURE_PIPELINING;
11162 +                   else if (strcasecmp(word, "SIZE") == 0)
11163 +                       state->features |= SMTP_FEATURE_SIZE;
11164 +                   else if (strcasecmp(word, "STARTTLS") == 0)
11165 +                       state->features |= SMTP_FEATURE_STARTTLS;
11166 +#ifdef USE_SASL_AUTH
11167 +                   else if (var_smtp_sasl_enable && strcasecmp(word, "AUTH") == 0)
11168 +                       smtp_sasl_helo_auth(state, words);
11169 +#endif
11170 +               }
11171 +           }
11172 +           /*
11173 +            * Actually, at this point STARTTLS should not be offered
11174 +            * anymore, so we could check for a protocol violation, but
11175 +            * what should we do then?
11176 +            */
11177 +
11178 +       }
11179 +    }
11180 +#endif
11181  #ifdef USE_SASL_AUTH
11182      if (var_smtp_sasl_enable && (state->features & SMTP_FEATURE_AUTH))
11183         return (smtp_sasl_helo_login(state));
11184 diff -Nur snapshot-20010228-orig/src/smtp/smtp_session.c snapshot-20010228/src/smtp/smtp_session.c
11185 --- snapshot-20010228-orig/src/smtp/smtp_session.c      Wed Mar 21 13:26:25 2001
11186 +++ snapshot-20010228/src/smtp/smtp_session.c   Wed Mar 21 13:32:23 2001
11187 @@ -42,15 +42,42 @@
11188  #include <vstream.h>
11189  #include <stringops.h>
11190  
11191 +#include <mail_params.h>
11192 +#include <maps.h>
11193 +#include <pfixtls.h>
11194 +
11195  /* Application-specific. */
11196  
11197  #include "smtp.h"
11198  
11199 +#ifdef HAS_SSL
11200 +/* static lists */
11201 +static MAPS *tls_per_site;
11202 +
11203 +/* smtp_tls_list_init - initialize lists */
11204 +
11205 +void smtp_tls_list_init(void)
11206 +{
11207 +    tls_per_site = maps_create(VAR_SMTP_TLS_PER_SITE, var_smtp_tls_per_site,
11208 +                              DICT_FLAG_LOCK);
11209 +}
11210 +#endif
11211 +
11212  /* smtp_session_alloc - allocate and initialize SMTP_SESSION structure */
11213  
11214 -SMTP_SESSION *smtp_session_alloc(VSTREAM *stream, char *host, char *addr)
11215 +SMTP_SESSION *smtp_session_alloc(char *dest, VSTREAM *stream, char *host, char *addr)
11216  {
11217      SMTP_SESSION *session;
11218 +    const char *lookup;
11219 +    char *lookup_key;
11220 +    int host_dont_use = 0;
11221 +    int host_use = 0;
11222 +    int host_enforce = 0;
11223 +    int host_enforce_peername = 0;
11224 +    int recipient_dont_use = 0;
11225 +    int recipient_use = 0;
11226 +    int recipient_enforce = 0;
11227 +    int recipient_enforce_peername = 0;
11228  
11229      session = (SMTP_SESSION *) mymalloc(sizeof(*session));
11230      session->stream = stream;
11231 @@ -58,6 +85,61 @@
11232      session->addr = mystrdup(addr);
11233      session->namaddr = concatenate(host, "[", addr, "]", (char *) 0);
11234      session->best = 1;
11235 +    session->tls_use_tls = session->tls_enforce_tls = 0;
11236 +    session->tls_enforce_peername = 0;
11237 +#ifdef HAS_SSL
11238 +    lookup_key = lowercase(mystrdup(host));
11239 +    if (lookup = maps_find(tls_per_site, lookup_key, 0)) {
11240 +       if (!strcasecmp(lookup, "NONE"))
11241 +           host_dont_use = 1;
11242 +       else if (!strcasecmp(lookup, "MAY"))
11243 +           host_use = 1;
11244 +       else if (!strcasecmp(lookup, "MUST"))
11245 +           host_enforce = host_enforce_peername = 1;
11246 +       else if (!strcasecmp(lookup, "MUST_NOPEERMATCH"))
11247 +           host_enforce = 1;
11248 +       else
11249 +           msg_warn("Unknown TLS state for receiving host %s: '%s', using default policy", session->host, lookup);
11250 +    }
11251 +    myfree(lookup_key);
11252 +    lookup_key = lowercase(mystrdup(dest));
11253 +    if (lookup = maps_find(tls_per_site, dest, 0)) {
11254 +       if (!strcasecmp(lookup, "NONE"))
11255 +           recipient_dont_use = 1;
11256 +       else if (!strcasecmp(lookup, "MAY"))
11257 +           recipient_use = 1;
11258 +       else if (!strcasecmp(lookup, "MUST"))
11259 +           recipient_enforce = recipient_enforce_peername = 1;
11260 +       else if (!strcasecmp(lookup, "MUST_NOPEERMATCH"))
11261 +           recipient_enforce = 1;
11262 +       else
11263 +           msg_warn("Unknown TLS state for recipient domain %s: '%s', using default policy", dest, lookup);
11264 +    }
11265 +    myfree(lookup_key);
11266 +
11267 +    if ((var_smtp_enforce_tls && !host_dont_use) || host_enforce ||
11268 +        recipient_enforce)
11269 +       session->tls_enforce_tls = session->tls_use_tls = 1;
11270 +
11271 +    /*
11272 +     * Set up peername checking. We want to make sure that a MUST* entry in
11273 +     * the tls_per_site table always has precedence. MUST always must lead to
11274 +     * a peername check, MUST_NOPEERMATCH must always disable it. Only when
11275 +     * no explicit setting has been found, the default will be used.
11276 +     * There is the case left, that both "host" and "recipient" settings
11277 +     * conflict. In this case, the "host" setting wins.
11278 +     */
11279 +    if (host_enforce && host_enforce_peername)
11280 +       session->tls_enforce_peername = 1;
11281 +    else if (recipient_enforce && recipient_enforce_peername)
11282 +       session->tls_enforce_peername = 1;
11283 +    else if (var_smtp_enforce_tls && var_smtp_tls_enforce_peername)
11284 +       session->tls_enforce_peername = 1;
11285 +
11286 +    else if ((var_smtp_use_tls && !host_dont_use) || host_use || recipient_use)
11287 +      session->tls_use_tls = 1;
11288 +#endif
11289 +    session->tls_info = tls_info_zero;
11290      return (session);
11291  }
11292  
11293 @@ -65,6 +147,11 @@
11294  
11295  void    smtp_session_free(SMTP_SESSION *session)
11296  {
11297 +#ifdef HAS_SSL
11298 +    vstream_fflush(session->stream);
11299 +    pfixtls_stop_clienttls(session->stream, var_smtp_starttls_tmout, 0,
11300 +                          &(session->tls_info));
11301 +#endif
11302      vstream_fclose(session->stream);
11303      myfree(session->host);
11304      myfree(session->addr);
11305 diff -Nur snapshot-20010228-orig/src/smtpd/Makefile.in snapshot-20010228/src/smtpd/Makefile.in
11306 --- snapshot-20010228-orig/src/smtpd/Makefile.in        Wed Mar 21 13:26:25 2001
11307 +++ snapshot-20010228/src/smtpd/Makefile.in     Wed Mar 21 13:32:23 2001
11308 @@ -120,6 +120,7 @@
11309  smtpd.o: ../../include/tok822.h
11310  smtpd.o: ../../include/resolve_clnt.h
11311  smtpd.o: ../../include/mail_server.h
11312 +smtpd.o: ../../include/pfixtls.h
11313  smtpd.o: smtpd_token.h
11314  smtpd.o: smtpd.h
11315  smtpd.o: smtpd_check.h
11316 @@ -147,6 +148,7 @@
11317  smtpd_chat.o: ../../include/cleanup_user.h
11318  smtpd_chat.o: ../../include/mail_error.h
11319  smtpd_chat.o: ../../include/name_mask.h
11320 +smtpd_chat.o: ../../include/pfixtls.h
11321  smtpd_chat.o: smtpd.h
11322  smtpd_chat.o: ../../include/mail_stream.h
11323  smtpd_chat.o: smtpd_chat.h
11324 @@ -177,6 +179,7 @@
11325  smtpd_check.o: ../../include/mail_conf.h
11326  smtpd_check.o: ../../include/maps.h
11327  smtpd_check.o: ../../include/mail_addr_find.h
11328 +smtpd_check.o: ../../include/pfixtls.h
11329  smtpd_check.o: smtpd.h
11330  smtpd_check.o: ../../include/mail_stream.h
11331  smtpd_check.o: smtpd_sasl_glue.h
11332 @@ -193,6 +196,7 @@
11333  smtpd_peer.o: ../../include/vstream.h
11334  smtpd_peer.o: ../../include/argv.h
11335  smtpd_peer.o: ../../include/mail_stream.h
11336 +smtpd_peer.o: ../../include/pfixtls.h
11337  smtpd_sasl_glue.o: smtpd_sasl_glue.c
11338  smtpd_sasl_glue.o: ../../include/sys_defs.h
11339  smtpd_sasl_glue.o: ../../include/msg.h
11340 @@ -243,6 +247,7 @@
11341  smtpd_state.o: ../../include/vstring.h
11342  smtpd_state.o: ../../include/argv.h
11343  smtpd_state.o: ../../include/mail_stream.h
11344 +smtpd_state.o: ../../include/pfixtls.h
11345  smtpd_state.o: smtpd_chat.h
11346  smtpd_state.o: smtpd_sasl_glue.h
11347  smtpd_token.o: smtpd_token.c
11348 @@ -252,3 +257,4 @@
11349  smtpd_token.o: smtpd_token.h
11350  smtpd_token.o: ../../include/vstring.h
11351  smtpd_token.o: ../../include/vbuf.h
11352 +smtpd_token.o: ../../include/pfixtls.h
11353 diff -Nur snapshot-20010228-orig/src/smtpd/smtpd.c snapshot-20010228/src/smtpd/smtpd.c
11354 --- snapshot-20010228-orig/src/smtpd/smtpd.c    Wed Mar 21 13:26:25 2001
11355 +++ snapshot-20010228/src/smtpd/smtpd.c Wed Mar 21 13:32:23 2001
11356 @@ -283,6 +283,7 @@
11357  #include <mail_stream.h>
11358  #include <mail_queue.h>
11359  #include <tok822.h>
11360 +#include <pfixtls.h>
11361  
11362  /* Single-threaded server skeleton. */
11363  
11364 @@ -307,6 +308,7 @@
11365    */
11366  int     var_smtpd_rcpt_limit;
11367  int     var_smtpd_tmout;
11368 +char   *var_relay_ccerts;
11369  int     var_smtpd_soft_erlim;
11370  int     var_smtpd_hard_erlim;
11371  int     var_queue_minfree;             /* XXX use off_t */
11372 @@ -350,6 +352,14 @@
11373  char   *var_smtpd_sasl_realm;
11374  char   *var_filter_xport;
11375  bool    var_broken_auth_clients;
11376 +int     var_smtpd_starttls_tmout;
11377 +int     var_smtpd_tls_wrappermode;
11378 +int     var_smtpd_use_tls;
11379 +int     var_smtpd_enforce_tls;
11380 +int     var_smtpd_tls_ask_ccert;
11381 +int     var_smtpd_tls_req_ccert;
11382 +int     var_smtpd_tls_ccert_vd;
11383 +int     var_smtpd_tls_received_header;
11384  
11385   /*
11386    * Global state, for stand-alone mode queue file cleanup. When this is
11387 @@ -445,11 +455,21 @@
11388      else
11389         smtpd_chat_reply(state, "250-SIZE");
11390      smtpd_chat_reply(state, "250-ETRN");
11391 +#ifdef HAS_SSL
11392 +    if ((state->tls_use_tls || state->tls_enforce_tls) && (!state->tls_active))
11393 +       smtpd_chat_reply(state, "250-STARTTLS");
11394 +#endif
11395  #ifdef USE_SASL_AUTH
11396      if (var_smtpd_sasl_enable) {
11397 +#ifdef HAS_SSL
11398 +      if (!state->tls_enforce_tls || state->tls_active) {
11399 +#endif
11400         smtpd_chat_reply(state, "250-AUTH %s", state->sasl_mechanism_list);
11401         if (var_broken_auth_clients)
11402             smtpd_chat_reply(state, "250-AUTH=%s", state->sasl_mechanism_list);
11403 +#ifdef HAS_SSL
11404 +      }
11405 +#endif
11406      }
11407  #endif
11408      smtpd_chat_reply(state, "250 8BITMIME");
11409 @@ -807,11 +827,76 @@
11410      state->rcpt_count = 0;
11411  }
11412  
11413 +/* CN_sanitize - make sure, the CN-string is well behaved */
11414 +
11415 +static void CN_sanitize(char *CNstring)
11416 +{
11417 +    int i;
11418 +    int len;
11419 +    int parencount;
11420 +
11421 +    /*
11422 +     * The information included in the CN (CommonName) of the peer and its
11423 +     * issuer can be included into the Received: header line. The characters
11424 +     * allowed as well as comment nesting are limited by RFC822.
11425 +     */
11426 +
11427 +    len = strlen(CNstring);
11428 +    /*
11429 +     * The Received: header can only contain characters. Make sure that only
11430 +     * acceptable characters are printed. Maybe we could allow more, but
11431 +     * not everything makes sense inside a CommonName.
11432 +     */
11433 +    for (i = 0; i < len; i++) 
11434 +       if (!((CNstring[i] >= 'A') && (CNstring[i] <='Z')) &&
11435 +           !((CNstring[i] >= 'a') && (CNstring[i] <='z')) &&
11436 +           !((CNstring[i] >= '0') && (CNstring[i] <='9')) &&
11437 +           (CNstring[i] != '(') && (CNstring[i] != ')') &&
11438 +           (CNstring[i] != '[') && (CNstring[i] != ']') &&
11439 +           (CNstring[i] != '{') && (CNstring[i] != '}') &&
11440 +           (CNstring[i] != '<') && (CNstring[i] != '>') &&
11441 +           (CNstring[i] != '?') && (CNstring[i] != '!') &&
11442 +           (CNstring[i] != ';') && (CNstring[i] != ':') &&
11443 +           (CNstring[i] != '"') && (CNstring[i] != '\'') &&
11444 +           (CNstring[i] != '/') && (CNstring[i] != '|') &&
11445 +           (CNstring[i] != '+') && (CNstring[i] != '&') &&
11446 +           (CNstring[i] != '~') && (CNstring[i] != '@') &&
11447 +           (CNstring[i] != '#') && (CNstring[i] != '$') &&
11448 +           (CNstring[i] != '%') && (CNstring[i] != '&') &&
11449 +           (CNstring[i] != '^') && (CNstring[i] != '*') &&
11450 +           (CNstring[i] != '_') && (CNstring[i] != '-') &&
11451 +           (CNstring[i] != '.') && (CNstring[i] != ' '))
11452 +           CNstring[i] = '?';
11453 +
11454 +    /*
11455 +     * This information will go into the Received: header inside a comment.
11456 +     * Since comments can be nested, parentheses '(' and ')' must match.
11457 +     */
11458 +    parencount = 0;
11459 +    for (i = 0; i < len; i++) {
11460 +       if (CNstring[i] == '(')
11461 +           parencount++;
11462 +       else if (CNstring[i] == ')')
11463 +           parencount--;
11464 +    }
11465 +    /*
11466 +     * The necessary condition is violated. Do YOU know, where to correct?
11467 +     * I don't know, so I will practically remove all parentheses.
11468 +     */
11469 +    if (parencount != 0) {
11470 +       for (i = 0; i < len; i++)
11471 +           if ((CNstring[i] == '(') || (CNstring[i] == ')'))
11472 +               CNstring[i] = '/';
11473 +    }
11474 +}
11475 +
11476  /* data_cmd - process DATA command */
11477  
11478  static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
11479  {
11480      char   *start;
11481 +    char   *peer_CN;
11482 +    char   *issuer_CN;
11483      int     len;
11484      int     curr_rec_type;
11485      int     prev_rec_type;
11486 @@ -846,6 +931,35 @@
11487                 "Received: from %s (%s [%s])",
11488                 state->helo_name ? state->helo_name : state->name,
11489                 state->name, state->addr);
11490 +    if (var_smtpd_tls_received_header && state->tls_active) {
11491 +       rec_fprintf(state->cleanup, REC_TYPE_NORM,
11492 +                   "\t(using %s with cipher %s (%d/%d bits))",
11493 +                   state->tls_info.protocol, state->tls_info.cipher_name,
11494 +                   state->tls_info.cipher_usebits,
11495 +                   state->tls_info.cipher_algbits);
11496 +       if (state->tls_info.peer_CN) {
11497 +            peer_CN = mystrdup(state->tls_info.peer_CN);
11498 +           CN_sanitize(peer_CN);
11499 +            issuer_CN = mystrdup(state->tls_info.issuer_CN);
11500 +           CN_sanitize(issuer_CN);
11501 +           if (state->tls_info.peer_verified)
11502 +               rec_fprintf(state->cleanup, REC_TYPE_NORM,
11503 +                       "\t(Client CN \"%s\", Issuer CN \"%s\" (verified OK))",
11504 +                       peer_CN, issuer_CN);
11505 +           else
11506 +               rec_fprintf(state->cleanup, REC_TYPE_NORM,
11507 +                       "\t(Client CN \"%s\", Issuer CN \"%s\" (not verified))",
11508 +                       peer_CN, issuer_CN);
11509 +           myfree(issuer_CN);
11510 +           myfree(peer_CN);
11511 +       }
11512 +       else if (var_smtpd_tls_ask_ccert)
11513 +           rec_fprintf(state->cleanup, REC_TYPE_NORM,
11514 +                       "\t(Client did not present a certificate)");
11515 +       else
11516 +           rec_fprintf(state->cleanup, REC_TYPE_NORM,
11517 +                       "\t(No client certificate requested)");
11518 +    }
11519      if (state->rcpt_count == 1 && state->recipient) {
11520         rec_fprintf(state->cleanup, REC_TYPE_NORM,
11521                     "\tby %s (%s) with %s id %s",
11522 @@ -1144,6 +1258,77 @@
11523      return (0);
11524  }
11525  
11526 +static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
11527 +{
11528 +    char   *err;
11529 +
11530 +#ifdef HAS_SSL
11531 +    if (argc != 1) {
11532 +       state->error_mask |= MAIL_ERROR_PROTOCOL;
11533 +       smtpd_chat_reply(state, "501 Syntax: STARTTLS");
11534 +       return (-1);
11535 +    }
11536 +    if (state->tls_active != 0) {
11537 +       state->error_mask |= MAIL_ERROR_PROTOCOL;
11538 +       smtpd_chat_reply(state, "554 Error: TLS already active");
11539 +       return (-1);
11540 +    }
11541 +    if (state->tls_use_tls == 0) {
11542 +       state->error_mask |= MAIL_ERROR_PROTOCOL;
11543 +       smtpd_chat_reply(state, "502 Error: command not implemented");
11544 +       return (-1);
11545 +    }
11546 +    if (!pfixtls_serverengine) {
11547 +       smtpd_chat_reply(state, "454 TLS not available due to temporary reason");
11548 +       return (0);
11549 +    }
11550 +    smtpd_chat_reply(state, "220 Ready to start TLS");
11551 +    vstream_fflush(state->client);
11552 +    /*
11553 +     * When deciding about continuing the handshake, we will stop when a
11554 +     * client certificate was _required_ and none was presented or the
11555 +     * verification failed. This however does only make sense when TLS is
11556 +     * enforced. Otherwise we would happily perform perform the SMTP
11557 +     * transaction without any STARTTLS at all! So only have the handshake
11558 +     * fail when TLS is also enforced.
11559 +     */
11560 +    if (pfixtls_start_servertls(state->client, var_smtpd_starttls_tmout,
11561 +                               state->name, state->addr, &(state->tls_info),
11562 +                       (var_smtpd_tls_req_ccert && state->tls_enforce_tls))) {
11563 +       /*
11564 +         * Typically the connection is hanging at this point, so
11565 +         * we should try to shut it down by force! Unfortunately this
11566 +         * problem is not addressed in postfix!
11567 +         */
11568 +       return (-1);
11569 +    }
11570 +    state->tls_active = 1;
11571 +    helo_reset(state);
11572 +    mail_reset(state);
11573 +    rcpt_reset(state);
11574 +    return (0);
11575 +#else
11576 +    state->error_mask |= MAIL_ERROR_PROTOCOL;
11577 +    smtpd_chat_reply(state, "502 Error: command not implemented");
11578 +    return (-1);
11579 +#endif
11580 +}
11581 +
11582 +static void tls_reset(SMTPD_STATE *state)
11583 +{
11584 +    int failure = 0;
11585 +
11586 +    if (state->reason && state->where && strcmp(state->where, SMTPD_AFTER_DOT))
11587 +       failure = 1;
11588 +#ifdef HAS_SSL
11589 +    vstream_fflush(state->client);
11590 +    if (state->tls_active)
11591 +       pfixtls_stop_servertls(state->client, var_smtpd_starttls_tmout,
11592 +                              failure, &(state->tls_info));
11593 +#endif
11594 +    state->tls_active = 0;
11595 +}
11596 +
11597   /*
11598    * The table of all SMTP commands that we know. Set the junk limit flag on
11599    * any command that can be repeated an arbitrary number of times without
11600 @@ -1161,6 +1346,10 @@
11601      "HELO", helo_cmd, SMTPD_CMD_FLAG_LIMIT,
11602      "EHLO", ehlo_cmd, SMTPD_CMD_FLAG_LIMIT,
11603  
11604 +#ifdef HAS_SSL
11605 +    "STARTTLS", starttls_cmd, 0,
11606 +#endif
11607 +
11608  #ifdef USE_SASL_AUTH
11609      "AUTH", smtpd_sasl_auth_cmd, 0,
11610  #endif
11611 @@ -1250,9 +1439,28 @@
11612                 state->error_count++;
11613                 continue;
11614             }
11615 +           if (state->tls_enforce_tls &&
11616 +               !state->tls_active &&
11617 +               cmdp->action != starttls_cmd &&
11618 +               cmdp->action != noop_cmd &&
11619 +               cmdp->action != ehlo_cmd &&
11620 +               cmdp->action != quit_cmd) {
11621 +               smtpd_chat_reply(state,
11622 +                                "530 Must issue a STARTTLS command first");
11623 +               state->error_count++;
11624 +               continue;
11625 +           }
11626             state->where = cmdp->name;
11627 -           if (cmdp->action(state, argc, argv) != 0)
11628 +           if (cmdp->action(state, argc, argv) != 0) {
11629                 state->error_count++;
11630 +               /*
11631 +                * Die after TLS negotiation failure, as there is no
11632 +                * stable way to recover from a possible mixture of
11633 +                * TLS and SMTP protocol from the client.
11634 +                */
11635 +               if (cmdp->action == starttls_cmd)
11636 +                   break;
11637 +           }
11638             if ((cmdp->flags & SMTPD_CMD_FLAG_LIMIT)
11639                 && state->junk_cmds++ > var_smtpd_junk_cmd_limit)
11640                 state->error_count++;
11641 @@ -1289,6 +1497,7 @@
11642       * Cleanup whatever information the client gave us during the SMTP
11643       * dialog.
11644       */
11645 +    tls_reset(state);
11646      helo_reset(state);
11647  #ifdef USE_SASL_AUTH
11648      if (var_smtpd_sasl_enable)
11649 @@ -1321,6 +1530,36 @@
11650       * machines.
11651       */
11652      smtpd_state_init(&state, stream);
11653 +#ifdef HAS_SSL
11654 +    state.tls_use_tls = var_smtpd_use_tls | var_smtpd_enforce_tls;
11655 +    state.tls_enforce_tls = var_smtpd_enforce_tls;
11656 +    if (var_smtpd_tls_wrappermode) {
11657 +       /*
11658 +        * TLS has been set to wrapper mode, meaning that we run on a
11659 +        * seperate port and we must switch to TLS layer before actually
11660 +        * performing the SMTP protocol. This implies enforce-mode.
11661 +        */
11662 +       state.tls_use_tls = state.tls_enforce_tls = 1;
11663 +       if (pfixtls_start_servertls(state.client, var_smtpd_starttls_tmout,
11664 +                                    state.name, state.addr, &state.tls_info,
11665 +                                   var_smtpd_tls_req_ccert)) {
11666 +            /*
11667 +             * Typically the connection is hanging at this point, so
11668 +             * we should try to shut it down by force! Unfortunately this
11669 +             * problem is not addressed in postfix!
11670 +             */
11671 +            return;
11672 +       }
11673 +       state.tls_active = 1;
11674 +    }
11675 +#else
11676 +    state.tls_use_tls = 0;
11677 +    state.tls_enforce_tls = 0;
11678 +#endif
11679 +
11680 +    /*
11681 +     * Provide the SMTP service.
11682 +     */
11683  
11684      /*
11685       * See if we need to turn on verbose logging for this client.
11686 @@ -1338,10 +1577,6 @@
11687         smtpd_chat_reply(&state, "220 %s", var_smtpd_banner);
11688         msg_info("connect from %s[%s]", state.name, state.addr);
11689      }
11690 -
11691 -    /*
11692 -     * Provide the SMTP service.
11693 -     */
11694      smtpd_proto(&state);
11695  
11696      /*
11697 @@ -1408,7 +1643,6 @@
11698  
11699  static void pre_jail_init(char *unused_name, char **unused_argv)
11700  {
11701 -
11702      /*
11703       * Initialize blacklist/etc. patterns before entering the chroot jail, in
11704       * case they specify a filename pattern.
11705 @@ -1424,6 +1658,12 @@
11706         msg_warn("%s is true, but SASL support is not compiled in",
11707                  VAR_SMTPD_SASL_ENABLE);
11708  #endif
11709 +
11710 +#ifdef HAS_SSL
11711 +    if (var_smtpd_use_tls || var_smtpd_enforce_tls || var_smtpd_tls_wrappermode)
11712 +       pfixtls_init_serverengine(var_smtpd_tls_ccert_vd,
11713 +                                 var_smtpd_tls_ask_ccert);
11714 +#endif
11715  }
11716  
11717  /* main - the main program */
11718 @@ -1446,10 +1686,12 @@
11719         VAR_REJECT_CODE, DEF_REJECT_CODE, &var_reject_code, 0, 0,
11720         VAR_NON_FQDN_CODE, DEF_NON_FQDN_CODE, &var_non_fqdn_code, 0, 0,
11721         VAR_SMTPD_JUNK_CMD, DEF_SMTPD_JUNK_CMD, &var_smtpd_junk_cmd_limit, 1, 0,
11722 +       VAR_SMTPD_TLS_CCERT_VD, DEF_SMTPD_TLS_CCERT_VD, &var_smtpd_tls_ccert_vd, 0, 0,
11723         0,
11724      };
11725      static CONFIG_TIME_TABLE time_table[] = {
11726         VAR_SMTPD_TMOUT, DEF_SMTPD_TMOUT, &var_smtpd_tmout, 1, 0,
11727 +       VAR_SMTPD_STARTTLS_TMOUT, DEF_SMTPD_STARTTLS_TMOUT, &var_smtpd_starttls_tmout, 1, 0,
11728         VAR_SMTPD_ERR_SLEEP, DEF_SMTPD_ERR_SLEEP, &var_smtpd_err_sleep, 0, 0,
11729         0,
11730      };
11731 @@ -1461,6 +1703,12 @@
11732         VAR_ALLOW_UNTRUST_ROUTE, DEF_ALLOW_UNTRUST_ROUTE, &var_allow_untrust_route,
11733         VAR_SMTPD_SASL_ENABLE, DEF_SMTPD_SASL_ENABLE, &var_smtpd_sasl_enable,
11734         VAR_BROKEN_AUTH_CLNTS, DEF_BROKEN_AUTH_CLNTS, &var_broken_auth_clients,
11735 +       VAR_SMTPD_TLS_WRAPPER, DEF_SMTPD_TLS_WRAPPER, &var_smtpd_tls_wrappermode,
11736 +       VAR_SMTPD_USE_TLS, DEF_SMTPD_USE_TLS, &var_smtpd_use_tls,
11737 +       VAR_SMTPD_ENFORCE_TLS, DEF_SMTPD_ENFORCE_TLS, &var_smtpd_enforce_tls,
11738 +       VAR_SMTPD_TLS_ACERT, DEF_SMTPD_TLS_ACERT, &var_smtpd_tls_ask_ccert,
11739 +       VAR_SMTPD_TLS_RCERT, DEF_SMTPD_TLS_RCERT, &var_smtpd_tls_req_ccert,
11740 +       VAR_SMTPD_TLS_RECHEAD, DEF_SMTPD_TLS_RECHEAD, &var_smtpd_tls_received_header,
11741         0,
11742      };
11743      static CONFIG_STR_TABLE str_table[] = {
11744 @@ -1485,6 +1733,7 @@
11745         VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0,
11746         VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 1, 0,
11747         VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0,
11748 +       VAR_RELAY_CCERTS, DEF_RELAY_CCERTS, &var_relay_ccerts, 0, 0,
11749         0,
11750      };
11751  
11752 @@ -1501,3 +1750,4 @@
11753                        MAIL_SERVER_PRE_ACCEPT, pre_accept,
11754                        0);
11755  }
11756 +
11757 diff -Nur snapshot-20010228-orig/src/smtpd/smtpd.h snapshot-20010228/src/smtpd/smtpd.h
11758 --- snapshot-20010228-orig/src/smtpd/smtpd.h    Wed Mar 21 13:26:25 2001
11759 +++ snapshot-20010228/src/smtpd/smtpd.h Wed Mar 21 13:32:23 2001
11760 @@ -32,6 +32,7 @@
11761    * Global library.
11762    */
11763  #include <mail_stream.h>
11764 +#include <pfixtls.h>
11765  
11766   /*
11767    * Variables that keep track of conversation state. There is only one SMTP
11768 @@ -76,6 +77,10 @@
11769      VSTRING *sasl_encoded;
11770      VSTRING *sasl_decoded;
11771  #endif
11772 +    int     tls_active;
11773 +    int     tls_use_tls;
11774 +    int     tls_enforce_tls;
11775 +    tls_info_t tls_info;
11776  } SMTPD_STATE;
11777  
11778  extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *);
11779 diff -Nur snapshot-20010228-orig/src/smtpd/smtpd_check.c snapshot-20010228/src/smtpd/smtpd_check.c
11780 --- snapshot-20010228-orig/src/smtpd/smtpd_check.c      Wed Mar 21 13:26:25 2001
11781 +++ snapshot-20010228/src/smtpd/smtpd_check.c   Wed Mar 21 13:32:23 2001
11782 @@ -268,6 +268,7 @@
11783  
11784  #include <namadr_list.h>
11785  #include <domain_list.h>
11786 +#include <string_list.h>
11787  #include <mail_params.h>
11788  #include <canon_addr.h>
11789  #include <resolve_clnt.h>
11790 @@ -320,6 +321,9 @@
11791    */
11792  static DOMAIN_LIST *relay_domains;
11793  static NAMADR_LIST *mynetworks;
11794 +#ifdef HAS_SSL
11795 +static MAPS *relay_ccerts;
11796 +#endif
11797  
11798   /*
11799    * Pre-parsed restriction lists.
11800 @@ -445,6 +449,10 @@
11801       */
11802      mynetworks = namadr_list_init(var_mynetworks);
11803      relay_domains = domain_list_init(var_relay_domains);
11804 +#ifdef HAS_SSL
11805 +    relay_ccerts = maps_create(VAR_RELAY_CCERTS, var_relay_ccerts,
11806 +                              DICT_FLAG_LOCK);
11807 +#endif
11808  
11809      /*
11810       * Pre-parse and pre-open the recipient maps.
11811 @@ -771,6 +779,36 @@
11812  
11813  static int permit_auth_destination(char *recipient);
11814  
11815 +/* permit_tls_clientcerts - OK/DUNNO for message relaying */
11816 +
11817 +#ifdef HAS_SSL
11818 +static int permit_tls_clientcerts(SMTPD_STATE *state, int permit_all_certs)
11819 +{
11820 +    char   *low_name;
11821 +    const char *found;
11822 +
11823 +    if (state->tls_info.peer_verified && permit_all_certs) {
11824 +       if (msg_verbose)
11825 +           msg_info("Relaying allowed for all verified client certificates");
11826 +       return(SMTPD_CHECK_OK);
11827 +    }
11828 +
11829 +    if (state->tls_info.peer_verified && state->tls_info.peer_fingerprint) {
11830 +       low_name = lowercase(mystrdup(state->tls_info.peer_fingerprint));
11831 +       found = maps_find(relay_ccerts, low_name, DICT_FLAG_FIXED);
11832 +       myfree(low_name);
11833 +       if (found) {
11834 +           if (msg_verbose)
11835 +               msg_info("Relaying allowed for certified client: %s", found);
11836 +           return (SMTPD_CHECK_OK);
11837 +       } else if (msg_verbose)
11838 +           msg_info("relay_clientcerts: No match for fingerprint '%s'",
11839 +                    state->tls_info.peer_fingerprint);
11840 +    }
11841 +    return (SMTPD_CHECK_DUNNO);
11842 +}
11843 +#endif
11844 +
11845  /* check_relay_domains - OK/FAIL for message relaying */
11846  
11847  static int check_relay_domains(SMTPD_STATE *state, char *recipient,
11848 @@ -1673,6 +1711,12 @@
11849                 status = permit_sasl_auth(state,
11850                                           SMTPD_CHECK_OK, SMTPD_CHECK_DUNNO);
11851  #endif
11852 +#ifdef HAS_SSL
11853 +       } else if (strcasecmp(name, PERMIT_TLS_ALL_CLIENTCERTS) == 0) {
11854 +         status = permit_tls_clientcerts(state, 1);
11855 +       } else if (strcasecmp(name, PERMIT_TLS_CLIENTCERTS) == 0) {
11856 +         status = permit_tls_clientcerts(state, 0);
11857 +#endif
11858         } else if (strcasecmp(name, REJECT_UNKNOWN_RCPTDOM) == 0) {
11859             if (state->recipient)
11860                 status = reject_unknown_address(state, state->recipient,
11861 @@ -2060,6 +2104,7 @@
11862  char   *var_rcpt_checks = "";
11863  char   *var_etrn_checks = "";
11864  char   *var_relay_domains = "";
11865 +char   *var_relay_ccerts = "";
11866  char   *var_mynetworks = "";
11867  char   *var_notify_classes = "";
11868  
11869 diff -Nur snapshot-20010228-orig/src/smtpd/smtpd_state.c snapshot-20010228/src/smtpd/smtpd_state.c
11870 --- snapshot-20010228-orig/src/smtpd/smtpd_state.c      Wed Mar 21 13:26:25 2001
11871 +++ snapshot-20010228/src/smtpd/smtpd_state.c   Wed Mar 21 13:32:23 2001
11872 @@ -91,6 +91,10 @@
11873      state->recursion = 0;
11874      state->msg_size = 0;
11875      state->junk_cmds = 0;
11876 +    state->tls_active = 0;
11877 +    state->tls_use_tls = 0;
11878 +    state->tls_enforce_tls = 0;
11879 +    state->tls_info = tls_info_zero;
11880  
11881  #ifdef USE_SASL_AUTH
11882      if (SMTPD_STAND_ALONE(state))
11883 diff -Nur snapshot-20010228-orig/src/tlsmgr/Makefile.in snapshot-20010228/src/tlsmgr/Makefile.in
11884 --- snapshot-20010228-orig/src/tlsmgr/Makefile.in       Thu Jan  1 01:00:00 1970
11885 +++ snapshot-20010228/src/tlsmgr/Makefile.in    Wed Mar 21 13:32:23 2001
11886 @@ -0,0 +1,75 @@
11887 +SHELL  = /bin/sh
11888 +SRCS   = tlsmgr.c
11889 +OBJS   = tlsmgr.o
11890 +HDRS   =
11891 +TESTSRC        =
11892 +WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
11893 +       -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
11894 +       -Wunused
11895 +DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
11896 +CFLAGS = $(DEBUG) $(OPT) $(DEFS)
11897 +TESTPROG= 
11898 +PROG   = tlsmgr
11899 +INC_DIR        = ../../include
11900 +LIBS   = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libutil.a
11901 +
11902 +.c.o:; $(CC) $(CFLAGS) -c $*.c
11903 +
11904 +$(PROG):       $(OBJS) $(LIBS)
11905 +       $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
11906 +
11907 +Makefile: Makefile.in
11908 +       (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs; cat $?) >$@
11909 +
11910 +test:  $(TESTPROG)
11911 +
11912 +update: ../../libexec/$(PROG)
11913 +
11914 +../../libexec/$(PROG): $(PROG)
11915 +       cp $(PROG) ../../libexec
11916 +
11917 +printfck: $(OBJS) $(PROG)
11918 +       rm -rf printfck
11919 +       mkdir printfck
11920 +       cp *.h printfck
11921 +       sed '1,/^# do not edit/!d' Makefile >printfck/Makefile
11922 +       set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
11923 +       cd printfck; make "INC_DIR=../../../../include" `cd ../..; ls *.o`
11924 +
11925 +lint:
11926 +       lint $(DEFS) $(SRCS) $(LINTFIX)
11927 +
11928 +clean:
11929 +       rm -f *.o *core $(PROG) $(TESTPROG) junk 
11930 +       rm -rf printfck
11931 +
11932 +tidy:  clean
11933 +
11934 +depend: $(MAKES)
11935 +       (sed '1,/^# do not edit/!d' Makefile.in; \
11936 +       set -e; for i in [a-z][a-z0-9]*.c; do \
11937 +           $(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
11938 +           -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
11939 +       done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
11940 +       @make -f Makefile.in Makefile
11941 +
11942 +# do not edit below this line - it is generated by 'make depend'
11943 +tlsmgr.o: tlsmgr.c
11944 +tlsmgr.o: ../../include/sys_defs.h
11945 +tlsmgr.o: ../../include/msg.h
11946 +tlsmgr.o: ../../include/events.h
11947 +tlsmgr.o: ../../include/vstream.h
11948 +tlsmgr.o: ../../include/vbuf.h
11949 +tlsmgr.o: ../../include/dict.h
11950 +tlsmgr.o: ../../include/argv.h
11951 +tlsmgr.o: ../../include/vstring.h
11952 +tlsmgr.o: ../../include/stringops.h
11953 +tlsmgr.o: ../../include/mymalloc.h
11954 +tlsmgr.o: ../../include/connect.h
11955 +tlsmgr.o: ../../include/myflock.h
11956 +tlsmgr.o: ../../include/mail_conf.h
11957 +tlsmgr.o: ../../include/mail_params.h
11958 +tlsmgr.o: ../../include/iostuff.h
11959 +tlsmgr.o: ../../include/master_proto.h
11960 +tlsmgr.o: ../../include/mail_server.h
11961 +tlsmgr.o: ../../include/pfixtls.h
11962 diff -Nur snapshot-20010228-orig/src/tlsmgr/tlsmgr.c snapshot-20010228/src/tlsmgr/tlsmgr.c
11963 --- snapshot-20010228-orig/src/tlsmgr/tlsmgr.c  Thu Jan  1 01:00:00 1970
11964 +++ snapshot-20010228/src/tlsmgr/tlsmgr.c       Wed Mar 21 13:32:23 2001
11965 @@ -0,0 +1,598 @@
11966 +/*++
11967 +/* NAME
11968 +/*     tlsmgr 8
11969 +/* SUMMARY
11970 +/*     Postfix TLS session cache and PRNG handling manager
11971 +/* SYNOPSIS
11972 +/*     \fBtlsmgr\fR [generic Postfix daemon options]
11973 +/* DESCRIPTION
11974 +/*     The tlsmgr process does housekeeping on the session cache database
11975 +/*     files. It runs through the databases and removes expired entries
11976 +/*     and entries written by older (incompatible) versions.
11977 +/*
11978 +/*     The tlsmgr is responsible for the PRNG handling. The used internal
11979 +/*     OpenSSL PRNG has a pool size of 8192 bits (= 1024 bytes). The pool
11980 +/*     is initially seeded at startup from an external source (EGD or
11981 +/*     /dev/urandom) and additional seed is obtained later during program
11982 +/*     run at a configurable period. The exact time of seed query is
11983 +/*     using random information and is equally distributed in the range of
11984 +/*     [0-\fBtls_random_reseed_period\fR] with a \fBtls_random_reseed_period\fR
11985 +/*     having a default of 1 hour.
11986 +/*
11987 +/*     Tlsmgr can be run chrooted and with dropped privileges, as it will
11988 +/*     connect to the entropy source at startup.
11989 +/*
11990 +/*     The PRNG is additionally seeded internally by the data found in the
11991 +/*     session cache and timevalues.
11992 +/*
11993 +/*     Tlsmgr reads the old value of the exchange file at startup to keep
11994 +/*     entropy already collected during previous runs.
11995 +/*
11996 +/*     From the PRNG random pool a cryptographically strong 1024 byte random
11997 +/*     sequence is written into the PRNG exchange file. The file is updated
11998 +/*     periodically with the time changing randomly from
11999 +/*     [0-\fBtls_random_prng_update_period\fR].
12000 +/* STANDARDS
12001 +/* SECURITY
12002 +/* .ad
12003 +/* .fi
12004 +/*     Tlsmgr is not security-sensitive. It only deals with external data
12005 +/*     to be fed into the PRNG, the contents is never trusted. The session
12006 +/*     cache housekeeping will only remove entries if expired and will never
12007 +/*     touch the contents of the cached data.
12008 +/* DIAGNOSTICS
12009 +/*     Problems and transactions are logged to the syslog daemon.
12010 +/* BUGS
12011 +/*     There is no automatic means to limit the number of entries in the
12012 +/*     session caches and/or the size of the session cache files.
12013 +/* CONFIGURATION PARAMETERS
12014 +/* .ad
12015 +/* .fi
12016 +/*     The following \fBmain.cf\fR parameters are especially relevant to
12017 +/*     this program. See the Postfix \fBmain.cf\fR file for syntax details
12018 +/*     and for default values. Use the \fBpostfix reload\fR command after
12019 +/*     a configuration change.
12020 +/* .SH Session Cache
12021 +/* .ad
12022 +/* .fi
12023 +/* .IP \fBsmtpd_tls_session_cache_database\fR
12024 +/*     Name of the SDBM file (type sdbm:) containing the SMTP server session
12025 +/*     cache. If the file does not exist, it is created.
12026 +/* .IP \fBsmtpd_tls_session_cache_timeout\fR
12027 +/*     Expiry time of SMTP server session cache entries in seconds. Entries
12028 +/*     older than this are removed from the session cache. A cleanup-run is
12029 +/*     performed periodically every \fBsmtpd_tls_session_cache_timeout\fR
12030 +/*     seconds. Default is 3600 (= 1 hour).
12031 +/* .IP \fBsmtp_tls_session_cache_database\fR
12032 +/*     Name of the SDBM file (type sdbm:) containing the SMTP client session
12033 +/*     cache. If the file does not exist, it is created.
12034 +/* .IP \fBsmtp_tls_session_cache_timeout\fR
12035 +/*     Expiry time of SMTP client session cache entries in seconds. Entries
12036 +/*     older than this are removed from the session cache. A cleanup-run is
12037 +/*     performed periodically every \fBsmtp_tls_session_cache_timeout\fR
12038 +/*     seconds. Default is 3600 (= 1 hour).
12039 +/* .SH Pseudo Random Number Generator
12040 +/* .ad
12041 +/* .fi
12042 +/* .IP \fBtls_random_source\fR
12043 +/*     Name of the EGD socket or device or regular file to obtain entropy
12044 +/*     from. The type of entropy source must be specified by preceding the
12045 +/*      name with the appropriate type: egd:/path/to/egd_socket,
12046 +/*      dev:/path/to/devicefile, or /path/to/regular/file.
12047 +/*     tlsmgr opens \fBtls_random_source\fR and tries to read
12048 +/*     \fBtls_random_bytes\fR from it.
12049 +/* .IP \fBtls_random_bytes\fR
12050 +/*     Number of bytes to be read from \fBtls_random_source\fR.
12051 +/*     Default value is 32 bytes. If using EGD, a maximum of 255 bytes is read.
12052 +/* .IP \fBtls_random_exchange_name\fR
12053 +/*     Name of the file written by tlsmgr and read by smtp and smtpd at
12054 +/*     startup. The length is 1024 bytes. Default value is
12055 +/*     /etc/postfix/prng_exch.
12056 +/* .IP \fBtls_random_reseed_period\fR
12057 +/*     Time in seconds until the next reseed from external sources is due.
12058 +/*     This is the maximum value. The actual point in time is calculated
12059 +/*     with a random factor equally distributed between 0 and this maximum
12060 +/*     value. Default is 3600 (= 60 minutes).
12061 +/* .IP \fBtls_random_prng_update_period\fR
12062 +/*     Time in seconds until the PRNG exchange file is updated with new
12063 +/*     pseude random values. This is the maximum value. The actual point
12064 +/*     in time is calculated with a random factor equally distributed
12065 +/*     between 0 and this maximum value. Default is 60 (= 1 minute).
12066 +/* SEE ALSO
12067 +/*     smtp(8) SMTP client
12068 +/*     smtpd(8) SMTP server
12069 +/* LICENSE
12070 +/* .ad
12071 +/* .fi
12072 +/*     The Secure Mailer license must be distributed with this software.
12073 +/* AUTHOR(S)
12074 +/*--*/
12075 +
12076 +/* System library. */
12077 +
12078 +#include <sys_defs.h>
12079 +#include <stdlib.h>
12080 +#include <unistd.h>
12081 +#include <ctype.h>
12082 +#include <errno.h>
12083 +#include <string.h>
12084 +#include <sys/time.h>                  /* gettimeofday, not POSIX */
12085 +
12086 +/* OpenSSL library. */
12087 +#ifdef HAS_SSL
12088 +#include <openssl/rand.h>              /* For the PRNG */
12089 +#endif
12090 +
12091 +/* Utility library. */
12092 +
12093 +#include <msg.h>
12094 +#include <events.h>
12095 +#include <dict.h>
12096 +#include <stringops.h>
12097 +#include <mymalloc.h>
12098 +#include <connect.h>
12099 +#include <myflock.h>
12100 +
12101 +/* Global library. */
12102 +
12103 +#include <mail_conf.h>
12104 +#include <mail_params.h>
12105 +#include <pfixtls.h>
12106 +
12107 +/* Master process interface */
12108 +
12109 +#include <master_proto.h>
12110 +#include <mail_server.h>
12111 +
12112 +/* Application-specific. */
12113 +
12114 + /*
12115 +  * Tunables.
12116 +  */
12117 +char   *var_tls_rand_source;
12118 +int    var_tls_rand_bytes;
12119 +int    var_tls_reseed_period;
12120 +int    var_tls_prng_upd_period;
12121 +
12122 +static int rand_exch_fd;
12123 +static int rand_source_dev_fd = -1;
12124 +static int rand_source_socket_fd = -1;
12125 +static int srvr_scache_db_active;
12126 +static int clnt_scache_db_active;
12127 +static DICT *srvr_scache_db = NULL;
12128 +static DICT *clnt_scache_db = NULL;
12129 +
12130 +static void tlsmgr_prng_upd_event(int unused_event, char *dummy)
12131 +{
12132 +    struct timeval tv;
12133 +    unsigned char buffer[1024];
12134 +    int next_period;
12135 +
12136 +#ifdef HAS_SSL
12137 +    /*
12138 +     * It is time to update the PRNG exchange file. Since other processes might
12139 +     * have added entropy, we do this in a read_stir-back_write cycle.
12140 +     */
12141 +    GETTIMEOFDAY(&tv);
12142 +    RAND_seed(&tv, sizeof(struct timeval));
12143 +
12144 +    if (myflock(rand_exch_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) != 0)
12145 +       msg_fatal("Could not lock random exchange file: %s",
12146 +                 strerror(errno));
12147 +
12148 +    lseek(rand_exch_fd, 0, SEEK_SET);
12149 +    if (read(rand_exch_fd, buffer, 1024) < 0)
12150 +       msg_fatal("reading exchange file failed");
12151 +    RAND_seed(buffer, 1024);
12152 +
12153 +    RAND_bytes(buffer, 1024);
12154 +    lseek(rand_exch_fd, 0, SEEK_SET);
12155 +    if (write(rand_exch_fd, buffer, 1024) != 1024)
12156 +       msg_fatal("Writing exchange file failed");
12157 +
12158 +    if (myflock(rand_exch_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) != 0)
12159 +       msg_fatal("Could not unlock random exchange file: %s",
12160 +                 strerror(errno));
12161 +
12162 +    /*
12163 +     * Make prediction difficult for outsiders and calculate the time for the
12164 +     * next execution randomly.
12165 +     */
12166 +    next_period = (var_tls_prng_upd_period * buffer[0]) / 255;
12167 +    event_request_timer(tlsmgr_prng_upd_event, dummy, next_period);
12168 +#endif
12169 +}
12170 +
12171 +
12172 +static void tlsmgr_reseed_event(int unused_event, char *dummy)
12173 +{
12174 +    int egd_success;
12175 +    int next_period;
12176 +    int rand_bytes;
12177 +    char buffer[255];
12178 +    struct timeval tv;
12179 +    unsigned char randbyte;
12180 +
12181 +#ifdef HAS_SSL
12182 +    /*
12183 +     * It is time to reseed the PRNG.
12184 +     */
12185 +
12186 +    GETTIMEOFDAY(&tv);
12187 +    RAND_seed(&tv, sizeof(struct timeval));
12188 +    if (rand_source_dev_fd != -1) {
12189 +       rand_bytes = read(rand_source_dev_fd, buffer, var_tls_rand_bytes);
12190 +       if (rand_bytes > 0)
12191 +           RAND_seed(buffer, rand_bytes);
12192 +       else if (rand_bytes < 0) {
12193 +           msg_fatal("Read from entropy device %s failed",
12194 +                     var_tls_rand_source);
12195 +       }
12196 +    } else if (rand_source_socket_fd != -1) {
12197 +       egd_success = 0;
12198 +       buffer[0] = 1;
12199 +       buffer[1] = var_tls_rand_bytes;
12200 +       if (write(rand_source_socket_fd, buffer, 2) != 2)
12201 +           msg_info("Could not talk to %s", var_tls_rand_source);
12202 +       else if (read(rand_source_socket_fd, buffer, 1) != 1)
12203 +           msg_info("Could not read info from %s", var_tls_rand_source);
12204 +       else {
12205 +           rand_bytes = buffer[0];
12206 +           if (read(rand_source_socket_fd, buffer, rand_bytes) != rand_bytes)
12207 +               msg_info("Could not read data from %s", var_tls_rand_source);
12208 +           else {
12209 +               egd_success = 1;
12210 +               RAND_seed(buffer, rand_bytes);
12211 +           }
12212 +       }
12213 +       if (!egd_success) {
12214 +           msg_info("Lost connection to EGD-device, exiting to reconnect.");
12215 +           exit(0);
12216 +       }
12217 +    } else if (*var_tls_rand_source) {
12218 +       rand_bytes = RAND_load_file(var_tls_rand_source, var_tls_rand_bytes);
12219 +    }
12220 +
12221 +    /*
12222 +     * Make prediction difficult for outsiders and calculate the time for the
12223 +     * next execution randomly.
12224 +     */
12225 +    RAND_bytes(&randbyte, 1);
12226 +    next_period = (var_tls_reseed_period * randbyte) / 255;
12227 +    event_request_timer(tlsmgr_reseed_event, dummy, next_period);
12228 +#endif
12229 +}
12230 +
12231 +
12232 +static int tlsmgr_do_scache_check(DICT *scache_db, int scache_timeout,
12233 +                                 int start)
12234 +{
12235 +#ifdef HAS_SSL
12236 +    int func;
12237 +    int len;
12238 +    int n;
12239 +    int delete = 0;
12240 +    int result;
12241 +    struct timeval tv;
12242 +    const char *member;
12243 +    const char *value;
12244 +    char *member_copy;
12245 +    unsigned char nibble, *data;
12246 +    pfixtls_scache_info_t scache_info;
12247 +
12248 +    GETTIMEOFDAY(&tv);
12249 +    RAND_seed(&tv, sizeof(struct timeval));
12250 +
12251 +    /*
12252 +     * Run through the given dictionary and check the stored sessions.
12253 +     * If "start" is set to 1, a new run is initiated, otherwise the next
12254 +     * item is accessed. The state is internally kept in the DICT.
12255 +     */
12256 +    if (start)
12257 +       func = DICT_SEQ_FUN_FIRST;
12258 +    else
12259 +       func = DICT_SEQ_FUN_NEXT;
12260 +    result = dict_seq(scache_db, func, &member, &value);
12261 +
12262 +    if (result > 0)
12263 +       return 0;       /* End of list reached */
12264 +    else if (result < 0)
12265 +       msg_fatal("Database fault, should already be caught.");
12266 +    else {
12267 +       member_copy = mystrdup(member);
12268 +       len = strlen(value);
12269 +       RAND_seed(value, len);          /* Use it to increase entropy */
12270 +       if (len < 2 * sizeof(pfixtls_scache_info_t))
12271 +           delete = 1;         /* Messed up, delete */
12272 +       else if (len > 2 * sizeof(pfixtls_scache_info_t))
12273 +           len = 2 * sizeof(pfixtls_scache_info_t);
12274 +       if (!delete) {
12275 +           data = (unsigned char *)(&scache_info);
12276 +           memset(data, 0, len / 2);
12277 +           for (n = 0; n < len; n++) {
12278 +            if ((value[n] >= '0') && (value[n] <= '9'))
12279 +                nibble = value[n] - '0';
12280 +            else
12281 +                nibble = value[n] - 'A' + 10;
12282 +            if (n % 2)
12283 +                data[n / 2] |= nibble;
12284 +            else
12285 +                data[n / 2] |= (nibble << 4);
12286 +        }
12287 +
12288 +        if ((scache_info.scache_db_version != scache_db_version) ||
12289 +            (scache_info.openssl_version != openssl_version) ||
12290 +            (scache_info.timestamp + scache_timeout < time(NULL)))
12291 +           delete = 1;
12292 +       }
12293 +       if (delete)
12294 +           result = dict_del(scache_db, member_copy);
12295 +       myfree(member_copy);
12296 +    }
12297 +
12298 +    if (delete && result)
12299 +       msg_info("Could not delete %s", member);
12300 +    return 1;
12301 +
12302 +#else
12303 +    return 0;
12304 +#endif
12305 +}
12306 +
12307 +static void tlsmgr_clnt_cache_run_event(int unused_event, char *dummy)
12308 +{
12309 +
12310 +    /*
12311 +     * This routine runs when it is time for another tls session cache scan.
12312 +     * Make sure this routine gets called again in the future.
12313 +     */
12314 +    clnt_scache_db_active = tlsmgr_do_scache_check(clnt_scache_db, 
12315 +                               var_smtp_tls_scache_timeout, 1);
12316 +    event_request_timer(tlsmgr_clnt_cache_run_event, dummy,
12317 +                var_smtp_tls_scache_timeout);
12318 +}
12319 +
12320 +
12321 +static void tlsmgr_srvr_cache_run_event(int unused_event, char *dummy)
12322 +{
12323 +
12324 +    /*
12325 +     * This routine runs when it is time for another tls session cache scan.
12326 +     * Make sure this routine gets called again in the future.
12327 +     */
12328 +    srvr_scache_db_active = tlsmgr_do_scache_check(srvr_scache_db,
12329 +                               var_smtpd_tls_scache_timeout, 1);
12330 +    event_request_timer(tlsmgr_srvr_cache_run_event, dummy,
12331 +                var_smtpd_tls_scache_timeout);
12332 +}
12333 +
12334 +
12335 +static DICT *tlsmgr_cache_open(const char *dbname)
12336 +{
12337 +    DICT *retval;
12338 +    char *dbpagname;
12339 +    char *dbdirname;
12340 +
12341 +    /*
12342 +     * First, try to find out the real name of the database file, so that
12343 +     * it can be removed.
12344 +     */
12345 +    if (!strncmp(dbname, "sdbm:", 5)) {
12346 +       dbpagname = concatenate(dbname + 5, ".pag", NULL);
12347 +       REMOVE(dbpagname);
12348 +       myfree(dbpagname);
12349 +       dbdirname = concatenate(dbname + 5, ".dir", NULL);
12350 +       REMOVE(dbdirname);
12351 +       myfree(dbdirname);
12352 +    }
12353 +    else {
12354 +       msg_warn("Only type sdbm: supported: %s", dbname);
12355 +       return NULL;
12356 +    }
12357 +
12358 +    /*
12359 +     * Now open the dictionary. Do it with O_EXCL, so that we only open a
12360 +     * fresh file. If we cannot open it with a fresh file, then we won't
12361 +     * touch it.
12362 +     */
12363 +    retval = dict_open(dbname, O_RDWR | O_CREAT | O_EXCL,
12364 +             DICT_FLAG_DUP_REPLACE | DICT_FLAG_LOCK | DICT_FLAG_SYNC_UPDATE);
12365 +    if (!retval)
12366 +       msg_warn("Could not create dictionary %s", dbname);
12367 +    return retval;
12368 +}
12369 +
12370 +/* tlsmgr_trigger_event - respond to external trigger(s) */
12371 +
12372 +static void tlsmgr_trigger_event(char *buf, int len,
12373 +                                      char *unused_service, char **argv)
12374 +{
12375 +    /*
12376 +     * Sanity check. This service takes no command-line arguments.
12377 +     */
12378 +    if (argv[0])
12379 +       msg_fatal("unexpected command-line argument: %s", argv[0]);
12380 +
12381 +}
12382 +
12383 +/* tlsmgr_loop - queue manager main loop */
12384 +
12385 +static int tlsmgr_loop(char *unused_name, char **unused_argv)
12386 +{
12387 +    /*
12388 +     * This routine runs as part of the event handling loop, after the event
12389 +     * manager has delivered a timer or I/O event (including the completion
12390 +     * of a connection to a delivery process), or after it has waited for a
12391 +     * specified amount of time. The result value of qmgr_loop() specifies
12392 +     * how long the event manager should wait for the next event.
12393 +     */
12394 +#define DONT_WAIT      0
12395 +#define WAIT_FOR_EVENT (-1)
12396 +
12397 +    if (clnt_scache_db_active)
12398 +       clnt_scache_db_active = tlsmgr_do_scache_check(clnt_scache_db,
12399 +                                       var_smtp_tls_scache_timeout, 0);
12400 +    if (srvr_scache_db_active)
12401 +       srvr_scache_db_active = tlsmgr_do_scache_check(srvr_scache_db,
12402 +                                       var_smtpd_tls_scache_timeout, 0);
12403 +    if (clnt_scache_db_active || srvr_scache_db_active)
12404 +       return (DONT_WAIT);
12405 +    return (WAIT_FOR_EVENT);
12406 +}
12407 +
12408 +/* pre_accept - see if tables have changed */
12409 +
12410 +static void pre_accept(char *unused_name, char **unused_argv)
12411 +{
12412 +    if (dict_changed()) {
12413 +       msg_info("table has changed -- exiting");
12414 +       exit(0);
12415 +    }
12416 +}
12417 +
12418 +/* tlsmgr_pre_init - pre-jail initialization */
12419 +
12420 +static void tlsmgr_pre_init(char *unused_name, char **unused_argv)
12421 +{
12422 +    int rand_bytes;
12423 +    unsigned char buffer[255];
12424 +
12425 +#ifdef HAS_SSL
12426 +    /*
12427 +     * Access the external sources for random seed. We may not be able to
12428 +     * access them again if we are sent to chroot jail, so we must leave
12429 +     * dev: and egd: type sources open.
12430 +     */
12431 +    if (*var_tls_rand_source) {
12432 +        if (!strncmp(var_tls_rand_source, "dev:", 4)) {
12433 +           /*
12434 +            * Source is a random device
12435 +            */
12436 +           rand_source_dev_fd = open(var_tls_rand_source + 4, 0, 0);
12437 +           if (rand_source_dev_fd == -1) 
12438 +               msg_fatal("Could not open entropy device %s",
12439 +                         var_tls_rand_source);
12440 +           if (var_tls_rand_bytes > 255)
12441 +               var_tls_rand_bytes = 255;
12442 +           rand_bytes = read(rand_source_dev_fd, buffer, var_tls_rand_bytes);
12443 +           RAND_seed(buffer, rand_bytes);
12444 +       } else if (!strncmp(var_tls_rand_source, "egd:", 4)) {
12445 +           /*
12446 +            * Source is a EGD compatible socket
12447 +            */
12448 +           rand_source_socket_fd = unix_connect(var_tls_rand_source +4,
12449 +                                                BLOCKING, 10);
12450 +           if (rand_source_socket_fd == -1)
12451 +               msg_fatal("Could not connect to %s", var_tls_rand_source);
12452 +           if (var_tls_rand_bytes > 255)
12453 +               var_tls_rand_bytes = 255;
12454 +           buffer[0] = 1;
12455 +           buffer[1] = var_tls_rand_bytes;
12456 +           if (write(rand_source_socket_fd, buffer, 2) != 2)
12457 +               msg_fatal("Could not talk to %s", var_tls_rand_source);
12458 +           if (read(rand_source_socket_fd, buffer, 1) != 1)
12459 +               msg_fatal("Could not read info from %s", var_tls_rand_source);
12460 +           rand_bytes = buffer[0];
12461 +           if (read(rand_source_socket_fd, buffer, rand_bytes) != rand_bytes)
12462 +               msg_fatal("Could not read data from %s", var_tls_rand_source);
12463 +           RAND_seed(buffer, rand_bytes);
12464 +       } else {
12465 +           rand_bytes = RAND_load_file(var_tls_rand_source,
12466 +                                       var_tls_rand_bytes);
12467 +       }
12468 +    }
12469 +#endif
12470 +
12471 +    /*
12472 +     * Now open the PRNG exchange file
12473 +     */
12474 +    if (*var_tls_rand_exch_name) {
12475 +       rand_exch_fd = open(var_tls_rand_exch_name, O_RDWR | O_CREAT, 0600);
12476 +    }
12477 +
12478 +    /*
12479 +     * Finally, open the session cache files. Remove old files, if still there.
12480 +     * If we could not remove the old files, something is pretty wrong and we
12481 +     * won't touch it!!
12482 +     */
12483 +    if (*var_smtp_tls_scache_db)
12484 +       clnt_scache_db = tlsmgr_cache_open(var_smtp_tls_scache_db);
12485 +    if (*var_smtpd_tls_scache_db)
12486 +       srvr_scache_db = tlsmgr_cache_open(var_smtpd_tls_scache_db);
12487 +}
12488 +
12489 +/* qmgr_post_init - post-jail initialization */
12490 +
12491 +static void tlsmgr_post_init(char *unused_name, char **unused_argv)
12492 +{
12493 +    unsigned char buffer[1024];
12494 +
12495 +    /*
12496 +     * This routine runs after the skeleton code has entered the chroot jail.
12497 +     * Prevent automatic process suicide after a limited number of client
12498 +     * requests or after a limited amount of idle time.
12499 +     */
12500 +    var_use_limit = 0;
12501 +    var_idle_limit = 0;
12502 +
12503 +#ifdef HAS_SSL
12504 +    /*
12505 +     * Complete thie initialization by reading the additional seed from the
12506 +     * PRNG exchange file. Don't care how many bytes were actually read, just
12507 +     * seed buffer into the PRNG, regardless of its contents.
12508 +     */
12509 +    if (rand_exch_fd >= 0) {
12510 +       if (myflock(rand_exch_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) == -1)
12511 +           msg_fatal("Could not lock random exchange file: %s",
12512 +                     strerror(errno));
12513 +       read(rand_exch_fd, buffer, 1024);
12514 +       if (myflock(rand_exch_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) == -1)
12515 +           msg_fatal("Could not unlock random exchange file: %s",
12516 +                     strerror(errno));
12517 +       RAND_seed(buffer, 1024);
12518 +       tlsmgr_prng_upd_event(0, (char *) 0);
12519 +       tlsmgr_reseed_event(0, (char *) 0);
12520 +    }
12521 +#endif
12522 +
12523 +    clnt_scache_db_active = 0;
12524 +    srvr_scache_db_active = 0;
12525 +    if (clnt_scache_db)
12526 +       tlsmgr_clnt_cache_run_event(0, (char *) 0);
12527 +    if (srvr_scache_db)
12528 +       tlsmgr_srvr_cache_run_event(0, (char *) 0);
12529 +}
12530 +
12531 +/* main - the main program */
12532 +
12533 +int     main(int argc, char **argv)
12534 +{
12535 +    static CONFIG_STR_TABLE str_table[] = {
12536 +       VAR_TLS_RAND_SOURCE, DEF_TLS_RAND_SOURCE, &var_tls_rand_source, 0, 0,
12537 +       0,
12538 +    };
12539 +    static CONFIG_TIME_TABLE time_table[] = {
12540 +       VAR_TLS_RESEED_PERIOD, DEF_TLS_RESEED_PERIOD, &var_tls_reseed_period, 0, 0,
12541 +       VAR_TLS_PRNG_UPD_PERIOD, DEF_TLS_PRNG_UPD_PERIOD, &var_tls_prng_upd_period, 0, 0,
12542 +       0,
12543 +    };
12544 +    static CONFIG_INT_TABLE int_table[] = {
12545 +       VAR_TLS_RAND_BYTES, DEF_TLS_RAND_BYTES, &var_tls_rand_bytes, 0, 0,
12546 +       0,
12547 +    };
12548 +
12549 +    /*
12550 +     * Use the trigger service skeleton, because no-one else should be
12551 +     * monitoring our service port while this process runs, and because we do
12552 +     * not talk back to the client.
12553 +     */
12554 +    trigger_server_main(argc, argv, tlsmgr_trigger_event,
12555 +                       MAIL_SERVER_TIME_TABLE, time_table,
12556 +                       MAIL_SERVER_INT_TABLE, int_table,
12557 +                       MAIL_SERVER_STR_TABLE, str_table,
12558 +                       MAIL_SERVER_PRE_INIT, tlsmgr_pre_init,
12559 +                       MAIL_SERVER_POST_INIT, tlsmgr_post_init,
12560 +                       MAIL_SERVER_LOOP, tlsmgr_loop,
12561 +                       MAIL_SERVER_PRE_ACCEPT, pre_accept,
12562 +                       0);
12563 +}
12564 diff -Nur snapshot-20010228-orig/src/util/Makefile.in snapshot-20010228/src/util/Makefile.in
12565 --- snapshot-20010228-orig/src/util/Makefile.in Wed Mar 21 13:26:25 2001
12566 +++ snapshot-20010228/src/util/Makefile.in      Wed Mar 21 13:32:23 2001
12567 @@ -23,7 +23,7 @@
12568         clean_env.c watchdog.c spawn_command.c duplex_pipe.c sane_rename.c \
12569         sane_link.c unescape.c timed_read.c timed_write.c dict_tcp.c \
12570         hex_quote.c dict_alloc.c rand_sleep.c sane_time.c dict_debug.c \
12571 -       sane_socketpair.c
12572 +       sane_socketpair.c dict_sdbm.c sdbm.c
12573  OBJS   = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
12574         close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
12575         dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
12576 @@ -48,7 +48,7 @@
12577         clean_env.o watchdog.o spawn_command.o duplex_pipe.o sane_rename.o \
12578         sane_link.o unescape.o timed_read.o timed_write.o dict_tcp.o \
12579         hex_quote.o dict_alloc.o rand_sleep.o sane_time.o dict_debug.o \
12580 -       sane_socketpair.o
12581 +       sane_socketpair.o dict_sdbm.o sdbm.o
12582  HDRS   = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
12583         dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
12584         dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
12585 @@ -64,7 +64,7 @@
12586         vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h \
12587         dict_unix.h dict_pcre.h dict_regexp.h mac_expand.h clean_env.h \
12588         watchdog.h spawn_command.h sane_fsops.h dict_tcp.h hex_quote.h \
12589 -       sane_time.h sane_socketpair.h
12590 +       sane_time.h sane_socketpair.h dict_sdbm.h sdbm.h
12591  TESTSRC        = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
12592         stream_test.c dup2_pass_on_exec.c
12593  WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
12594 @@ -469,6 +469,7 @@
12595  dict_open.o: dict_unix.h
12596  dict_open.o: dict_tcp.h
12597  dict_open.o: dict_dbm.h
12598 +dict_open.o: dict_sdbm.h
12599  dict_open.o: dict_db.h
12600  dict_open.o: dict_nis.h
12601  dict_open.o: dict_nisplus.h
12602 @@ -1051,3 +1052,9 @@
12603  write_wait.o: sys_defs.h
12604  write_wait.o: msg.h
12605  write_wait.o: iostuff.h
12606 +sdbm.o: sdbm.c
12607 +sdbm.o: sdbm.h
12608 +dict_sdbm.o: sdbm.h
12609 +dict_sdbm.o: dict_sdbm.c
12610 +dict_sdbm.o: dict_sdbm.h
12611 +dict_sdbm.o: sys_defs.h
12612 diff -Nur snapshot-20010228-orig/src/util/dict_open.c snapshot-20010228/src/util/dict_open.c
12613 --- snapshot-20010228-orig/src/util/dict_open.c Wed Mar 21 13:26:25 2001
12614 +++ snapshot-20010228/src/util/dict_open.c      Wed Mar 21 13:32:23 2001
12615 @@ -157,6 +157,7 @@
12616  #include <dict_env.h>
12617  #include <dict_unix.h>
12618  #include <dict_tcp.h>
12619 +#include <dict_sdbm.h>
12620  #include <dict_dbm.h>
12621  #include <dict_db.h>
12622  #include <dict_nis.h>
12623 @@ -184,6 +185,7 @@
12624  #if 0
12625      DICT_TYPE_TCP, dict_tcp_open,
12626  #endif
12627 +    "sdbm", dict_sdbm_open,
12628  #ifdef HAS_DBM
12629      DICT_TYPE_DBM, dict_dbm_open,
12630  #endif
12631 diff -Nur snapshot-20010228-orig/src/util/dict_sdbm.c snapshot-20010228/src/util/dict_sdbm.c
12632 --- snapshot-20010228-orig/src/util/dict_sdbm.c Thu Jan  1 01:00:00 1970
12633 +++ snapshot-20010228/src/util/dict_sdbm.c      Wed Mar 21 13:32:24 2001
12634 @@ -0,0 +1,407 @@
12635 +/*++
12636 +/* NAME
12637 +/*     dict_sdbm 3
12638 +/* SUMMARY
12639 +/*     dictionary manager interface to SDBM files
12640 +/* SYNOPSIS
12641 +/*     #include <dict_sdbm.h>
12642 +/*
12643 +/*     DICT    *dict_sdbm_open(path, open_flags, dict_flags)
12644 +/*     const char *name;
12645 +/*     const char *path;
12646 +/*     int     open_flags;
12647 +/*     int     dict_flags;
12648 +/* DESCRIPTION
12649 +/*     dict_sdbm_open() opens the named SDBM database and makes it available
12650 +/*     via the generic interface described in dict_open(3).
12651 +/* DIAGNOSTICS
12652 +/*     Fatal errors: cannot open file, file write error, out of memory.
12653 +/* SEE ALSO
12654 +/*     dict(3) generic dictionary manager
12655 +/*     sdbm(3) data base subroutines
12656 +/* LICENSE
12657 +/* .ad
12658 +/* .fi
12659 +/*     The Secure Mailer license must be distributed with this software.
12660 +/* AUTHOR(S)
12661 +/*     Wietse Venema
12662 +/*     IBM T.J. Watson Research
12663 +/*     P.O. Box 704
12664 +/*     Yorktown Heights, NY 10598, USA
12665 +/*--*/
12666 +
12667 +#include "sys_defs.h"
12668 +
12669 +/* System library. */
12670 +
12671 +#include <sys/stat.h>
12672 +#include <string.h>
12673 +#include <unistd.h>
12674 +
12675 +/* Utility library. */
12676 +
12677 +#include "msg.h"
12678 +#include "mymalloc.h"
12679 +#include "htable.h"
12680 +#include "iostuff.h"
12681 +#include "vstring.h"
12682 +#include "myflock.h"
12683 +#include "stringops.h"
12684 +#include "dict.h"
12685 +#include "dict_sdbm.h"
12686 +#include "sdbm.h"
12687 +
12688 +/* Application-specific. */
12689 +
12690 +typedef struct {
12691 +    DICT    dict;                      /* generic members */
12692 +    SDBM   *dbm;                       /* open database */
12693 +    char   *path;                      /* pathname */
12694 +} DICT_SDBM;
12695 +
12696 +/* dict_sdbm_lookup - find database entry */
12697 +
12698 +static const char *dict_sdbm_lookup(DICT *dict, const char *name)
12699 +{
12700 +    DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
12701 +    datum   dbm_key;
12702 +    datum   dbm_value;
12703 +    static VSTRING *buf;
12704 +    const char *result = 0;
12705 +
12706 +    dict_errno = 0;
12707 +
12708 +    /*
12709 +     * Acquire an exclusive lock.
12710 +     */
12711 +    if ((dict->flags & DICT_FLAG_LOCK)
12712 +       && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
12713 +       msg_fatal("%s: lock dictionary: %m", dict_sdbm->path);
12714 +
12715 +    /*
12716 +     * See if this DBM file was written with one null byte appended to key
12717 +     * and value.
12718 +     */
12719 +    if (dict->flags & DICT_FLAG_TRY1NULL) {
12720 +       dbm_key.dptr = (void *) name;
12721 +       dbm_key.dsize = strlen(name) + 1;
12722 +       dbm_value = sdbm_fetch(dict_sdbm->dbm, dbm_key);
12723 +       if (dbm_value.dptr != 0) {
12724 +           dict->flags &= ~DICT_FLAG_TRY0NULL;
12725 +           result = dbm_value.dptr;
12726 +       }
12727 +    }
12728 +
12729 +    /*
12730 +     * See if this DBM file was written with no null byte appended to key and
12731 +     * value.
12732 +     */
12733 +    if (result == 0 && (dict->flags & DICT_FLAG_TRY0NULL)) {
12734 +       dbm_key.dptr = (void *) name;
12735 +       dbm_key.dsize = strlen(name);
12736 +       dbm_value = sdbm_fetch(dict_sdbm->dbm, dbm_key);
12737 +       if (dbm_value.dptr != 0) {
12738 +           if (buf == 0)
12739 +               buf = vstring_alloc(10);
12740 +           vstring_strncpy(buf, dbm_value.dptr, dbm_value.dsize);
12741 +           dict->flags &= ~DICT_FLAG_TRY1NULL;
12742 +           result = vstring_str(buf);
12743 +       }
12744 +    }
12745 +
12746 +    /*
12747 +     * Release the exclusive lock.
12748 +     */
12749 +    if ((dict->flags & DICT_FLAG_LOCK)
12750 +       && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
12751 +       msg_fatal("%s: unlock dictionary: %m", dict_sdbm->path);
12752 +
12753 +    return (result);
12754 +}
12755 +
12756 +/* dict_sdbm_update - add or update database entry */
12757 +
12758 +static void dict_sdbm_update(DICT *dict, const char *name, const char *value)
12759 +{
12760 +    DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
12761 +    datum   dbm_key;
12762 +    datum   dbm_value;
12763 +    int     status;
12764 +
12765 +    dbm_key.dptr = (void *) name;
12766 +    dbm_value.dptr = (void *) value;
12767 +    dbm_key.dsize = strlen(name);
12768 +    dbm_value.dsize = strlen(value);
12769 +
12770 +    /*
12771 +     * If undecided about appending a null byte to key and value, choose a
12772 +     * default depending on the platform.
12773 +     */
12774 +    if ((dict->flags & DICT_FLAG_TRY1NULL)
12775 +       && (dict->flags & DICT_FLAG_TRY0NULL)) {
12776 +#ifdef DBM_NO_TRAILING_NULL
12777 +       dict->flags &= ~DICT_FLAG_TRY1NULL;
12778 +#else
12779 +       dict->flags &= ~DICT_FLAG_TRY0NULL;
12780 +#endif
12781 +    }
12782 +
12783 +    /*
12784 +     * Optionally append a null byte to key and value.
12785 +     */
12786 +    if (dict->flags & DICT_FLAG_TRY1NULL) {
12787 +       dbm_key.dsize++;
12788 +       dbm_value.dsize++;
12789 +    }
12790 +
12791 +    /*
12792 +     * Acquire an exclusive lock.
12793 +     */
12794 +    if ((dict->flags & DICT_FLAG_LOCK)
12795 +       && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
12796 +       msg_fatal("%s: lock dictionary: %m", dict_sdbm->path);
12797 +
12798 +    /*
12799 +     * Do the update.
12800 +     */
12801 +    if ((status = sdbm_store(dict_sdbm->dbm, dbm_key, dbm_value,
12802 +     (dict->flags & DICT_FLAG_DUP_REPLACE) ? DBM_REPLACE : DBM_INSERT)) < 0)
12803 +       msg_fatal("error writing SDBM database %s: %m", dict_sdbm->path);
12804 +    if (status) {
12805 +       if (dict->flags & DICT_FLAG_DUP_IGNORE)
12806 +            /* void */ ;
12807 +       else if (dict->flags & DICT_FLAG_DUP_WARN)
12808 +           msg_warn("%s: duplicate entry: \"%s\"", dict_sdbm->path, name);
12809 +       else
12810 +           msg_fatal("%s: duplicate entry: \"%s\"", dict_sdbm->path, name);
12811 +    }
12812 +
12813 +    /*
12814 +     * Release the exclusive lock.
12815 +     */
12816 +    if ((dict->flags & DICT_FLAG_LOCK)
12817 +       && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
12818 +       msg_fatal("%s: unlock dictionary: %m", dict_sdbm->path);
12819 +}
12820 +
12821 +
12822 +/* dict_sdbm_delete - delete one entry from the dictionary */
12823 +
12824 +static int dict_sdbm_delete(DICT *dict, const char *name)
12825 +{
12826 +    DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
12827 +    datum   dbm_key;
12828 +    int     status = 1;
12829 +    int     flags = 0;
12830 +
12831 +    /*
12832 +     * Acquire an exclusive lock.
12833 +     */
12834 +    if ((dict->flags & DICT_FLAG_LOCK)
12835 +       && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
12836 +       msg_fatal("%s: lock dictionary: %m", dict_sdbm->path);
12837 +
12838 +    /*
12839 +     * See if this DBM file was written with one null byte appended to key
12840 +     * and value.
12841 +     */
12842 +    if (dict->flags & DICT_FLAG_TRY1NULL) {
12843 +       dbm_key.dptr = (void *) name;
12844 +       dbm_key.dsize = strlen(name) + 1;
12845 +       sdbm_clearerr(dict_sdbm->dbm);
12846 +       if ((status = sdbm_delete(dict_sdbm->dbm, dbm_key)) < 0) {
12847 +           if (sdbm_error(dict_sdbm->dbm) != 0)        /* fatal error */
12848 +               msg_fatal("error deleting from %s: %m", dict_sdbm->path);
12849 +           status = 1;                         /* not found */
12850 +       } else {
12851 +           dict->flags &= ~DICT_FLAG_TRY0NULL; /* found */
12852 +       }
12853 +    }
12854 +
12855 +    /*
12856 +     * See if this DBM file was written with no null byte appended to key and
12857 +     * value.
12858 +     */
12859 +    if (status > 0 && (dict->flags & DICT_FLAG_TRY0NULL)) {
12860 +       dbm_key.dptr = (void *) name;
12861 +       dbm_key.dsize = strlen(name);
12862 +       sdbm_clearerr(dict_sdbm->dbm);
12863 +       if ((status = sdbm_delete(dict_sdbm->dbm, dbm_key)) < 0) {
12864 +           if (sdbm_error(dict_sdbm->dbm) != 0)        /* fatal error */
12865 +               msg_fatal("error deleting from %s: %m", dict_sdbm->path);
12866 +           status = 1;                         /* not found */
12867 +       } else {
12868 +           dict->flags &= ~DICT_FLAG_TRY1NULL; /* found */
12869 +       }
12870 +    }
12871 +
12872 +    /*
12873 +     * Release the exclusive lock.
12874 +     */
12875 +    if ((dict->flags & DICT_FLAG_LOCK)
12876 +       && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
12877 +       msg_fatal("%s: unlock dictionary: %m", dict_sdbm->path);
12878 +
12879 +    return (status);
12880 +}
12881 +
12882 +/* traverse the dictionary */
12883 +
12884 +static int dict_sdbm_sequence(DICT *dict, const int function,
12885 +                                    const char **key, const char **value)
12886 +{
12887 +    char   *myname = "dict_sdbm_sequence";
12888 +    DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
12889 +    datum   dbm_key;
12890 +    datum   dbm_value;
12891 +    int     status = 0;
12892 +    static VSTRING *key_buf;
12893 +    static VSTRING *value_buf;
12894 +
12895 +    /*
12896 +     * Acquire an exclusive lock.
12897 +     */
12898 +    if ((dict->flags & DICT_FLAG_LOCK)
12899 +       && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
12900 +       msg_fatal("%s: lock dictionary: %m", dict_sdbm->path);
12901 +
12902 +    /*
12903 +     * Determine and execute the seek function. It returns the key.
12904 +     */
12905 +    switch (function) {
12906 +    case DICT_SEQ_FUN_FIRST:
12907 +       dbm_key = sdbm_firstkey(dict_sdbm->dbm);
12908 +       break;
12909 +    case DICT_SEQ_FUN_NEXT:
12910 +       dbm_key = sdbm_nextkey(dict_sdbm->dbm);
12911 +       break;
12912 +    default:
12913 +       msg_panic("%s: invalid function: %d", myname, function);
12914 +    }
12915 +
12916 +    /*
12917 +     * Release the exclusive lock.
12918 +     */
12919 +    if ((dict->flags & DICT_FLAG_LOCK)
12920 +       && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
12921 +       msg_fatal("%s: unlock dictionary: %m", dict_sdbm->path);
12922 +
12923 +    if (dbm_key.dptr != 0 && dbm_key.dsize > 0) {
12924 +
12925 +       /*
12926 +        * See if this DB file was written with one null byte appended to key
12927 +        * an d value or not. If necessary, copy the key.
12928 +        */
12929 +       if (((char *) dbm_key.dptr)[dbm_key.dsize - 1] == 0) {
12930 +           *key = dbm_key.dptr;
12931 +       } else {
12932 +           if (key_buf == 0)
12933 +               key_buf = vstring_alloc(10);
12934 +           vstring_strncpy(key_buf, dbm_key.dptr, dbm_key.dsize);
12935 +           *key = vstring_str(key_buf);
12936 +       }
12937 +
12938 +       /*
12939 +        * Fetch the corresponding value.
12940 +        */
12941 +       dbm_value = sdbm_fetch(dict_sdbm->dbm, dbm_key);
12942 +
12943 +       if (dbm_value.dptr != 0 && dbm_value.dsize > 0) {
12944 +
12945 +           /*
12946 +            * See if this DB file was written with one null byte appended to
12947 +            * key and value or not. If necessary, copy the key.
12948 +            */
12949 +           if (((char *) dbm_value.dptr)[dbm_value.dsize - 1] == 0) {
12950 +               *value = dbm_value.dptr;
12951 +           } else {
12952 +               if (value_buf == 0)
12953 +                   value_buf = vstring_alloc(10);
12954 +               vstring_strncpy(value_buf, dbm_value.dptr, dbm_value.dsize);
12955 +               *value = vstring_str(value_buf);
12956 +           }
12957 +       } else {
12958 +
12959 +           /*
12960 +            * Determine if we have hit the last record or an error
12961 +            * condition.
12962 +            */
12963 +           if (sdbm_error(dict_sdbm->dbm))
12964 +               msg_fatal("error seeking %s: %m", dict_sdbm->path);
12965 +           return (1);                         /* no error: eof/not found
12966 +                                                * (should not happen!) */
12967 +       }
12968 +    } else {
12969 +
12970 +       /*
12971 +        * Determine if we have hit the last record or an error condition.
12972 +        */
12973 +       if (sdbm_error(dict_sdbm->dbm))
12974 +           msg_fatal("error seeking %s: %m", dict_sdbm->path);
12975 +       return (1);                             /* no error: eof/not found */
12976 +    }
12977 +    return (0);
12978 +}
12979 +
12980 +/* dict_sdbm_close - disassociate from data base */
12981 +
12982 +static void dict_sdbm_close(DICT *dict)
12983 +{
12984 +    DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
12985 +
12986 +    sdbm_close(dict_sdbm->dbm);
12987 +    myfree(dict_sdbm->path);
12988 +    myfree((char *) dict_sdbm);
12989 +}
12990 +
12991 +/* dict_sdbm_open - open SDBM data base */
12992 +
12993 +DICT   *dict_sdbm_open(const char *path, int open_flags, int dict_flags)
12994 +{
12995 +    DICT_SDBM *dict_sdbm;
12996 +    struct stat st;
12997 +    SDBM   *dbm;
12998 +    char   *dbm_path;
12999 +    int     lock_fd;
13000 +
13001 +    if (dict_flags & DICT_FLAG_LOCK) {
13002 +       dbm_path = concatenate(path, ".pag", (char *) 0);
13003 +       if ((lock_fd = open(dbm_path, open_flags, 0644)) < 0)
13004 +           msg_fatal("open database %s: %m", dbm_path);
13005 +       if (myflock(lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
13006 +           msg_fatal("shared-lock database %s for open: %m", dbm_path);
13007 +    }
13008 +
13009 +    /*
13010 +     * XXX SunOS 5.x has no const in dbm_open() prototype.
13011 +     */
13012 +    if ((dbm = sdbm_open((char *) path, open_flags, 0644)) == 0)
13013 +       msg_fatal("open database %s.{dir,pag}: %m", path);
13014 +
13015 +    if (dict_flags & DICT_FLAG_LOCK) {
13016 +       if (myflock(lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
13017 +           msg_fatal("unlock database %s for open: %m", dbm_path);
13018 +       if (close(lock_fd) < 0)
13019 +           msg_fatal("close database %s: %m", dbm_path);
13020 +       myfree(dbm_path);
13021 +    }
13022 +    dict_sdbm = (DICT_SDBM *) mymalloc(sizeof(*dict_sdbm));
13023 +    dict_sdbm->dict.lookup = dict_sdbm_lookup;
13024 +    dict_sdbm->dict.update = dict_sdbm_update;
13025 +    dict_sdbm->dict.delete = dict_sdbm_delete;
13026 +    dict_sdbm->dict.sequence = dict_sdbm_sequence;
13027 +    dict_sdbm->dict.close = dict_sdbm_close;
13028 +    dict_sdbm->dict.fd = sdbm_pagfno(dbm);
13029 +    if (fstat(dict_sdbm->dict.fd, &st) < 0)
13030 +       msg_fatal("dict_sdbm_open: fstat: %m");
13031 +    dict_sdbm->dict.mtime = st.st_mtime;
13032 +    close_on_exec(sdbm_pagfno(dbm), CLOSE_ON_EXEC);
13033 +    close_on_exec(sdbm_dirfno(dbm), CLOSE_ON_EXEC);
13034 +    dict_sdbm->dict.flags = dict_flags | DICT_FLAG_FIXED;
13035 +    if ((dict_flags & (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL)) == 0)
13036 +       dict_sdbm->dict.flags |= (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL);
13037 +    dict_sdbm->dbm = dbm;
13038 +    dict_sdbm->path = mystrdup(path);
13039 +
13040 +    return (&dict_sdbm->dict);
13041 +}
13042 diff -Nur snapshot-20010228-orig/src/util/dict_sdbm.h snapshot-20010228/src/util/dict_sdbm.h
13043 --- snapshot-20010228-orig/src/util/dict_sdbm.h Thu Jan  1 01:00:00 1970
13044 +++ snapshot-20010228/src/util/dict_sdbm.h      Wed Mar 21 13:32:24 2001
13045 @@ -0,0 +1,35 @@
13046 +#ifndef _DICT_SDBM_H_INCLUDED_
13047 +#define _DICT_SDBM_H_INCLUDED_
13048 +
13049 +/*++
13050 +/* NAME
13051 +/*     dict_dbm 3h
13052 +/* SUMMARY
13053 +/*     dictionary manager interface to DBM files
13054 +/* SYNOPSIS
13055 +/*     #include <dict_dbm.h>
13056 +/* DESCRIPTION
13057 +/* .nf
13058 +
13059 + /*
13060 +  * Utility library.
13061 +  */
13062 +#include <dict.h>
13063 +
13064 + /*
13065 +  * External interface.
13066 +  */
13067 +extern DICT *dict_sdbm_open(const char *, int, int);
13068 +
13069 +/* LICENSE
13070 +/* .ad
13071 +/* .fi
13072 +/*     The Secure Mailer license must be distributed with this software.
13073 +/* AUTHOR(S)
13074 +/*     Wietse Venema
13075 +/*     IBM T.J. Watson Research
13076 +/*     P.O. Box 704
13077 +/*     Yorktown Heights, NY 10598, USA
13078 +/*--*/
13079 +
13080 +#endif
13081 diff -Nur snapshot-20010228-orig/src/util/sdbm.c snapshot-20010228/src/util/sdbm.c
13082 --- snapshot-20010228-orig/src/util/sdbm.c      Thu Jan  1 01:00:00 1970
13083 +++ snapshot-20010228/src/util/sdbm.c   Wed Mar 21 13:32:24 2001
13084 @@ -0,0 +1,939 @@
13085 +/*++
13086 +/* NAME
13087 +/*      sdbm 3h
13088 +/* SUMMARY
13089 +/*      SDBM Simple DBM: ndbm work-alike hashed database library
13090 +/* SYNOPSIS
13091 +/*      include "sdbm.h"
13092 +/* DESCRIPTION
13093 +/* .nf
13094 +/*--*/
13095 +
13096 +/*
13097 + * sdbm - ndbm work-alike hashed database library
13098 + * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
13099 + * author: oz@nexus.yorku.ca
13100 + * status: public domain.
13101 + *
13102 + * core routines
13103 + */
13104 +
13105 +#include <stdio.h>
13106 +#include <stdlib.h>
13107 +#ifdef WIN32
13108 +#include <io.h>
13109 +#include <errno.h>
13110 +#else
13111 +#include <unistd.h>
13112 +#endif
13113 +#include <sys/types.h>
13114 +#include <sys/stat.h>
13115 +#include <fcntl.h>
13116 +#include <errno.h>
13117 +#include <string.h>
13118 +#ifdef __STDC__
13119 +#include <stddef.h>
13120 +#endif
13121 +
13122 +#include <sdbm.h>
13123 +
13124 +/*
13125 + * useful macros
13126 + */
13127 +#define bad(x)          ((x).dptr == NULL || (x).dsize <= 0)
13128 +#define exhash(item)    sdbm_hash((item).dptr, (item).dsize)
13129 +#define ioerr(db)       ((db)->flags |= DBM_IOERR)
13130 +
13131 +#define OFF_PAG(off)    (long) (off) * PBLKSIZ
13132 +#define OFF_DIR(off)    (long) (off) * DBLKSIZ
13133 +
13134 +static long masks[] =
13135 +{
13136 +    000000000000, 000000000001, 000000000003, 000000000007,
13137 +    000000000017, 000000000037, 000000000077, 000000000177,
13138 +    000000000377, 000000000777, 000000001777, 000000003777,
13139 +    000000007777, 000000017777, 000000037777, 000000077777,
13140 +    000000177777, 000000377777, 000000777777, 000001777777,
13141 +    000003777777, 000007777777, 000017777777, 000037777777,
13142 +    000077777777, 000177777777, 000377777777, 000777777777,
13143 +    001777777777, 003777777777, 007777777777, 017777777777
13144 +};
13145 +
13146 +datum   nullitem =
13147 +{NULL, 0};
13148 +
13149 +typedef struct
13150 +{
13151 +    int     dirf;                      /* directory file descriptor */
13152 +    int     pagf;                      /* page file descriptor */
13153 +    int     flags;                     /* status/error flags, see below */
13154 +    long    maxbno;                    /* size of dirfile in bits */
13155 +    long    curbit;                    /* current bit number */
13156 +    long    hmask;                     /* current hash mask */
13157 +    long    blkptr;                    /* current block for nextkey */
13158 +    int     keyptr;                    /* current key for nextkey */
13159 +    long    blkno;                     /* current page to read/write */
13160 +    long    pagbno;                    /* current page in pagbuf */
13161 +    char   *pagbuf;                    /* page file block buffer */
13162 +    long    dirbno;                    /* current block in dirbuf */
13163 +    char   *dirbuf;                    /* directory file block buffer */
13164 +}       DBM;
13165 +
13166 +
13167 +/* ************************* */
13168 +
13169 +/*
13170 + * sdbm - ndbm work-alike hashed database library
13171 + * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
13172 + * author: oz@nexus.yorku.ca
13173 + * status: public domain. keep it that way.
13174 + *
13175 + * hashing routine
13176 + */
13177 +
13178 +/*
13179 + * polynomial conversion ignoring overflows
13180 + * [this seems to work remarkably well, in fact better
13181 + * then the ndbm hash function. Replace at your own risk]
13182 + * use: 65599   nice.
13183 + *      65587   even better.
13184 + */
13185 +static long sdbm_hash (char *str, int len)
13186 +{
13187 +    unsigned long n = 0;
13188 +
13189 +#ifdef DUFF
13190 +#define HASHC   n = *str++ + 65599 * n
13191 +    if (len > 0)
13192 +      {
13193 +         int     loop = (len + 8 - 1) >> 3;
13194 +
13195 +         switch (len & (8 - 1))
13196 +           {
13197 +           case 0:
13198 +               do
13199 +                 {
13200 +                     HASHC;
13201 +           case 7:
13202 +                     HASHC;
13203 +           case 6:
13204 +                     HASHC;
13205 +           case 5:
13206 +                     HASHC;
13207 +           case 4:
13208 +                     HASHC;
13209 +           case 3:
13210 +                     HASHC;
13211 +           case 2:
13212 +                     HASHC;
13213 +           case 1:
13214 +                     HASHC;
13215 +                 }
13216 +               while (--loop);
13217 +           }
13218 +
13219 +      }
13220 +#else
13221 +    while (len--)
13222 +       n = *str++ + 65599 * n;
13223 +#endif
13224 +    return n;
13225 +}
13226 +
13227 +/*
13228 + * check page sanity:
13229 + * number of entries should be something
13230 + * reasonable, and all offsets in the index should be in order.
13231 + * this could be made more rigorous.
13232 + */
13233 +static int chkpage (char *pag)
13234 +{
13235 +    int     n;
13236 +    int     off;
13237 +    short  *ino = (short *) pag;
13238 +
13239 +    if ((n = ino[0]) < 0 || n > PBLKSIZ / sizeof (short))
13240 +               return 0;
13241 +
13242 +    if (n > 0)
13243 +      {
13244 +         off = PBLKSIZ;
13245 +         for (ino++; n > 0; ino += 2)
13246 +           {
13247 +               if (ino[0] > off || ino[1] > off ||
13248 +                   ino[1] > ino[0])
13249 +                   return 0;
13250 +               off = ino[1];
13251 +               n -= 2;
13252 +           }
13253 +      }
13254 +    return 1;
13255 +}
13256 +
13257 +/*
13258 + * search for the key in the page.
13259 + * return offset index in the range 0 < i < n.
13260 + * return 0 if not found.
13261 + */
13262 +static int seepair (char *pag, int n, char *key, int siz)
13263 +{
13264 +    int     i;
13265 +    int     off = PBLKSIZ;
13266 +    short  *ino = (short *) pag;
13267 +
13268 +    for (i = 1; i < n; i += 2)
13269 +      {
13270 +         if (siz == off - ino[i] &&
13271 +             memcmp (key, pag + ino[i], siz) == 0)
13272 +             return i;
13273 +         off = ino[i + 1];
13274 +      }
13275 +    return 0;
13276 +}
13277 +
13278 +#ifdef SEEDUPS
13279 +static int duppair (char *pag, datum key)
13280 +{
13281 +    short  *ino = (short *) pag;
13282 +
13283 +    return ino[0] > 0 && seepair (pag, ino[0], key.dptr, key.dsize) > 0;
13284 +}
13285 +
13286 +#endif
13287 +
13288 +/* ************************* */
13289 +
13290 +/*
13291 + * sdbm - ndbm work-alike hashed database library
13292 + * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
13293 + * author: oz@nexus.yorku.ca
13294 + * status: public domain.
13295 + *
13296 + * page-level routines
13297 + */
13298 +
13299 +/*
13300 + * page format:
13301 + *      +------------------------------+
13302 + * ino  | n | keyoff | datoff | keyoff |
13303 + *      +------------+--------+--------+
13304 + *      | datoff | - - - ---->         |
13305 + *      +--------+---------------------+
13306 + *      |        F R E E A R E A       |
13307 + *      +--------------+---------------+
13308 + *      |  <---- - - - | data          |
13309 + *      +--------+-----+----+----------+
13310 + *      |  key   | data     | key      |
13311 + *      +--------+----------+----------+
13312 + *
13313 + * calculating the offsets for free area:  if the number
13314 + * of entries (ino[0]) is zero, the offset to the END of
13315 + * the free area is the block size. Otherwise, it is the
13316 + * nth (ino[ino[0]]) entry's offset.
13317 + */
13318 +
13319 +static int fitpair (char *pag, int need)
13320 +{
13321 +    int     n;
13322 +    int     off;
13323 +    int     avail;
13324 +    short  *ino = (short *) pag;
13325 +
13326 +    off = ((n = ino[0]) > 0) ? ino[n] : PBLKSIZ;
13327 +    avail = off - (n + 1) * sizeof (short);
13328 +    need += 2 * sizeof (short);
13329 +
13330 +    return need <= avail;
13331 +}
13332 +
13333 +static void putpair (char *pag, datum key, datum val)
13334 +{
13335 +    int     n;
13336 +    int     off;
13337 +    short  *ino = (short *) pag;
13338 +
13339 +    off = ((n = ino[0]) > 0) ? ino[n] : PBLKSIZ;
13340 +/*
13341 + * enter the key first
13342 + */
13343 +    off -= key.dsize;
13344 +    (void) memcpy (pag + off, key.dptr, key.dsize);
13345 +    ino[n + 1] = off;
13346 +/*
13347 + * now the data
13348 + */
13349 +    off -= val.dsize;
13350 +    (void) memcpy (pag + off, val.dptr, val.dsize);
13351 +    ino[n + 2] = off;
13352 +/*
13353 + * adjust item count
13354 + */
13355 +    ino[0] += 2;
13356 +}
13357 +
13358 +static datum getpair (char *pag, datum key)
13359 +{
13360 +    int     i;
13361 +    int     n;
13362 +    datum   val;
13363 +    short  *ino = (short *) pag;
13364 +
13365 +    if ((n = ino[0]) == 0)
13366 +       return nullitem;
13367 +
13368 +    if ((i = seepair (pag, n, key.dptr, key.dsize)) == 0)
13369 +       return nullitem;
13370 +
13371 +    val.dptr = pag + ino[i + 1];
13372 +    val.dsize = ino[i] - ino[i + 1];
13373 +    return val;
13374 +}
13375 +
13376 +static datum getnkey (char *pag, int num)
13377 +{
13378 +    datum   key;
13379 +    int     off;
13380 +    short  *ino = (short *) pag;
13381 +
13382 +    num = num * 2 - 1;
13383 +    if (ino[0] == 0 || num > ino[0])
13384 +       return nullitem;
13385 +
13386 +    off = (num > 1) ? ino[num - 1] : PBLKSIZ;
13387 +
13388 +    key.dptr = pag + ino[num];
13389 +    key.dsize = off - ino[num];
13390 +
13391 +    return key;
13392 +}
13393 +
13394 +static int delpair (char *pag, datum key)
13395 +{
13396 +    int     n;
13397 +    int     i;
13398 +    short  *ino = (short *) pag;
13399 +
13400 +    if ((n = ino[0]) == 0)
13401 +       return 0;
13402 +
13403 +    if ((i = seepair (pag, n, key.dptr, key.dsize)) == 0)
13404 +       return 0;
13405 +/*
13406 + * found the key. if it is the last entry
13407 + * [i.e. i == n - 1] we just adjust the entry count.
13408 + * hard case: move all data down onto the deleted pair,
13409 + * shift offsets onto deleted offsets, and adjust them.
13410 + * [note: 0 < i < n]
13411 + */
13412 +    if (i < n - 1)
13413 +      {
13414 +         int     m;
13415 +         char   *dst = pag + (i == 1 ? PBLKSIZ : ino[i - 1]);
13416 +         char   *src = pag + ino[i + 1];
13417 +         int     zoo = dst - src;
13418 +
13419 +/*
13420 + * shift data/keys down
13421 + */
13422 +         m = ino[i + 1] - ino[n];
13423 +#ifdef DUFF
13424 +#define MOVB    *--dst = *--src
13425 +         if (m > 0)
13426 +           {
13427 +               int     loop = (m + 8 - 1) >> 3;
13428 +
13429 +               switch (m & (8 - 1))
13430 +                 {
13431 +                 case 0:
13432 +                     do
13433 +                       {
13434 +                           MOVB;
13435 +                 case 7:
13436 +                           MOVB;
13437 +                 case 6:
13438 +                           MOVB;
13439 +                 case 5:
13440 +                           MOVB;
13441 +                 case 4:
13442 +                           MOVB;
13443 +                 case 3:
13444 +                           MOVB;
13445 +                 case 2:
13446 +                           MOVB;
13447 +                 case 1:
13448 +                           MOVB;
13449 +                       }
13450 +                     while (--loop);
13451 +                 }
13452 +           }
13453 +#else
13454 +         dst -= m;
13455 +         src -= m;
13456 +         memmove (dst, src, m);
13457 +#endif
13458 +/*
13459 + * adjust offset index up
13460 + */
13461 +         while (i < n - 1)
13462 +           {
13463 +               ino[i] = ino[i + 2] + zoo;
13464 +               i++;
13465 +           }
13466 +      }
13467 +    ino[0] -= 2;
13468 +    return 1;
13469 +}
13470 +
13471 +static void splpage (char *pag, char *new, long sbit)
13472 +{
13473 +    datum   key;
13474 +    datum   val;
13475 +
13476 +    int     n;
13477 +    int     off = PBLKSIZ;
13478 +    char    cur[PBLKSIZ];
13479 +    short  *ino = (short *) cur;
13480 +
13481 +    (void) memcpy (cur, pag, PBLKSIZ);
13482 +    (void) memset (pag, 0, PBLKSIZ);
13483 +    (void) memset (new, 0, PBLKSIZ);
13484 +
13485 +    n = ino[0];
13486 +    for (ino++; n > 0; ino += 2)
13487 +      {
13488 +         key.dptr = cur + ino[0];
13489 +         key.dsize = off - ino[0];
13490 +         val.dptr = cur + ino[1];
13491 +         val.dsize = ino[0] - ino[1];
13492 +/*
13493 + * select the page pointer (by looking at sbit) and insert
13494 + */
13495 +         (void) putpair ((exhash (key) & sbit) ? new : pag, key, val);
13496 +
13497 +         off = ino[1];
13498 +         n -= 2;
13499 +      }
13500 +}
13501 +
13502 +static int getdbit (DBM * db, long dbit)
13503 +{
13504 +    long    c;
13505 +    long    dirb;
13506 +
13507 +    c = dbit / BYTESIZ;
13508 +    dirb = c / DBLKSIZ;
13509 +
13510 +    if (dirb != db->dirbno)
13511 +      {
13512 +         if (lseek (db->dirf, OFF_DIR (dirb), SEEK_SET) < 0
13513 +             || read (db->dirf, db->dirbuf, DBLKSIZ) < 0)
13514 +             return 0;
13515 +         db->dirbno = dirb;
13516 +      }
13517 +
13518 +    return db->dirbuf[c % DBLKSIZ] & (1 << dbit % BYTESIZ);
13519 +}
13520 +
13521 +static int setdbit (DBM * db, long dbit)
13522 +{
13523 +    long    c;
13524 +    long    dirb;
13525 +
13526 +    c = dbit / BYTESIZ;
13527 +    dirb = c / DBLKSIZ;
13528 +
13529 +    if (dirb != db->dirbno)
13530 +      {
13531 +         if (lseek (db->dirf, OFF_DIR (dirb), SEEK_SET) < 0
13532 +             || read (db->dirf, db->dirbuf, DBLKSIZ) < 0)
13533 +             return 0;
13534 +         db->dirbno = dirb;
13535 +      }
13536 +
13537 +    db->dirbuf[c % DBLKSIZ] |= (1 << dbit % BYTESIZ);
13538 +
13539 +    if (dbit >= db->maxbno)
13540 +       db->maxbno += DBLKSIZ * BYTESIZ;
13541 +
13542 +    if (lseek (db->dirf, OFF_DIR (dirb), SEEK_SET) < 0
13543 +       || write (db->dirf, db->dirbuf, DBLKSIZ) < 0)
13544 +       return 0;
13545 +
13546 +    return 1;
13547 +}
13548 +
13549 +/*
13550 + * getnext - get the next key in the page, and if done with
13551 + * the page, try the next page in sequence
13552 + */
13553 +static datum getnext (DBM * db)
13554 +{
13555 +    datum   key;
13556 +
13557 +    for (;;)
13558 +      {
13559 +         db->keyptr++;
13560 +         key = getnkey (db->pagbuf, db->keyptr);
13561 +         if (key.dptr != NULL)
13562 +             return key;
13563 +/*
13564 + * we either run out, or there is nothing on this page..
13565 + * try the next one... If we lost our position on the
13566 + * file, we will have to seek.
13567 + */
13568 +         db->keyptr = 0;
13569 +         if (db->pagbno != db->blkptr++)
13570 +             if (lseek (db->pagf, OFF_PAG (db->blkptr), SEEK_SET) < 0)
13571 +                 break;
13572 +         db->pagbno = db->blkptr;
13573 +         if (read (db->pagf, db->pagbuf, PBLKSIZ) <= 0)
13574 +             break;
13575 +         if (!chkpage (db->pagbuf))
13576 +             break;
13577 +      }
13578 +
13579 +    return ioerr (db), nullitem;
13580 +}
13581 +
13582 +/*
13583 + * all important binary trie traversal
13584 + */
13585 +static int getpage (DBM * db, long hash)
13586 +{
13587 +    int     hbit;
13588 +    long    dbit;
13589 +    long    pagb;
13590 +
13591 +    dbit = 0;
13592 +    hbit = 0;
13593 +    while (dbit < db->maxbno && getdbit (db, dbit))
13594 +       dbit = 2 * dbit + ((hash & (1 << hbit++)) ? 2 : 1);
13595 +
13596 +    db->curbit = dbit;
13597 +    db->hmask = masks[hbit];
13598 +
13599 +    pagb = hash & db->hmask;
13600 +/*
13601 + * see if the block we need is already in memory.
13602 + * note: this lookaside cache has about 10% hit rate.
13603 + */
13604 +    if (pagb != db->pagbno)
13605 +      {
13606 +/*
13607 + * note: here, we assume a "hole" is read as 0s.
13608 + * if not, must zero pagbuf first.
13609 + */
13610 +         if (lseek (db->pagf, OFF_PAG (pagb), SEEK_SET) < 0
13611 +             || read (db->pagf, db->pagbuf, PBLKSIZ) < 0)
13612 +             return 0;
13613 +         if (!chkpage (db->pagbuf))
13614 +             return 0;
13615 +         db->pagbno = pagb;
13616 +      }
13617 +    return 1;
13618 +}
13619 +
13620 +/*
13621 + * makroom - make room by splitting the overfull page
13622 + * this routine will attempt to make room for SPLTMAX times before
13623 + * giving up.
13624 + */
13625 +static int makroom (DBM * db, long hash, int need)
13626 +{
13627 +    long    newp;
13628 +    char    twin[PBLKSIZ];
13629 +    char   *pag = db->pagbuf;
13630 +    char   *new = twin;
13631 +    int     smax = SPLTMAX;
13632 +
13633 +    do
13634 +      {
13635 +/*
13636 + * split the current page
13637 + */
13638 +         (void) splpage (pag, new, db->hmask + 1);
13639 +/*
13640 + * address of the new page
13641 + */
13642 +         newp = (hash & db->hmask) | (db->hmask + 1);
13643 +
13644 +/*
13645 + * write delay, read avoidence/cache shuffle:
13646 + * select the page for incoming pair: if key is to go to the new page,
13647 + * write out the previous one, and copy the new one over, thus making
13648 + * it the current page. If not, simply write the new page, and we are
13649 + * still looking at the page of interest. current page is not updated
13650 + * here, as sdbm_store will do so, after it inserts the incoming pair.
13651 + */
13652 +         if (hash & (db->hmask + 1))
13653 +           {
13654 +               if (lseek (db->pagf, OFF_PAG (db->pagbno), SEEK_SET) < 0
13655 +                   || write (db->pagf, db->pagbuf, PBLKSIZ) < 0)
13656 +                   return 0;
13657 +               db->pagbno = newp;
13658 +               (void) memcpy (pag, new, PBLKSIZ);
13659 +           }
13660 +         else if (lseek (db->pagf, OFF_PAG (newp), SEEK_SET) < 0
13661 +                  || write (db->pagf, new, PBLKSIZ) < 0)
13662 +             return 0;
13663 +
13664 +         if (!setdbit (db, db->curbit))
13665 +             return 0;
13666 +/*
13667 + * see if we have enough room now
13668 + */
13669 +         if (fitpair (pag, need))
13670 +             return 1;
13671 +/*
13672 + * try again... update curbit and hmask as getpage would have
13673 + * done. because of our update of the current page, we do not
13674 + * need to read in anything. BUT we have to write the current
13675 + * [deferred] page out, as the window of failure is too great.
13676 + */
13677 +         db->curbit = 2 * db->curbit +
13678 +             ((hash & (db->hmask + 1)) ? 2 : 1);
13679 +         db->hmask |= db->hmask + 1;
13680 +
13681 +         if (lseek (db->pagf, OFF_PAG (db->pagbno), SEEK_SET) < 0
13682 +             || write (db->pagf, db->pagbuf, PBLKSIZ) < 0)
13683 +             return 0;
13684 +
13685 +      }
13686 +    while (--smax);
13687 +/*
13688 + * if we are here, this is real bad news. After SPLTMAX splits,
13689 + * we still cannot fit the key. say goodnight.
13690 + */
13691 +#ifdef BADMESS
13692 +    (void) write (2, "sdbm: cannot insert after SPLTMAX attempts.\n", 44);
13693 +#endif
13694 +    return 0;
13695 +
13696 +}
13697 +
13698 +static SDBM *sdbm_prep (char *dirname, char *pagname, int flags, int mode)
13699 +{
13700 +    SDBM   *db;
13701 +    struct stat dstat;
13702 +
13703 +    if ((db = (SDBM *) mymalloc (sizeof (SDBM))) == NULL)
13704 +       return errno = ENOMEM, (SDBM *) NULL;
13705 +
13706 +    db->flags = 0;
13707 +    db->blkptr = 0;
13708 +    db->keyptr = 0;
13709 +/*
13710 + * adjust user flags so that WRONLY becomes RDWR,
13711 + * as required by this package. Also set our internal
13712 + * flag for RDONLY if needed.
13713 + */
13714 +    if (flags & O_WRONLY)
13715 +       flags = (flags & ~O_WRONLY) | O_RDWR;
13716 +    else if ((flags & 03) == O_RDONLY)
13717 +       db->flags = DBM_RDONLY;
13718 +#if defined(OS2) || defined(MSDOS) || defined(WIN32)
13719 +    flags |= O_BINARY;
13720 +#endif
13721 +
13722 +/*
13723 + * Make sure to ignore the O_EXCL option, as the file might exist due
13724 + * to the locking.
13725 + */
13726 +    flags &= ~O_EXCL;
13727 +
13728 +/*
13729 + * open the files in sequence, and stat the dirfile.
13730 + * If we fail anywhere, undo everything, return NULL.
13731 + */
13732 +
13733 +    if ((db->pagf = open (pagname, flags, mode)) > -1)
13734 +      {
13735 +         if ((db->dirf = open (dirname, flags, mode)) > -1)
13736 +           {
13737 +/*
13738 + * need the dirfile size to establish max bit number.
13739 + */
13740 +               if (fstat (db->dirf, &dstat) == 0)
13741 +                 {
13742 +                     /*
13743 +                       * success
13744 +                       */
13745 +                     return db;
13746 +                 }
13747 +               msg_info ("closing dirf");
13748 +               (void) close (db->dirf);
13749 +           }
13750 +         msg_info ("closing pagf");
13751 +         (void) close (db->pagf);
13752 +      }
13753 +    myfree ((char *) db);
13754 +    return (SDBM *) NULL;
13755 +}
13756 +
13757 +static DBM *sdbm_internal_open (SDBM * sdbm)
13758 +{
13759 +    DBM    *db;
13760 +    struct stat dstat;
13761 +
13762 +    if ((db = (DBM *) mymalloc (sizeof (DBM))) == NULL)
13763 +       return errno = ENOMEM, (DBM *) NULL;
13764 +
13765 +    db->flags = sdbm->flags;
13766 +    db->hmask = 0;
13767 +    db->blkptr = sdbm->blkptr;
13768 +    db->keyptr = sdbm->keyptr;
13769 +    db->pagf = sdbm->pagf;
13770 +    db->dirf = sdbm->dirf;
13771 +    db->pagbuf = sdbm->pagbuf;
13772 +    db->dirbuf = sdbm->dirbuf;
13773 +
13774 +/*
13775 + * need the dirfile size to establish max bit number.
13776 + */
13777 +    if (fstat (db->dirf, &dstat) == 0)
13778 +      {
13779 +/*
13780 + * zero size: either a fresh database, or one with a single,
13781 + * unsplit data page: dirpage is all zeros.
13782 + */
13783 +         db->dirbno = (!dstat.st_size) ? 0 : -1;
13784 +         db->pagbno = -1;
13785 +         db->maxbno = dstat.st_size * BYTESIZ;
13786 +
13787 +         (void) memset (db->pagbuf, 0, PBLKSIZ);
13788 +         (void) memset (db->dirbuf, 0, DBLKSIZ);
13789 +         return db;
13790 +      }
13791 +    myfree ((char *) db);
13792 +    return (DBM *) NULL;
13793 +}
13794 +
13795 +static void sdbm_internal_close (DBM * db)
13796 +{
13797 +    if (db == NULL)
13798 +       errno = EINVAL;
13799 +    else
13800 +      {
13801 +         myfree ((char *) db);
13802 +      }
13803 +}
13804 +
13805 +datum   sdbm_fetch (SDBM * sdb, datum key)
13806 +{
13807 +    datum   retval;
13808 +    DBM    *db;
13809 +
13810 +    if (sdb == NULL || bad (key))
13811 +       return errno = EINVAL, nullitem;
13812 +
13813 +    if (!(db = sdbm_internal_open (sdb)))
13814 +       return errno = EINVAL, nullitem;
13815 +
13816 +    if (getpage (db, exhash (key)))
13817 +      {
13818 +         retval = getpair (db->pagbuf, key);
13819 +         sdbm_internal_close (db);
13820 +         return retval;
13821 +      }
13822 +
13823 +    sdbm_internal_close (db);
13824 +
13825 +    return ioerr (sdb), nullitem;
13826 +}
13827 +
13828 +int     sdbm_delete (SDBM * sdb, datum key)
13829 +{
13830 +    int     retval;
13831 +    DBM    *db;
13832 +
13833 +    if (sdb == NULL || bad (key))
13834 +       return errno = EINVAL, -1;
13835 +    if (sdbm_rdonly (sdb))
13836 +       return errno = EPERM, -1;
13837 +
13838 +    if (!(db = sdbm_internal_open (sdb)))
13839 +       return errno = EINVAL, -1;
13840 +
13841 +    if (getpage (db, exhash (key)))
13842 +      {
13843 +         if (!delpair (db->pagbuf, key))
13844 +             retval = -1;
13845 +/*
13846 + * update the page file
13847 + */
13848 +         else if (lseek (db->pagf, OFF_PAG (db->pagbno), SEEK_SET) < 0
13849 +                  || write (db->pagf, db->pagbuf, PBLKSIZ) < 0)
13850 +             retval = ioerr (sdb), -1;
13851 +         else
13852 +             retval = 0;
13853 +      }
13854 +    else
13855 +       retval = ioerr (sdb), -1;
13856 +
13857 +    sdbm_internal_close (db);
13858 +
13859 +    return retval;
13860 +}
13861 +
13862 +int     sdbm_store (SDBM * sdb, datum key, datum val, int flags)
13863 +{
13864 +    int     need;
13865 +    int     retval;
13866 +    long    hash;
13867 +    DBM    *db;
13868 +
13869 +    if (sdb == NULL || bad (key))
13870 +       return errno = EINVAL, -1;
13871 +    if (sdbm_rdonly (sdb))
13872 +       return errno = EPERM, -1;
13873 +
13874 +    need = key.dsize + val.dsize;
13875 +/*
13876 + * is the pair too big (or too small) for this database ??
13877 + */
13878 +    if (need < 0 || need > PAIRMAX)
13879 +       return errno = EINVAL, -1;
13880 +
13881 +    if (!(db = sdbm_internal_open (sdb)))
13882 +       return errno = EINVAL, -1;
13883 +
13884 +    if (getpage (db, (hash = exhash (key))))
13885 +      {
13886 +/*
13887 + * if we need to replace, delete the key/data pair
13888 + * first. If it is not there, ignore.
13889 + */
13890 +         if (flags == DBM_REPLACE)
13891 +             (void) delpair (db->pagbuf, key);
13892 +#ifdef SEEDUPS
13893 +         else if (duppair (db->pagbuf, key))
13894 +           {
13895 +               sdbm_internal_close (db);
13896 +               return 1;
13897 +           }
13898 +#endif
13899 +/*
13900 + * if we do not have enough room, we have to split.
13901 + */
13902 +         if (!fitpair (db->pagbuf, need))
13903 +             if (!makroom (db, hash, need))
13904 +               {
13905 +                   sdbm_internal_close (db);
13906 +                   return ioerr (db), -1;
13907 +               }
13908 +/*
13909 + * we have enough room or split is successful. insert the key,
13910 + * and update the page file.
13911 + */
13912 +         (void) putpair (db->pagbuf, key, val);
13913 +
13914 +         if (lseek (db->pagf, OFF_PAG (db->pagbno), SEEK_SET) < 0
13915 +             || write (db->pagf, db->pagbuf, PBLKSIZ) < 0)
13916 +           {
13917 +               sdbm_internal_close (db);
13918 +               return ioerr (db), -1;
13919 +           }
13920 +         /*
13921 +           * success
13922 +           */
13923 +         sdbm_internal_close (db);
13924 +         return 0;
13925 +      }
13926 +
13927 +    sdbm_internal_close (db);
13928 +    return ioerr (sdb), -1;
13929 +}
13930 +
13931 +/*
13932 + * the following two routines will break if
13933 + * deletions aren't taken into account. (ndbm bug)
13934 + */
13935 +datum   sdbm_firstkey (SDBM * sdb)
13936 +{
13937 +    datum   retval;
13938 +    DBM    *db;
13939 +
13940 +    if (sdb == NULL)
13941 +       return errno = EINVAL, nullitem;
13942 +
13943 +    if (!(db = sdbm_internal_open (sdb)))
13944 +       return errno = EINVAL, nullitem;
13945 +
13946 +/*
13947 + * start at page 0
13948 + */
13949 +    if (lseek (db->pagf, OFF_PAG (0), SEEK_SET) < 0
13950 +       || read (db->pagf, db->pagbuf, PBLKSIZ) < 0)
13951 +      {
13952 +         sdbm_internal_close (db);
13953 +         return ioerr (sdb), nullitem;
13954 +      }
13955 +    db->pagbno = 0;
13956 +    db->blkptr = 0;
13957 +    db->keyptr = 0;
13958 +
13959 +    retval = getnext (db);
13960 +    sdb->blkptr = db->blkptr;
13961 +    sdb->keyptr = db->keyptr;
13962 +    sdbm_internal_close (db);
13963 +    return retval;
13964 +}
13965 +
13966 +datum   sdbm_nextkey (SDBM * sdb)
13967 +{
13968 +    datum   retval;
13969 +    DBM    *db;
13970 +
13971 +    if (sdb == NULL)
13972 +       return errno = EINVAL, nullitem;
13973 +
13974 +    if (!(db = sdbm_internal_open (sdb)))
13975 +       return errno = EINVAL, nullitem;
13976 +
13977 +    retval = getnext (db);
13978 +    sdb->blkptr = db->blkptr;
13979 +    sdb->keyptr = db->keyptr;
13980 +    sdbm_internal_close (db);
13981 +    return retval;
13982 +}
13983 +
13984 +void    sdbm_close (SDBM * db)
13985 +{
13986 +    if (db == NULL)
13987 +       errno = EINVAL;
13988 +    else
13989 +      {
13990 +         (void) close (db->dirf);
13991 +         (void) close (db->pagf);
13992 +         myfree ((char *) db);
13993 +      }
13994 +}
13995 +
13996 +SDBM   *sdbm_open (char *file, int flags, int mode)
13997 +{
13998 +    SDBM   *db;
13999 +    char   *dirname;
14000 +    char   *pagname;
14001 +    int     n;
14002 +
14003 +    if (file == NULL || !*file)
14004 +       return errno = EINVAL, (SDBM *) NULL;
14005 +/*
14006 + * need space for two seperate filenames
14007 + */
14008 +    n = strlen (file) * 2 + strlen (DIRFEXT) + strlen (PAGFEXT) + 2;
14009 +
14010 +    if ((dirname = (char *) mymalloc ((unsigned) n)) == NULL)
14011 +       return errno = ENOMEM, (SDBM *) NULL;
14012 +/*
14013 + * build the file names
14014 + */
14015 +    dirname = strcat (strcpy (dirname, file), DIRFEXT);
14016 +    pagname = strcpy (dirname + strlen (dirname) + 1, file);
14017 +    pagname = strcat (pagname, PAGFEXT);
14018 +
14019 +    db = sdbm_prep (dirname, pagname, flags, mode);
14020 +    myfree ((char *) dirname);
14021 +    return db;
14022 +}
14023 +
14024 diff -Nur snapshot-20010228-orig/src/util/sdbm.h snapshot-20010228/src/util/sdbm.h
14025 --- snapshot-20010228-orig/src/util/sdbm.h      Thu Jan  1 01:00:00 1970
14026 +++ snapshot-20010228/src/util/sdbm.h   Wed Mar 21 13:32:24 2001
14027 @@ -0,0 +1,97 @@
14028 +/*++
14029 +/* NAME
14030 +/*      sdbm 3h
14031 +/* SUMMARY
14032 +/*      SDBM Simple DBM: ndbm work-alike hashed database library
14033 +/* SYNOPSIS
14034 +/*      include "sdbm.h"
14035 +/* DESCRIPTION
14036 +/* .nf
14037 +/*--*/
14038 +
14039 +#ifndef UTIL_SDBM_H
14040 +#define UTIL_SDBM_H
14041 +
14042 +/*
14043 + * sdbm - ndbm work-alike hashed database library
14044 + * based on Per-Ake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
14045 + * author: oz@nexus.yorku.ca
14046 + * status: public domain.
14047 + */
14048 +
14049 +#define DUFF    /* go ahead and use the loop-unrolled version */
14050 +
14051 +#include <stdio.h>
14052 +
14053 +#define DBLKSIZ 16384                   /* SSL cert chains require more */
14054 +#define PBLKSIZ 8192                    /* SSL cert chains require more */
14055 +#define PAIRMAX 8008                    /* arbitrary on PBLKSIZ-N */
14056 +#define SPLTMAX 10                      /* maximum allowed splits */
14057 +                                        /* for a single insertion */
14058 +#define DIRFEXT ".dir"
14059 +#define PAGFEXT ".pag"
14060 +
14061 +typedef struct {
14062 +        int dirf;                      /* directory file descriptor */
14063 +        int pagf;                      /* page file descriptor */
14064 +        int flags;                     /* status/error flags, see below */
14065 +        long blkptr;                   /* current block for nextkey */
14066 +        int keyptr;                    /* current key for nextkey */
14067 +        char pagbuf[PBLKSIZ];          /* page file block buffer */
14068 +        char dirbuf[DBLKSIZ];          /* directory file block buffer */
14069 +} SDBM;
14070 +
14071 +#define DBM_RDONLY      0x1            /* data base open read-only */
14072 +#define DBM_IOERR       0x2            /* data base I/O error */
14073 +
14074 +/*
14075 + * utility macros
14076 + */
14077 +#define sdbm_rdonly(db)         ((db)->flags & DBM_RDONLY)
14078 +#define sdbm_error(db)          ((db)->flags & DBM_IOERR)
14079 +
14080 +#define sdbm_clearerr(db)       ((db)->flags &= ~DBM_IOERR)  /* ouch */
14081 +
14082 +#define sdbm_dirfno(db) ((db)->dirf)
14083 +#define sdbm_pagfno(db) ((db)->pagf)
14084 +
14085 +typedef struct {
14086 +        char *dptr;
14087 +        int dsize;
14088 +} datum;
14089 +
14090 +extern datum nullitem;
14091 +
14092 +/*
14093 + * flags to sdbm_store
14094 + */
14095 +#define DBM_INSERT      0
14096 +#define DBM_REPLACE     1
14097 +
14098 +/*
14099 + * ndbm interface
14100 + */
14101 +extern SDBM *sdbm_open(char *, int, int);
14102 +extern void sdbm_close(SDBM *);
14103 +extern datum sdbm_fetch(SDBM *, datum);
14104 +extern int sdbm_delete(SDBM *, datum);
14105 +extern int sdbm_store(SDBM *, datum, datum, int);
14106 +extern datum sdbm_firstkey(SDBM *);
14107 +extern datum sdbm_nextkey(SDBM *);
14108 +
14109 +/*
14110 + * sdbm - ndbm work-alike hashed database library
14111 + * tuning and portability constructs [not nearly enough]
14112 + * author: oz@nexus.yorku.ca
14113 + */
14114 +
14115 +#define BYTESIZ         8
14116 +
14117 +/*
14118 + * important tuning parms (hah)
14119 + */
14120 +
14121 +#define SEEDUPS                 /* always detect duplicates */
14122 +#define BADMESS                 /* generate a message for worst case:
14123 +                                   cannot make room after SPLTMAX splits */
14124 +#endif /* UTIL_SDBM_H */
14125 diff -Nur snapshot-20010228-orig/src/util/vstream.c snapshot-20010228/src/util/vstream.c
14126 --- snapshot-20010228-orig/src/util/vstream.c   Wed Mar 21 13:26:27 2001
14127 +++ snapshot-20010228/src/util/vstream.c        Wed Mar 21 13:32:24 2001
14128 @@ -72,6 +72,9 @@
14129  /*     int     vstream_fileno(stream)
14130  /*     VSTREAM *stream;
14131  /*
14132 +/*     void    *vstream_context(stream)
14133 +/*     VSTREAM *stream;
14134 +/*
14135  /*     int     vstream_ferror(stream)
14136  /*     VSTREAM *stream;
14137  /*
14138 @@ -249,6 +252,9 @@
14139  /*     vstream_fileno() gives access to the file handle associated with
14140  /*     a buffered stream. With streams that have separate read/write
14141  /*     file descriptors, the result is the current descriptor.
14142 +/*
14143 +/*     vstream_context() returns the application context that is passed on to
14144 +/*     the application-specified read/write routines.
14145  /*
14146  /*     VSTREAM_PATH() is an unsafe macro that returns the name stored
14147  /*     with vstream_fopen() or with vstream_control(). The macro is
14148 diff -Nur snapshot-20010228-orig/src/util/vstream.h snapshot-20010228/src/util/vstream.h
14149 --- snapshot-20010228-orig/src/util/vstream.h   Wed Mar 21 13:26:27 2001
14150 +++ snapshot-20010228/src/util/vstream.h        Wed Mar 21 13:32:24 2001
14151 @@ -90,6 +90,7 @@
14152  #define VSTREAM_GETCHAR()      VSTREAM_GETC(VSTREAM_IN)
14153  
14154  #define vstream_fileno(vp)     ((vp)->fd)
14155 +#define vstream_context(vp)    ((vp)->context)
14156  #define vstream_ferror(vp)     vbuf_error(&(vp)->buf)
14157  #define vstream_feof(vp)       vbuf_eof(&(vp)->buf)
14158  #define vstream_ftimeout(vp)   vbuf_timeout(&(vp)->buf)
This page took 4.035335 seconds and 3 git commands to generate.