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
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
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
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
35 smtp_helo_timeout = 300s
37 +# The smtp_starttls_timeout parameter limits the time in seconds to write and
38 +# read operations during TLS start and stop handhake procedures.
40 +# In case of problems the client does NOT try the next address on
41 +# the mail exchanger list.
43 +# smtp_starttls_timeout = 300s
45 # The smtp_mail_timeout parameter specifies the SMTP client timeout
46 # for sending the SMTP MAIL FROM command, and for receiving the server
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
53 strict_rfc821_envelopes = no
55 +# The smtpd_starttls_timeout parameter limits the time in seconds to write and
56 +# read operations during TLS start and stop handhake procedures.
58 +# smtpd_starttls_timeout = 300s
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
67 +# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
68 +# HERE JUST SERVES AS AN EXAMPLE.
70 +# This file contains example settings of Postfix configuration
71 +# parameters that control the behaviour of the TLS extensions.
73 +# We strictly seperate between server side TLS (smtpd_) and client side
74 +# TLS (smtp_), as for practical reasons we might choose differently.
76 +# Section with SMTPD specific settings
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.
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.
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).
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'
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.
103 +# A certificate supplied here must be useable as SSL server certificate and
104 +# hence pass the "openssl verify -purpose sslserver ..." test.
106 +smtpd_tls_cert_file = /etc/postfix/server.pem
107 +smtpd_tls_key_file = $smtpd_tls_cert_file
109 +# Its DSA counterparts:
110 +smtpd_tls_dcert_file = /etc/postfix/server-dsa.pem
111 +smtpd_tls_dkey_file = $smtpd_tls_dcert_file
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.
119 +# smtpd_tls_CAfile = /etc/postfix/CAcert.pem
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!
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.
134 +# I therefore discourage the use of this option.
136 +smtpd_tls_CApath = /etc/postfix/certs
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
148 +# smtpd_tls_loglevel = 0
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.
156 +#smtpd_tls_received_header = yes
158 +# By default TLS is disabled, so no difference to plain postfix is visible.
159 +# Explicitely switch it on here:
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
169 +# smtpd_enforce_tls = no
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.
179 +# smtpd_tls_wrappermode = no
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
188 +# smtpd_tls_ask_ccert = no
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
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
201 +# smtpd_tls_req_ccert = no
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...)
208 +# smtpd_tls_ccert_verifydepth = 5
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
218 +smtpd_tls_session_cache_database = sdbm:/etc/postfix/smtpd_scache
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.
224 +# smtpd_tls_session_cache_timeout = 3600s
226 +# Two additional options has been added for relay control to the UCE rules:
227 +# permit_tls_clientcerts (a)
229 +# permit_tls_all_clientcerts. (b)
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.
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).
246 +# smtpd_recipient_restrictions = ... permit_tls_clientcerts ...
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
258 +# relay_clientcerts = hash:/etc/postfix/relay_clientcerts
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
263 +# If you don't know what to do with it, simply don't touch it and leave the
264 +# (openssl-)compiled in default!
266 +# DO NOT USE " to enclose the string, just the string!!!
268 +# smtpd_tls_cipherlist = DEFAULT
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.
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/.
284 +smtpd_tls_dh1024_param_file = /etc/postfix/dh_1024.pem
285 +smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem
287 +# The smtpd_starttls_timeout parameter limits the time in seconds to write and
288 +# read operations during TLS start and stop handhake procedures.
290 +# smtpd_starttls_timeout = 300s
292 +# Section with SMTP specific settings
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
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).
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'
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.
319 +# A certificate supplied here must be useable as SSL client certificate and
320 +# hence pass the "openssl verify -purpose sslclient ..." test.
322 +smtp_tls_cert_file = /etc/postfix/client.pem
323 +smtp_tls_key_file = $smtp_tls_cert_file
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.
331 +smtp_tls_CAfile = /etc/postfix/CAcert.pem
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!
340 +# To use this option in chroot mode, this directory itself or a copy of it
341 +# must be inside the chroot jail.
343 +smtp_tls_CApath = /etc/postfix/certs
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
355 +smtp_tls_loglevel = 0
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
365 +smtp_tls_session_cache_database = sdbm:/etc/postfix/smtp_scache
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.
371 +# smtp_tls_session_cache_timeout = 3600s
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
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 :-)
388 +# In case of failure, a "4xx" code is issued and the mail stays in the queue.
390 +# Explicitely switch it on here, if you want it.
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
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.
409 +# smtp_enforce_tls = no
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.
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).
424 +# smtp_tls_enforce_peername = yes
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
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).
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.
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).
455 +# important.host MUST
456 +# some.host.dom.ain MUST_NOPEERMATCH
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.
462 +smtp_tls_per_site = hash:/etc/postfix/tls_per_site
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...)
469 +# smtp_tls_scert_verifydepth = 5
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.
475 +# If activated and TLS is not already enabled for this host, a line is added
477 +# postfix/smtp[pid]: Host offered STARTTLS: [name.of.host]
479 +smtp_tls_note_starttls_offer = yes
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
484 +# If you don't know what to do with it, simply don't touch it and leave the
485 +# (openssl-)compiled in default!
487 +# DO NOT USE " to enclose the string, just the string!!!
489 +# smtp_tls_cipherlist = DEFAULT
491 +# The smtp_starttls_timeout parameter limits the time in seconds to write and
492 +# read operations during TLS start and stop handhake procedures.
494 +# In case of problems the client does NOT try the next address on
495 +# the mail exchanger list.
497 +# smtp_starttls_timeout = 300s
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.
507 +# tls_random_exchange_name = /etc/postfix/prng_exch
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.
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.
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
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.
534 +# tls_random_upd_period = 60s
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.
546 +# tls_daemon_random_source = dev:/dev/urandom
547 +tls_daemon_random_source = egd:/var/run/egd-pool
548 +# tls_daemon_random_bytes = 32
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
554 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
557 +<meta name="generator" content="HTML Tidy, see www.w3.org">
558 +<title>Postfix/TLS - Configuring main.cf and master.cf</title>
561 +<h1>Postfix/TLS - Configuring main.cf and master.cf</h1>
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.
566 +<h2>main.cf: smtpd (server) specific variables</h2>
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.
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.
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).
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'
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.
594 +# A certificate supplied here must be useable as SSL server certificate and
595 +# hence pass the "openssl verify -purpose sslserver ..." test.
597 +smtpd_tls_cert_file = /etc/postfix/server.pem
598 +smtpd_tls_key_file = $smtpd_tls_cert_file
600 +# Its DSA counterparts:
601 +smtpd_tls_dcert_file = /etc/postfix/server-dsa.pem
602 +smtpd_tls_dkey_file = $smtpd_tls_dcert_file
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.
610 +# smtpd_tls_CAfile = /etc/postfix/CAcert.pem
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!
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.
625 +# I therefore discourage the use of this option.
627 +smtpd_tls_CApath = /etc/postfix/certs
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
639 +# smtpd_tls_loglevel = 0
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.
647 +#smtpd_tls_received_header = yes
649 +# By default TLS is disabled, so no difference to plain postfix is visible.
650 +# Explicitely switch it on here:
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
660 +# smtpd_enforce_tls = no
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.
670 +# smtpd_tls_wrappermode = no
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
679 +# smtpd_tls_ask_ccert = no
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
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
692 +# smtpd_tls_req_ccert = no
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...)
699 +# smtpd_tls_ccert_verifydepth = 5
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
709 +smtpd_tls_session_cache_database = sdbm:/etc/postfix/smtpd_scache
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.
715 +# smtpd_tls_session_cache_timeout = 3600s
717 +# Two additional options has been added for relay control to the UCE rules:
718 +# permit_tls_clientcerts (a)
720 +# permit_tls_all_clientcerts. (b)
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.
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).
737 +# smtpd_recipient_restrictions = ... permit_tls_clientcerts ...
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
749 +# relay_clientcerts = hash:/etc/postfix/relay_clientcerts
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
754 +# If you don't know what to do with it, simply don't touch it and leave the
755 +# (openssl-)compiled in default!
757 +# DO NOT USE " to enclose the string, just the string!!!
759 +# smtpd_tls_cipherlist = DEFAULT
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.
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/.
775 +smtpd_tls_dh1024_param_file = /etc/postfix/dh_1024.pem
776 +smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem
778 +# The smtpd_starttls_timeout parameter limits the time in seconds to write and
779 +# read operations during TLS start and stop handhake procedures.
781 +# smtpd_starttls_timeout = 300s
784 +<h2>main.cf: smtp (client) specific variables</h2>
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
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).
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'
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.
812 +# A certificate supplied here must be useable as SSL client certificate and
813 +# hence pass the "openssl verify -purpose sslclient ..." test.
815 +smtp_tls_cert_file = /etc/postfix/client.pem
816 +smtp_tls_key_file = $smtp_tls_cert_file
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.
824 +smtp_tls_CAfile = /etc/postfix/CAcert.pem
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!
833 +# To use this option in chroot mode, this directory itself or a copy of it
834 +# must be inside the chroot jail.
836 +smtp_tls_CApath = /etc/postfix/certs
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
848 +smtp_tls_loglevel = 0
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
858 +smtp_tls_session_cache_database = sdbm:/etc/postfix/smtp_scache
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.
864 +# smtp_tls_session_cache_timeout = 3600s
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
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 :-)
881 +# In case of failure, a "4xx" code is issued and the mail stays in the queue.
883 +# Explicitely switch it on here, if you want it.
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
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.
902 +# smtp_enforce_tls = no
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.
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).
917 +# smtp_tls_enforce_peername = yes
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
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).
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.
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).
948 +# important.host MUST
949 +# some.host.dom.ain MUST_NOPEERMATCH
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.
955 +smtp_tls_per_site = hash:/etc/postfix/tls_per_site
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...)
962 +# smtp_tls_scert_verifydepth = 5
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.
968 +# If activated and TLS is not already enabled for this host, a line is added
970 +# postfix/smtp[pid]: Host offered STARTTLS: [name.of.host]
972 +smtp_tls_note_starttls_offer = yes
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
977 +# If you don't know what to do with it, simply don't touch it and leave the
978 +# (openssl-)compiled in default!
980 +# DO NOT USE " to enclose the string, just the string!!!
982 +# smtp_tls_cipherlist = DEFAULT
984 +# The smtp_starttls_timeout parameter limits the time in seconds to write and
985 +# read operations during TLS start and stop handhake procedures.
987 +# In case of problems the client does NOT try the next address on
988 +# the mail exchanger list.
990 +# smtp_starttls_timeout = 300s
993 +<h2>main.cf: general variables</h2>
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.
1004 +# tls_random_exchange_name = /etc/postfix/prng_exch
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.
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.
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
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.
1031 +# tls_random_upd_period = 60s
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.
1043 +# tls_daemon_random_source = dev:/dev/urandom
1044 +tls_daemon_random_source = egd:/var/run/egd-pool
1045 +# tls_daemon_random_bytes = 32
1048 +<h2>master.cf: tlsmgr daemon</h2>
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.
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
1064 +<h2>master.cf: additional services</h2>
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).
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>
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
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
1095 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1098 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1099 +<title>Postfix/TLS - A TLS extension for POSTFIX</title>
1102 +<h1>Postfix/TLS - A TLS extension for POSTFIX</h1>
1107 +<li><a href="intro.html">Introduction</a></li>
1109 +<li><a href="install.html">Installating the patchkit</a></li>
1111 +<li><a href="setup.html">Setting up the certificates</a></li>
1113 +<li><a href="conf.html">Configuring main.cf</a></li>
1115 +<li><a href="security.html">Security considerations</a></li>
1117 +<li><a href="test.html">Testing</a></li>
1119 +<li><a href="prng.html">PRNG - Pseudo Random Number
1122 +<li><a href="references.html">References</a></li>
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.
1138 +Lutz Jä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>
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
1149 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1152 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1153 +<title>Postfix/TLS - Installation</title>
1156 +<h1>Postfix/TLS - Installing the patchkit</h1>
1158 +<h2>Prerequisits</h2>
1160 +This patchkit is prepared for
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>
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
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.
1182 +You may also need to update your "patch" utility (see below).
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.
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>
1197 +patch -p0 < path-to/pfixtls.diff
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.
1204 +<p>If you need to apply the patchkit to a different version of
1205 +patchlevel of postfix, you might try the following:</p>
1208 +cd postfix-directory ; patch -p1 < path-to/pfixtls.diff
1211 +Since the patch is in unified form, it might also apply to a mildly
1212 +changed source, as long as no conflicts appear.
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
1223 +make makefiles CCARGS="-DHAS_SSL -I/usr/local/ssl/include" AUXLIBS="-L/usr/local/ssl/lib -lssl -lcrypto"
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:
1234 +and then follow the instructions in the postfix INSTALL file.
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
1243 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1246 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1247 +<title>Postfix/TLS - Introduction</title>
1250 +<h1>Postfix/TLS - Introduction</h1>
1252 +Postfix/TLS is an extension of the Postfix [<a href=
1253 +"references.html#postfix">POSTFIX</a>] MTA software to support the
1256 +<h2>A note about the start of the project</h2>
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.
1262 +<h2>RFC2246: The TLS (former SSL) protocol</h2>
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.
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>
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
1290 +<h2>RFC2487: Introducing TLS to SMTP</h2>
1292 +The integration of the TLS protocol to Internet mail, SMTP (Simple
1293 +Mail Transport Protocol) is described in <a href="rfc2487.txt">
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>
1306 +<h2>Postfix/TLS: what can it do for you</h2>
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
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>
1321 +<li>Authentication of the receiving host to prevent
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>
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
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
1353 +<li>Any more ideas???<br>
1354 +Status: Send me an email.</li>
1357 +<h2>Postfix/TLS: what it cannot do for you</h2>
1359 +There is one thing that I explicitly want to point out:
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
1369 +<li>all of the mailhubs in between are enforcing TLS.</li>
1371 +<li>all mailhubs themselves are trustworthy, as the email is only
1372 +encrypted during transport, not when queued or spooled.</li>
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>
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
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>
1394 +<h2>Other OpenSource packages</h2>
1396 +As of version sendmail-8.11, sendmail includes RFC2487 support [<a
1397 +href="references.html#sendmail">SENDMAIL</a>].
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>
1403 +<p>Matti Aarnio has integrated RFC2487 into ZMailer [<a href=
1404 +"references.html#zmailer">ZMAILER</a>].</p>
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>
1410 +<p>Trey Childs is also working on a "wrapper" solution [<a href=
1411 +"references.html#smtps">SMTPS</a>].</p>
1413 +<h2>Commercial implementations</h2>
1415 +The commercial version of sendmail includes RFC2487 support [<a
1416 +href="references.html#sendmail.inc">SENDMAIL.INC</a>].
1418 +<p>Netscape Enterprise Server and Microsoft Exchange Server do offer
1419 +RFC2487 functionality.</p>
1421 +<p>The CommunigatePro mailserver software also supports RFC2487
1422 +[<a href="references.html#communigate">COMMUNIGATE</a>].</p>
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
1431 +#!/usr/local/bin/perl -T
1437 +my $cert_dir = "/usr/local/ssl/certs";
1438 +my $cert_file = "CAcert.pem";
1440 +my $query = new CGI;
1442 +my $kind = $query->param('FORMAT');
1443 +if($kind eq 'DER') { $cert_file = "CAcert.der"; }
1445 +my $cert_path = "$cert_dir/$cert_file";
1447 +open(CERT, "<$cert_path");
1448 +my $data = join '', <CERT>;
1450 +print "Content-Type: application/x-x509-ca-cert\n";
1451 +print "Content-Length: ", length($data), "\n\n$data";
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
1458 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1461 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1462 +<title>Postfix/TLS - Being your on CA</title>
1465 +<h1>Postfix/TLS - Lutz's very short course on being your own
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.
1475 +<h2>Be your own CA</h2>
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).
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>
1492 +<p>Using OpenSSL it is quite simple to become your own CA. Just
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.
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>
1516 +<h2>Create your site certificate</h2>
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.
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>
1529 +*** CA.pl Wed Mar 24 10:30:38 1999
1530 +--- CA1.pl Sat Mar 27 19:36:47 1999
1534 + } elsif (/^-newcert$/) {
1535 + # create a certificate
1536 +! system ("$REQ -new -x509 -keyout newreq.pem -out newreq.pem $DAYS");
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");
1543 + print "Request (and private key) is in newreq.pem\n";
1544 + } elsif (/^-newca$/) {
1547 + } elsif (/^-newcert$/) {
1548 + # create a certificate
1549 +! system ("$REQ -new -x509 -nodes -keyout newreq.pem -out newreq.pem $DAYS");
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");
1556 + print "Request (and private key) is in newreq.pem\n";
1557 + } elsif (/^-newca$/) {
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
1568 +and then sign it with your CA:
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
1585 +chown root /etc/postfix/key.pem ; chmod 400 /etc/postfix/key.pem
1588 +<h2>Create a client certificate</h2>
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:
1600 +If you want to do client certificate based relaying, you do need
1601 +the fingerprint of the certificate, which can be obtained with
1604 +openssl x509 -fingerprint -in newcert.pem
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:
1614 +pkcs12 -export -in newcert.pem -inkey newreq.pem \
1615 + -certfile /usr/local/ssl/CAcert.pem -name "Name" -out newcert.p12
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>
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
1637 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1640 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1641 +<title>Postfix/TLS - PRNG Pseudo Random Number Generator</title>
1644 +<h1>Postfix/TLS - PRNG Pseudo Random Number Generator</h1>
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.
1652 +<h2>Included PRNG</h2>
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
1662 +<h2>Obtaining Entropy</h2>
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".
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>
1675 +<h2>External sources</h2>
1677 +Only few operating systems provide good entropy collection.
1679 +<h3>/dev/random and /dev/urandom</h3>
1681 +Linux offers the <tt>/dev/random</tt> and <tt>/dev/urandom</tt>
1682 +devices, some BSD derivatives as well.
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>
1695 +<h3>Entropy Gathering Daemon</h3>
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
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>
1708 +<p>EGD should hence not be used for direct feeding of smtp[d]
1709 +processes. Again, imagine 50 smtp processes starting delivery at
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>
1717 +<h3>Intermediate File</h3>
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.
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.
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
1738 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1741 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1742 +<title>Postfix/TLS - References</title>
1745 +<h1>Postfix/TLS - References</h1>
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>
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>
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>
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>
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>
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>
1773 +<li>[<a name="imcorg">IMC</a>] Internet Mail Consortium: <a href=
1774 +"http://www.imc.org/">http://www.imc.org/</a>.</li>
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>
1780 +<li>[<a name="openca">OPENCA</a>] The OpenCA Project: <a href=
1781 +"http://www.openca.org/">http://www.openca.org/</a>.</li>
1783 +<li>[<a name="dfncert">DFNCERT</a>] DFN-CERT: <a href=
1784 +"http://www.cert.dfn.de/">http://www.cert.dfn.de/</a>.</li>
1786 +<li>[<a name="sendmail">SENDMAIL</a>] Sendmail: <a href=
1787 +"http://www.sendmail.org/">http://www.sendmail.org/</a>.</li>
1789 +<li>[<a name="sendmail.inc">SENDMAIL.INC</a>] Sendmail Inc: <a
1790 +href="http://www.sendmail.com/">http://www.sendmail.com/</a>.</li>
1792 +<li>[<a name="qmail">QMAIL</a>] Qmail: <a href=
1793 +"http://www.qmail.org/">http://www.qmail.org/</a>.</li>
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>
1799 +<li>[<a name="zmailer">ZMAILER</a>] ZMailer: <a href=
1800 +"http://www.zmailer.org/">http://www.zmailer.org/</a>.</li>
1802 +<li>[<a name="jonama">JONAMA</a>] Jonama: <a href=
1803 +"http://www.multimania.com/jonama/">
1804 +http://www.multimania.com/jonama/</a>.</li>
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>
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>
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>
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>
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>
1826 +<li>[<a name="prngd">PRNGD</a>] Pseudo Random Number Generator
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>
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>
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
1843 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1846 +<meta name="generator" content="HTML Tidy, see www.w3.org">
1847 +<title>Postfix/TLS - Initial Motivation</title>
1850 +<h1>Postfix/TLS - Initial Motivation</h1>
1852 +This introduction shall point out the motivation, why I spend my
1853 +time writing this TLS extension for postfix.
1855 +<h2>Roaming users problem</h2>
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.
1864 +<h2>UCE control</h2>
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.
1874 +<h2>Passwords and insecure networks</h2>
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.
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>
1890 +<h2>Encryption via SSL</h2>
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>].
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
1903 +<h2>Netscape 4.5</h2>
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>].
1915 +<h2>RFC 2487 - SMTP Service Extension for Secure SMTP over TLS</h2>
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.
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>
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.
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>
1947 +<h2>Postfix/TLS</h2>
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
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.
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
1977 +Network Working Group T. Dierks
1978 +Request for Comments: 2246 Certicom
1979 +Category: Standards Track C. Allen
1987 +Status of this Memo
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.
1997 + Copyright (C) The Internet Society (1999). All Rights Reserved.
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.
2011 + 3. Goals of this document 5
2012 + 4. Presentation language 5
2013 + 4.1. Basic block size 6
2014 + 4.2. Miscellaneous 6
2017 + 4.5. Enumerateds 7
2018 + 4.6. Constructed types 8
2020 + 4.7. Cryptographic attributes 10
2022 + 5. HMAC and the pseudorandom function 11
2023 + 6. The TLS Record Protocol 13
2024 + 6.1. Connection states 14
2028 +Dierks & Allen Standards Track [Page 1]
2030 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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
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
2080 + C. CipherSuite definitions 61
2084 +Dierks & Allen Standards Track [Page 2]
2086 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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
2114 + Full Copyright Statement 80
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
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.
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
2140 +Dierks & Allen Standards Track [Page 3]
2142 +RFC 2246 The TLS Protocol Version 1.0 January 1999
2145 + this mode while another protocol is using the Record Protocol as
2146 + a transport for negotiating security parameters.
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:
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.
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.
2166 + - The negotiation is reliable: no attacker can modify the
2167 + negotiation communication without being detected by the parties
2168 + to the communication.
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.
2180 + The goals of TLS Protocol, in order of their priority, are:
2182 + 1. Cryptographic security: TLS should be used to establish a secure
2183 + connection between two parties.
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.
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
2196 +Dierks & Allen Standards Track [Page 4]
2198 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
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.
2212 +3. Goals of this document
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.
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
2232 +4. Presentation language
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.
2252 +Dierks & Allen Standards Track [Page 5]
2254 +RFC 2246 The TLS Protocol Version 1.0 January 1999
2257 +4.1. Basic block size
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:
2265 + value = (byte[0] << 8*(n-1)) | (byte[1] << 8*(n-2)) |
2268 + This byte ordering for multi-byte values is the commonplace network
2269 + byte order or big endian format.
2273 + Comments begin with "/*" and end with "*/".
2275 + Optional components are denoted by enclosing them in "[[ ]]" double
2278 + Single byte entities containing uninterpreted data are of type
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
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
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.
2300 + opaque Datum[3]; /* three uninterpreted bytes */
2301 + Datum Data[9]; /* 3 consecutive 3 byte vectors */
2308 +Dierks & Allen Standards Track [Page 6]
2310 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
2321 + T T'<floor..ceiling>;
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).
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 */
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.
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.
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
2364 +Dierks & Allen Standards Track [Page 7]
2366 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
2373 + enum { e1(v1), e2(v2), ... , en(vn) [[, (n)]] } Te;
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.
2379 + enum { red(3), blue(5), white(7) } Color;
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.
2386 + enum { sweet(1), sour(2), bitter(4), (32000) } Taste;
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
2394 + Color color = Color.blue; /* overspecified, legal */
2395 + Color color = blue; /* correct, type implicit */
2397 + For enumerateds that are never converted to external representation,
2398 + the numerical information may be omitted.
2400 + enum { low, medium, high } Amount;
2402 +4.6. Constructed types
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.
2420 +Dierks & Allen Standards Track [Page 8]
2422 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
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.
2455 + enum { apple, orange } VariantTag;
2458 + opaque string<0..10>; /* variable length */
2462 + opaque string[10]; /* fixed length */
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 */
2471 + Variant structures may be qualified (narrowed) by specifying a value
2472 + for the selector prior to the type. For example, a
2476 +Dierks & Allen Standards Track [Page 9]
2478 +RFC 2246 The TLS Protocol Version 1.0 January 1999
2481 + orange VariantRecord
2483 + is a narrowed type of a VariantRecord containing a variant_body of
2486 +4.7. Cryptographic attributes
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).
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.
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].
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:
2510 + Dss-Sig-Value ::= SEQUENCE {
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.
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.
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.
2532 +Dierks & Allen Standards Track [Page 10]
2534 +RFC 2246 The TLS Protocol Version 1.0 January 1999
2537 + An RSA encrypted value is encoded with PKCS #1 block type 2 as
2538 + described in [PKCS1].
2540 + In the following example:
2542 + stream-ciphered struct {
2545 + digitally-signed opaque hash[20];
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.
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.
2571 + Example1 ex1 = {1, 4}; /* assigns f1 = 1, f2 = 4 */
2573 +5. HMAC and the pseudorandom function
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].
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,
2588 +Dierks & Allen Standards Track [Page 11]
2590 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
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.
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.
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:
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) + ...
2614 + Where + indicates concatenation.
2616 + A() is defined as:
2618 + A(i) = HMAC_hash(secret, A(i-1))
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
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.
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
2639 + L_S = length in bytes of secret;
2640 + L_S1 = L_S2 = ceil(L_S / 2);
2644 +Dierks & Allen Standards Track [Page 12]
2646 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
2653 + The PRF is then defined as the result of mixing the two pseudorandom
2654 + streams by exclusive-or'ing them together.
2656 + PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
2657 + P_SHA-1(S2, label + seed);
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
2664 + 73 6C 69 74 68 79 20 74 6F 76 65 73
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).
2671 +6. The TLS Record Protocol
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.
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.
2700 +Dierks & Allen Standards Track [Page 13]
2702 +RFC 2246 The TLS Protocol Version 1.0 January 1999
2705 +6.1. Connection states
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.
2724 + The security parameters for a TLS Connection read and write state are
2725 + set by providing the following values:
2728 + Whether this entity is considered the "client" or the "server" in
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
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.
2743 + compression algorithm
2744 + An algorithm to be used for data compression. This specification
2745 + must include all information the algorithm requires to do
2749 + A 48 byte secret shared between the two peers in the connection.
2752 + A 32 byte value provided by the client.
2756 +Dierks & Allen Standards Track [Page 14]
2758 +RFC 2246 The TLS Protocol Version 1.0 January 1999
2762 + A 32 byte value provided by the server.
2764 + These parameters are defined in the presentation language as:
2766 + enum { server, client } ConnectionEnd;
2768 + enum { null, rc4, rc2, des, 3des, des40 } BulkCipherAlgorithm;
2770 + enum { stream, block } CipherType;
2772 + enum { true, false } IsExportable;
2774 + enum { null, md5, sha } MACAlgorithm;
2776 + enum { null(0), (255) } CompressionMethod;
2778 + /* The algorithms specified in CompressionMethod,
2779 + BulkCipherAlgorithm, and MACAlgorithm may be added to. */
2782 + ConnectionEnd entity;
2783 + BulkCipherAlgorithm bulk_cipher_algorithm;
2784 + CipherType cipher_type;
2786 + uint8 key_material_length;
2787 + IsExportable is_exportable;
2788 + MACAlgorithm mac_algorithm;
2790 + CompressionMethod compression_algorithm;
2791 + opaque master_secret[48];
2792 + opaque client_random[32];
2793 + opaque server_random[32];
2794 + } SecurityParameters;
2796 + The record layer will use the security parameters to generate the
2797 + following six items:
2799 + client write MAC secret
2800 + server write MAC secret
2803 + client write IV (for block ciphers only)
2804 + server write IV (for block ciphers only)
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.
2812 +Dierks & Allen Standards Track [Page 15]
2814 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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
2824 + The current state of the compression algorithm.
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.
2837 + The MAC secret for this connection as generated above.
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.
2850 + The TLS Record Layer receives uninterpreted data from higher layers
2851 + in non-empty blocks of arbitrary size.
2853 +6.2.1. Fragmentation
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).
2863 + uint8 major, minor;
2864 + } ProtocolVersion;
2868 +Dierks & Allen Standards Track [Page 16]
2870 +RFC 2246 The TLS Protocol Version 1.0 January 1999
2874 + change_cipher_spec(20), alert(21), handshake(22),
2875 + application_data(23), (255)
2880 + ProtocolVersion version;
2882 + opaque fragment[TLSPlaintext.length];
2886 + The higher level protocol used to process the enclosed fragment.
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).
2896 + The length (in bytes) of the following TLSPlaintext.fragment.
2897 + The length should not exceed 2^14.
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.
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.
2908 +6.2.2. Record compression and decompression
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.
2924 +Dierks & Allen Standards Track [Page 17]
2926 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
2935 + ContentType type; /* same as TLSPlaintext.type */
2936 + ProtocolVersion version;/* same as TLSPlaintext.version */
2938 + opaque fragment[TLSCompressed.length];
2942 + The length (in bytes) of the following TLSCompressed.fragment.
2943 + The length should not exceed 2^14 + 1024.
2946 + The compressed form of TLSPlaintext.fragment.
2948 + Note: A CompressionMethod.null operation is an identity operation; no
2949 + fields are altered.
2951 + Implementation note:
2952 + Decompression functions are responsible for ensuring that
2953 + messages cannot cause internal buffer overflows.
2955 +6.2.3. Record payload protection
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.
2964 + ProtocolVersion version;
2966 + select (CipherSpec.cipher_type) {
2967 + case stream: GenericStreamCipher;
2968 + case block: GenericBlockCipher;
2973 + The type field is identical to TLSCompressed.type.
2976 + The version field is identical to TLSCompressed.version.
2980 +Dierks & Allen Standards Track [Page 18]
2982 +RFC 2246 The TLS Protocol Version 1.0 January 1999
2986 + The length (in bytes) of the following TLSCiphertext.fragment.
2987 + The length may not exceed 2^14 + 2048.
2990 + The encrypted form of TLSCompressed.fragment, with the MAC.
2992 +6.2.3.1. Null or standard stream cipher
2994 + Stream ciphers (including BulkCipherAlgorithm.null - see Appendix
2995 + A.6) convert TLSCompressed.fragment structures to and from stream
2996 + TLSCiphertext.fragment structures.
2998 + stream-ciphered struct {
2999 + opaque content[TLSCompressed.length];
3000 + opaque MAC[CipherSpec.hash_size];
3001 + } GenericStreamCipher;
3003 + The MAC is generated as:
3005 + HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
3006 + TLSCompressed.version + TLSCompressed.length +
3007 + TLSCompressed.fragment));
3009 + where "+" denotes concatenation.
3012 + The sequence number for this record.
3015 + The hashing algorithm specified by
3016 + SecurityParameters.mac_algorithm.
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.
3028 +6.2.3.2. CBC block cipher
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.
3036 +Dierks & Allen Standards Track [Page 19]
3038 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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;
3048 + The MAC is generated as described in Section 6.2.3.1.
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.
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.
3067 + The encrypted data length (TLSCiphertext.length) is one more than the
3068 + sum of TLSCompressed.length, CipherSpec.hash_size, and
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.
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.
3092 +Dierks & Allen Standards Track [Page 20]
3094 +RFC 2246 The TLS Protocol Version 1.0 January 1999
3097 +6.3. Key calculation
3099 + The Record Protocol requires an algorithm to generate keys, IVs, and
3100 + MAC secrets from the security parameters provided by the handshake
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
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.
3115 + To generate the key material, compute
3117 + key_block = PRF(SecurityParameters.master_secret,
3119 + SecurityParameters.server_random +
3120 + SecurityParameters.client_random);
3122 + until enough output has been generated. Then the key_block is
3123 + partitioned as follows:
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]
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.
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.
3148 +Dierks & Allen Standards Track [Page 21]
3150 +RFC 2246 The TLS Protocol Version 1.0 January 1999
3153 + Exportable encryption algorithms (for which CipherSpec.is_exportable
3154 + is true) require additional processing as follows to derive their
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);
3168 + Exportable encryption algorithms derive their IVs solely from the
3169 + random values from the hello messages:
3171 + iv_block = PRF("", "IV block", SecurityParameters.client_random +
3172 + SecurityParameters.server_random);
3174 + The iv_block is partitioned into two initialization vectors as the
3175 + key_block was above:
3177 + client_write_IV[SecurityParameters.IV_size]
3178 + server_write_IV[SecurityParameters.IV_size]
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.
3184 +6.3.1. Export key generation example
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.
3192 + key_block = PRF(master_secret,
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]
3204 +Dierks & Allen Standards Track [Page 22]
3206 +RFC 2246 The TLS Protocol Version 1.0 January 1999
3209 + final_client_write_key = PRF(client_write_key,
3210 + "client write key",
3212 + server_random)[0..15]
3213 + final_server_write_key = PRF(server_write_key,
3214 + "server write key",
3216 + server_random)[0..15]
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]
3223 +7. The TLS Handshake Protocol
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.
3230 + The Handshake Protocol is responsible for negotiating a session,
3231 + which consists of the following items:
3233 + session identifier
3234 + An arbitrary byte sequence chosen by the server to identify an
3235 + active or resumable session state.
3238 + X509v3 [X509] certificate of the peer. This element of the state
3241 + compression method
3242 + The algorithm used to compress data prior to encryption.
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)
3251 + 48-byte secret shared between the client and server.
3254 + A flag indicating whether the session can be used to initiate new
3260 +Dierks & Allen Standards Track [Page 23]
3262 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
3270 +7.1. Change cipher spec protocol
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.
3278 + enum { change_cipher_spec(1), (255) } type;
3279 + } ChangeCipherSpec;
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
3293 +7.2. Alert protocol
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.
3305 + enum { warning(1), fatal(2), (255) } AlertLevel;
3309 + unexpected_message(10),
3310 + bad_record_mac(20),
3311 + decryption_failed(21),
3312 + record_overflow(22),
3316 +Dierks & Allen Standards Track [Page 24]
3318 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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),
3330 + access_denied(49),
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),
3340 + } AlertDescription;
3344 + AlertDescription description;
3347 +7.2.1. Closure alerts
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.
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.
3359 + Either party may initiate a close by sending a close_notify alert.
3360 + Any data received after a closure alert is ignored.
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.
3372 +Dierks & Allen Standards Track [Page 25]
3374 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
3389 + NB: It is assumed that closing a connection reliably delivers
3390 + pending data before destroying the transport.
3392 +7.2.2. Error alerts
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
3402 + unexpected_message
3403 + An inappropriate message was received. This alert is always fatal
3404 + and should never be observed in communication between proper
3408 + This alert is returned if a record is received with an incorrect
3409 + MAC. This message is always fatal.
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.
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.
3421 + decompression_failure
3422 + The decompression function received improper input (e.g. data
3423 + that would expand to excessive length). This message is always
3428 +Dierks & Allen Standards Track [Page 26]
3430 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
3439 + A certificate was corrupt, contained signatures that did not
3440 + verify correctly, etc.
3442 + unsupported_certificate
3443 + A certificate was of an unsupported type.
3445 + certificate_revoked
3446 + A certificate was revoked by its signer.
3448 + certificate_expired
3449 + A certificate has expired or is not currently valid.
3451 + certificate_unknown
3452 + Some other (unspecified) issue arose in processing the
3453 + certificate, rendering it unacceptable.
3456 + A field in the handshake was out of range or inconsistent with
3457 + other fields. This is always fatal.
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.
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.
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.
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.
3484 +Dierks & Allen Standards Track [Page 27]
3486 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
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
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
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.
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.
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.
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
3540 +Dierks & Allen Standards Track [Page 28]
3542 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
3549 +7.3. Handshake Protocol overview
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.
3558 + The TLS Handshake Protocol involves the following steps:
3560 + - Exchange hello messages to agree on algorithms, exchange random
3561 + values, and check for session resumption.
3563 + - Exchange the necessary cryptographic parameters to allow the
3564 + client and server to agree on a premaster secret.
3566 + - Exchange certificates and cryptographic information to allow the
3567 + client and server to authenticate themselves.
3569 + - Generate a master secret from the premaster secret and exchanged
3572 + - Provide security parameters to the record layer.
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.
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.
3596 +Dierks & Allen Standards Track [Page 29]
3598 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
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.
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
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.
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
3652 +Dierks & Allen Standards Track [Page 30]
3654 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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
3663 + ClientHello -------->
3666 + ServerKeyExchange*
3667 + CertificateRequest*
3668 + <-------- ServerHelloDone
3671 + CertificateVerify*
3672 + [ChangeCipherSpec]
3673 + Finished -------->
3674 + [ChangeCipherSpec]
3675 + <-------- Finished
3676 + Application Data <-------> Application Data
3678 + Fig. 1 - Message flow for a full handshake
3680 + * Indicates optional or situation-dependent messages that are not
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.
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:
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.
3708 +Dierks & Allen Standards Track [Page 31]
3710 +RFC 2246 The TLS Protocol Version 1.0 January 1999
3715 + ClientHello -------->
3717 + [ChangeCipherSpec]
3718 + <-------- Finished
3719 + [ChangeCipherSpec]
3720 + Finished -------->
3721 + Application Data <-------> Application Data
3723 + Fig. 2 - Message flow for an abbreviated handshake
3725 + The contents and significance of each message will be presented in
3726 + detail in the following sections.
3728 +7.4. Handshake protocol
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.
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)
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;
3764 +Dierks & Allen Standards Track [Page 32]
3766 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
3779 +7.4.1. Hello messages
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.
3787 +7.4.1.1. Hello request
3789 + When this message will be sent:
3790 + The hello request message may be sent by the server at any time.
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.
3806 + After sending a hello request, servers should not repeat the request
3807 + until the subsequent handshake negotiation is complete.
3809 + Structure of this message:
3810 + struct { } HelloRequest;
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.
3820 +Dierks & Allen Standards Track [Page 33]
3822 +RFC 2246 The TLS Protocol Version 1.0 January 1999
3825 +7.4.1.2. Client hello
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.
3834 + Structure of this message:
3835 + The client hello message includes a random structure, which is
3836 + used later in the protocol.
3839 + uint32 gmt_unix_time;
3840 + opaque random_bytes[28];
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.
3851 + 28 bytes generated by a secure random number generator.
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
3869 + opaque SessionID<0..32>;
3876 +Dierks & Allen Standards Track [Page 34]
3878 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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
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.
3899 + uint8 CipherSuite[2]; /* Cryptographic suite selector */
3901 + The client hello includes a list of compression algorithms supported
3902 + by the client, ordered according to the client's preference.
3904 + enum { null(0), (255) } CompressionMethod;
3907 + ProtocolVersion client_version;
3909 + SessionID session_id;
3910 + CipherSuite cipher_suites<2..2^16-1>;
3911 + CompressionMethod compression_methods<1..2^8-1>;
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).
3922 + A client-generated random structure.
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.
3932 +Dierks & Allen Standards Track [Page 35]
3934 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
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.
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.
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
3966 +7.4.1.3. Server hello
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
3974 + Structure of this message:
3976 + ProtocolVersion server_version;
3978 + SessionID session_id;
3979 + CipherSuite cipher_suite;
3980 + CompressionMethod compression_method;
3988 +Dierks & Allen Standards Track [Page 36]
3990 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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).
4000 + This structure is generated by the server and must be different
4001 + from (and independent of) ClientHello.random.
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.
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.
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.
4028 +7.4.2. Server certificate
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.
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
4044 +Dierks & Allen Standards Track [Page 37]
4046 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
4053 + Key Exchange Algorithm Certificate Key Type
4055 + RSA RSA public key; the certificate must
4056 + allow the key to be used for encryption.
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
4064 + DHE_DSS DSS public key.
4066 + DHE_DSS_EXPORT DSS public key.
4068 + DHE_RSA RSA public key which can be used for
4071 + DHE_RSA_EXPORT RSA public key which can be used for
4074 + DH_DSS Diffie-Hellman key. The algorithm used
4075 + to sign the certificate should be DSS.
4077 + DH_RSA Diffie-Hellman key. The algorithm used
4078 + to sign the certificate should be RSA.
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.
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.
4091 + Structure of this message:
4092 + opaque ASN.1Cert<1..2^24-1>;
4095 + ASN.1Cert certificate_list<0..2^24-1>;
4100 +Dierks & Allen Standards Track [Page 38]
4102 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
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.
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.
4125 +7.4.3. Server key exchange message
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).
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:
4137 + RSA_EXPORT (if the public key in the server certificate is
4138 + longer than 512 bits)
4145 + It is not legal to send the server key exchange message for the
4146 + following key exchange methods:
4149 + RSA_EXPORT (when the public key in the server certificate is
4150 + less than or equal to 512 bits in length)
4156 +Dierks & Allen Standards Track [Page 39]
4158 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.)
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.
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.
4180 + Structure of this message:
4181 + enum { rsa, diffie_hellman } KeyExchangeAlgorithm;
4184 + opaque rsa_modulus<1..2^16-1>;
4185 + opaque rsa_exponent<1..2^16-1>;
4186 + } ServerRSAParams;
4189 + The modulus of the server's temporary RSA key.
4192 + The public exponent of the server's temporary RSA key.
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 */
4201 + The prime modulus used for the Diffie-Hellman operation.
4204 + The generator used for the Diffie-Hellman operation.
4207 + The server's Diffie-Hellman public value (g^X mod p).
4212 +Dierks & Allen Standards Track [Page 40]
4214 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4218 + select (KeyExchangeAlgorithm) {
4219 + case diffie_hellman:
4220 + ServerDHParams params;
4221 + Signature signed_params;
4223 + ServerRSAParams params;
4224 + Signature signed_params;
4226 + } ServerKeyExchange;
4229 + The server's key exchange parameters.
4232 + For non-anonymous key exchanges, a hash of the corresponding
4233 + params value, with the signature appropriate to that hash
4237 + MD5(ClientHello.random + ServerHello.random + ServerParams);
4240 + SHA(ClientHello.random + ServerHello.random + ServerParams);
4242 + enum { anonymous, rsa, dsa } SignatureAlgorithm;
4244 + select (SignatureAlgorithm)
4245 + { case anonymous: struct { };
4247 + digitally-signed struct {
4248 + opaque md5_hash[16];
4249 + opaque sha_hash[20];
4252 + digitally-signed struct {
4253 + opaque sha_hash[20];
4257 +7.4.4. Certificate request
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
4268 +Dierks & Allen Standards Track [Page 41]
4270 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4273 + Structure of this message:
4275 + rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
4277 + } ClientCertificateType;
4279 + opaque DistinguishedName<1..2^16-1>;
4282 + ClientCertificateType certificate_types<1..2^8-1>;
4283 + DistinguishedName certificate_authorities<3..2^16-1>;
4284 + } CertificateRequest;
4287 + This field is a list of the types of certificates requested,
4288 + sorted in order of the server's preference.
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.
4297 + Note: DistinguishedName is derived from [X509].
4299 + Note: It is a fatal handshake_failure alert for an anonymous server to
4300 + request client identification.
4302 +7.4.5. Server hello done
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.
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.
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.
4318 + Structure of this message:
4319 + struct { } ServerHelloDone;
4324 +Dierks & Allen Standards Track [Page 42]
4326 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4329 +7.4.6. Client certificate
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.
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
4348 +7.4.7. Client key exchange message
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.
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
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
4374 + select (KeyExchangeAlgorithm) {
4375 + case rsa: EncryptedPreMasterSecret;
4376 + case diffie_hellman: ClientDiffieHellmanPublic;
4380 +Dierks & Allen Standards Track [Page 43]
4382 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4386 + } ClientKeyExchange;
4388 +7.4.7.1. RSA encrypted premaster secret message
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
4399 + Structure of this message:
4401 + ProtocolVersion client_version;
4402 + opaque random[46];
4403 + } PreMasterSecret;
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
4413 + 46 securely-generated random bytes.
4416 + public-key-encrypted PreMasterSecret pre_master_secret;
4417 + } EncryptedPreMasterSecret;
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
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.
4436 +Dierks & Allen Standards Track [Page 44]
4438 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4442 + This random value is generated by the client and is used to
4443 + generate the master secret, as specified in Section 8.1.
4445 +7.4.7.2. Client Diffie-Hellman public value
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.
4454 + Structure of this message:
4455 + enum { implicit, explicit } PublicValueEncoding;
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.
4464 + Yc needs to be sent.
4467 + select (PublicValueEncoding) {
4468 + case implicit: struct { };
4469 + case explicit: opaque dh_Yc<1..2^16-1>;
4471 + } ClientDiffieHellmanPublic;
4474 + The client's Diffie-Hellman public value (Yc).
4476 +7.4.8. Certificate verify
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.
4485 + Structure of this message:
4487 + Signature signature;
4488 + } CertificateVerify;
4492 +Dierks & Allen Standards Track [Page 45]
4494 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4497 + The Signature type is defined in 7.4.3.
4499 + CertificateVerify.signature.md5_hash
4500 + MD5(handshake_messages);
4502 + Certificate.signature.sha_hash
4503 + SHA(handshake_messages);
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.
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.
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.
4529 + opaque verify_data[12];
4533 + PRF(master_secret, finished_label, MD5(handshake_messages) +
4534 + SHA-1(handshake_messages)) [0..11];
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".
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.
4548 +Dierks & Allen Standards Track [Page 46]
4550 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4553 + This is the concatenation of all the Handshake structures as
4554 + defined in 7.4 exchanged thus far.
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.
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
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
4575 +8. Cryptographic computations
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.
4586 +8.1. Computing the master secret
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
4593 + master_secret = PRF(pre_master_secret, "master secret",
4594 + ClientHello.random + ServerHello.random)
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.
4604 +Dierks & Allen Standards Track [Page 47]
4606 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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
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.
4621 +8.1.2. Diffie-Hellman
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.
4627 + Note: Diffie-Hellman parameters are specified by the server, and may
4628 + be either ephemeral or contained within the server's certificate.
4630 +9. Mandatory Cipher Suites
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.
4636 +10. Application data protocol
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
4660 +Dierks & Allen Standards Track [Page 48]
4662 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4665 +A. Protocol constant values
4667 + This section describes protocol types and constants.
4672 + uint8 major, minor;
4673 + } ProtocolVersion;
4675 + ProtocolVersion version = { 3, 1 }; /* TLS v1.0 */
4678 + change_cipher_spec(20), alert(21), handshake(22),
4679 + application_data(23), (255)
4684 + ProtocolVersion version;
4686 + opaque fragment[TLSPlaintext.length];
4691 + ProtocolVersion version;
4693 + opaque fragment[TLSCompressed.length];
4698 + ProtocolVersion version;
4700 + select (CipherSpec.cipher_type) {
4701 + case stream: GenericStreamCipher;
4702 + case block: GenericBlockCipher;
4706 + stream-ciphered struct {
4707 + opaque content[TLSCompressed.length];
4708 + opaque MAC[CipherSpec.hash_size];
4709 + } GenericStreamCipher;
4711 + block-ciphered struct {
4712 + opaque content[TLSCompressed.length];
4716 +Dierks & Allen Standards Track [Page 49]
4718 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4721 + opaque MAC[CipherSpec.hash_size];
4722 + uint8 padding[GenericBlockCipher.padding_length];
4723 + uint8 padding_length;
4724 + } GenericBlockCipher;
4726 +A.2. Change cipher specs message
4729 + enum { change_cipher_spec(1), (255) } type;
4730 + } ChangeCipherSpec;
4732 +A.3. Alert messages
4734 + enum { warning(1), fatal(2), (255) } AlertLevel;
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),
4751 + access_denied(49),
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),
4761 + } AlertDescription;
4765 + AlertDescription description;
4772 +Dierks & Allen Standards Track [Page 50]
4774 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4777 +A.4. Handshake protocol
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)
4788 + HandshakeType msg_type;
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;
4804 +A.4.1. Hello messages
4806 + struct { } HelloRequest;
4809 + uint32 gmt_unix_time;
4810 + opaque random_bytes[28];
4813 + opaque SessionID<0..32>;
4815 + uint8 CipherSuite[2];
4817 + enum { null(0), (255) } CompressionMethod;
4820 + ProtocolVersion client_version;
4822 + SessionID session_id;
4823 + CipherSuite cipher_suites<2..2^16-1>;
4824 + CompressionMethod compression_methods<1..2^8-1>;
4828 +Dierks & Allen Standards Track [Page 51]
4830 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4836 + ProtocolVersion server_version;
4838 + SessionID session_id;
4839 + CipherSuite cipher_suite;
4840 + CompressionMethod compression_method;
4843 +A.4.2. Server authentication and key exchange messages
4845 + opaque ASN.1Cert<2^24-1>;
4848 + ASN.1Cert certificate_list<1..2^24-1>;
4851 + enum { rsa, diffie_hellman } KeyExchangeAlgorithm;
4854 + opaque RSA_modulus<1..2^16-1>;
4855 + opaque RSA_exponent<1..2^16-1>;
4856 + } ServerRSAParams;
4859 + opaque DH_p<1..2^16-1>;
4860 + opaque DH_g<1..2^16-1>;
4861 + opaque DH_Ys<1..2^16-1>;
4865 + select (KeyExchangeAlgorithm) {
4866 + case diffie_hellman:
4867 + ServerDHParams params;
4868 + Signature signed_params;
4870 + ServerRSAParams params;
4871 + Signature signed_params;
4873 + } ServerKeyExchange;
4875 + enum { anonymous, rsa, dsa } SignatureAlgorithm;
4877 + select (SignatureAlgorithm)
4878 + { case anonymous: struct { };
4880 + digitally-signed struct {
4884 +Dierks & Allen Standards Track [Page 52]
4886 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4889 + opaque md5_hash[16];
4890 + opaque sha_hash[20];
4893 + digitally-signed struct {
4894 + opaque sha_hash[20];
4899 + rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
4901 + } ClientCertificateType;
4903 + opaque DistinguishedName<1..2^16-1>;
4906 + ClientCertificateType certificate_types<1..2^8-1>;
4907 + DistinguishedName certificate_authorities<3..2^16-1>;
4908 + } CertificateRequest;
4910 + struct { } ServerHelloDone;
4912 +A.4.3. Client authentication and key exchange messages
4915 + select (KeyExchangeAlgorithm) {
4916 + case rsa: EncryptedPreMasterSecret;
4917 + case diffie_hellman: DiffieHellmanClientPublicValue;
4919 + } ClientKeyExchange;
4922 + ProtocolVersion client_version;
4923 + opaque random[46];
4925 + } PreMasterSecret;
4928 + public-key-encrypted PreMasterSecret pre_master_secret;
4929 + } EncryptedPreMasterSecret;
4931 + enum { implicit, explicit } PublicValueEncoding;
4934 + select (PublicValueEncoding) {
4935 + case implicit: struct {};
4936 + case explicit: opaque DH_Yc<1..2^16-1>;
4940 +Dierks & Allen Standards Track [Page 53]
4942 +RFC 2246 The TLS Protocol Version 1.0 January 1999
4946 + } ClientDiffieHellmanPublic;
4949 + Signature signature;
4950 + } CertificateVerify;
4952 +A.4.4. Handshake finalization message
4955 + opaque verify_data[12];
4958 +A.5. The CipherSuite
4960 + The following values define the CipherSuite codes used in the client
4961 + hello and server hello messages.
4963 + A CipherSuite defines a cipher specification supported in TLS Version
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.
4971 + CipherSuite TLS_NULL_WITH_NULL_NULL = { 0x00,0x00 };
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.
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 };
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
4996 +Dierks & Allen Standards Track [Page 54]
4998 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
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 };
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.
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 };
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.
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
5052 +Dierks & Allen Standards Track [Page 55]
5054 +RFC 2246 The TLS Protocol Version 1.0 January 1999
5057 + Note: The cipher suite values { 0x00, 0x1C } and { 0x00, 0x1D } are
5058 + reserved to avoid collision with Fortezza-based cipher suites in
5061 +A.6. The Security Parameters
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:
5067 + enum { null(0), (255) } CompressionMethod;
5069 + enum { server, client } ConnectionEnd;
5071 + enum { null, rc4, rc2, des, 3des, des40, idea }
5072 + BulkCipherAlgorithm;
5074 + enum { stream, block } CipherType;
5076 + enum { true, false } IsExportable;
5078 + enum { null, md5, sha } MACAlgorithm;
5080 + /* The algorithms specified in CompressionMethod,
5081 + BulkCipherAlgorithm, and MACAlgorithm may be added to. */
5084 + ConnectionEnd entity;
5085 + BulkCipherAlgorithm bulk_cipher_algorithm;
5086 + CipherType cipher_type;
5088 + uint8 key_material_length;
5089 + IsExportable is_exportable;
5090 + MACAlgorithm mac_algorithm;
5092 + CompressionMethod compression_algorithm;
5093 + opaque master_secret[48];
5094 + opaque client_random[32];
5095 + opaque server_random[32];
5096 + } SecurityParameters;
5108 +Dierks & Allen Standards Track [Page 56]
5110 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
5121 + See public key cryptography.
5124 + Authentication is the ability of one entity to determine the
5125 + identity of another entity.
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.
5132 + A symmetric encryption algorithm used to encrypt large quantities
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
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.
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
5158 + The key used to encrypt data written by the client.
5164 +Dierks & Allen Standards Track [Page 57]
5166 +RFC 2246 The TLS Protocol Version 1.0 January 1999
5169 + client write MAC secret
5170 + The secret data used to authenticate data written by the client.
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.
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]
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.
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.
5203 + An initial negotiation between client and server that establishes
5204 + the parameters of their transactions.
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
5212 + A 64-bit block cipher designed by Xuejia Lai and James Massey.
5220 +Dierks & Allen Standards Track [Page 58]
5222 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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
5232 + Secure secret data used for generating encryption keys, MAC
5236 + MD5 is a secure hashing function that converts an arbitrarily
5237 + long data stream into a digest of fixed size (16 bytes). [MD5]
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.
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.
5252 + A block cipher developed by Ron Rivest at RSA Data Security, Inc.
5253 + [RSADSI] described in [RC2].
5256 + A stream cipher licensed by RSA Data Security [RSADSI]. A
5257 + compatible cipher is described in [RC4].
5260 + A very widely used public-key algorithm that can be used for
5261 + either encryption or digital signing. [RSA]
5264 + Non-secret random data used to make export encryption keys resist
5265 + precomputation attacks.
5268 + The server is the application entity that responds to requests
5269 + for connections from clients. See also under client.
5276 +Dierks & Allen Standards Track [Page 59]
5278 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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
5289 + session identifier
5290 + A session identifier is a value generated by a server that
5291 + identifies a particular session.
5294 + The key used to encrypt data written by the server.
5296 + server write MAC secret
5297 + The secret data used to authenticate data written by the server.
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]
5305 + Netscape's Secure Socket Layer protocol [SSL3]. TLS is based on
5309 + An encryption algorithm that converts a key into a
5310 + cryptographically-strong keystream, which is then exclusive-ORed
5311 + with the plaintext.
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.
5332 +Dierks & Allen Standards Track [Page 60]
5334 +RFC 2246 The TLS Protocol Version 1.0 January 1999
5337 +C. CipherSuite definitions
5339 +CipherSuite Is Key Cipher Hash
5340 + Exportable Exchange
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
5372 + * Indicates IsExportable is True
5376 + Algorithm Description Key size limit
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,
5383 + DH_anon Anonymous DH, no signatures None
5384 + DH_anon_EXPORT Anonymous DH, no signatures DH = 512 bits
5388 +Dierks & Allen Standards Track [Page 61]
5390 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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,
5398 + NULL No key exchange N/A
5399 + RSA RSA key exchange None
5400 + RSA_EXPORT RSA key exchange RSA = 512 bits
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
5407 + Key Expanded Effective IV Block
5408 + Cipher Type Material Key Material Key Bits Size Size
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
5419 + * Indicates IsExportable is true.
5422 + Indicates whether this is a stream cipher or a block cipher
5423 + running in CBC mode.
5426 + The number of bytes from the key_block that are used for
5427 + generating the write keys.
5429 + Expanded Key Material
5430 + The number of bytes actually fed into the encryption algorithm
5432 + Effective Key Bits
5433 + How much entropy material is in the key material being fed into
5434 + the encryption routines.
5437 + How much data needs to be generated for the initialization
5438 + vector. Zero for stream ciphers; equal to the block size for
5444 +Dierks & Allen Standards Track [Page 62]
5446 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
5455 + function Size Size
5500 +Dierks & Allen Standards Track [Page 63]
5502 +RFC 2246 The TLS Protocol Version 1.0 January 1999
5505 +D. Implementation Notes
5507 + The TLS protocol cannot prevent many common security mistakes. This
5508 + section provides several recommendations to assist implementors.
5510 +D.1. Temporary RSA keys
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.
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.
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.
5533 + Whenever a new key is completed, the existing temporary key can be
5534 + replaced with the new one.
5536 +D.2. Random Number Generation and Seeding
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.)
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.
5556 +Dierks & Allen Standards Track [Page 64]
5558 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
5573 +D.3. Certificates and authentication
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.
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
5612 +Dierks & Allen Standards Track [Page 65]
5614 +RFC 2246 The TLS Protocol Version 1.0 January 1999
5617 +E. Backward Compatibility With SSL
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.
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.
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
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.
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.
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.
5658 + The following cipher specifications are carryovers from SSL Version
5659 + 2.0. These are assumed to use RSA for key exchange and
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 };
5668 +Dierks & Allen Standards Track [Page 66]
5670 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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 };
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):
5685 + V2CipherSpec (see TLS name) = { 0x00, CipherSuite };
5687 +E.1. Version 2 client hello
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.
5693 + uint8 V2CipherSpec[3];
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];
5707 + This field, in conjunction with the version field, identifies a
5708 + version 2 client hello message. The value should be one (1).
5711 + The highest version of the protocol supported by the client
5712 + (equals ProtocolVersion.version, see Appendix A.1).
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
5724 +Dierks & Allen Standards Track [Page 67]
5726 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
5735 + The length in bytes of the client's challenge to the server to
5736 + authenticate itself. This value must be 32.
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
5744 + If this field's length is not zero, it will contain the
5745 + identification for a session that the client wishes to resume.
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.
5757 + Note: Requests to resume a TLS session should use a TLS client hello.
5759 +E.2. Avoiding man-in-the-middle version rollback
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.
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.
5780 +Dierks & Allen Standards Track [Page 68]
5782 +RFC 2246 The TLS Protocol Version 1.0 January 1999
5785 +F. Security analysis
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
5797 +F.1. Handshake protocol
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.
5805 +F.1.1. Authentication and key exchange
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.
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.
5828 +F.1.1.1. Anonymous key exchange
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
5836 +Dierks & Allen Standards Track [Page 69]
5838 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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).
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).
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.
5860 +F.1.1.2. RSA key exchange and authentication
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.
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.
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.
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.
5892 +Dierks & Allen Standards Track [Page 70]
5894 +RFC 2246 The TLS Protocol Version 1.0 January 1999
5897 +F.1.1.3. Diffie-Hellman key exchange with authentication
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.
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.
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.
5923 +F.1.2. Version rollback attacks
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.
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.
5948 +Dierks & Allen Standards Track [Page 71]
5950 +RFC 2246 The TLS Protocol Version 1.0 January 1999
5953 +F.1.3. Detecting attacks against the handshake protocol
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.
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.
5968 +F.1.4. Resuming sessions
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).
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
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.
5996 +F.2. Protecting application data
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.
6004 +Dierks & Allen Standards Track [Page 72]
6006 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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
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.
6028 + Note: MAC secrets may be larger than encryption keys, so messages can
6029 + remain tamper resistant even if encryption keys are broken.
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.
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.
6060 +Dierks & Allen Standards Track [Page 73]
6062 +RFC 2246 The TLS Protocol Version 1.0 January 1999
6065 +G. Patent Statement
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.
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:
6079 + Cryptographic Communications System and Method ("RSA"), No.
6082 + Netscape Communications Corporation has been issued the following
6083 + patent in the United States:
6085 + Secure Socket Layer Application Program Apparatus And Method
6086 + ("SSL"), No. 5,657,390
6088 + Netscape Communications has issued the following statement:
6090 + Intellectual Property Rights
6092 + Secure Sockets Layer
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:
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.
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
6116 +Dierks & Allen Standards Track [Page 74]
6118 +RFC 2246 The TLS Protocol Version 1.0 January 1999
6121 + What are "Patent Claims":
6123 + Patent claims are claims in an issued foreign or domestic patent
6126 + 1) must be infringed in order to implement methods or build
6127 + products according to the IETF TLS specification; or
6129 + 2) patent claims which require the elements of the SSL patent
6130 + claims and/or their equivalents to be infringed.
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.
6141 +Security Considerations
6143 + Security issues are discussed throughout this memo.
6147 + [3DES] W. Tuchman, "Hellman Presents No Shortcut Solutions To DES,"
6148 + IEEE Spectrum, v. 16, n. 7, July 1979, pp40-41.
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:
6155 + [DES] ANSI X3.106, "American National Standard for Information
6156 + Systems-Data Link Encryption," American National Standards
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.
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.
6167 + [FTP] Postel J., and J. Reynolds, "File Transfer Protocol", STD 9,
6168 + RFC 959, October 1985.
6172 +Dierks & Allen Standards Track [Page 75]
6174 +RFC 2246 The TLS Protocol Version 1.0 January 1999
6177 + [HTTP] Berners-Lee, T., Fielding, R., and H. Frystyk, "Hypertext
6178 + Transfer Protocol -- HTTP/1.0", RFC 1945, May 1996.
6180 + [HMAC] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
6181 + Hashing for Message Authentication," RFC 2104, February
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.
6188 + [MD2] Kaliski, B., "The MD2 Message Digest Algorithm", RFC 1319,
6191 + [MD5] Rivest, R., "The MD5 Message Digest Algorithm", RFC 1321,
6194 + [PKCS1] RSA Laboratories, "PKCS #1: RSA Encryption Standard,"
6195 + version 1.5, November 1993.
6197 + [PKCS6] RSA Laboratories, "PKCS #6: RSA Extended Certificate Syntax
6198 + Standard," version 1.5, November 1993.
6200 + [PKCS7] RSA Laboratories, "PKCS #7: RSA Cryptographic Message Syntax
6201 + Standard," version 1.5, November 1993.
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.
6207 + [RC2] Rivest, R., "A Description of the RC2(r) Encryption
6208 + Algorithm", RFC 2268, January 1998.
6210 + [RC4] Thayer, R. and K. Kaukonen, A Stream Cipher Encryption
6211 + Algorithm, Work in Progress.
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-
6218 + [RSADSI] Contact RSA Data Security, Inc., Tel: 415-595-8782
6220 + [SCH] B. Schneier. Applied Cryptography: Protocols, Algorithms,
6221 + and Source Code in C, Published by John Wiley & Sons, Inc.
6228 +Dierks & Allen Standards Track [Page 76]
6230 +RFC 2246 The TLS Protocol Version 1.0 January 1999
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.
6237 + [SSL2] Hickman, Kipp, "The SSL Protocol", Netscape Communications
6238 + Corp., Feb 9, 1995.
6240 + [SSL3] A. Frier, P. Karlton, and P. Kocher, "The SSL 3.0 Protocol",
6241 + Netscape Communications Corp., Nov 18, 1996.
6243 + [TCP] Postel, J., "Transmission Control Protocol," STD 7, RFC 793,
6246 + [TEL] Postel J., and J. Reynolds, "Telnet Protocol
6247 + Specifications", STD 8, RFC 854, May 1993.
6249 + [TEL] Postel J., and J. Reynolds, "Telnet Option Specifications",
6250 + STD 8, RFC 855, May 1993.
6252 + [X509] CCITT. Recommendation X.509: "The Directory - Authentication
6255 + [XDR] R. Srinivansan, Sun Microsystems, RFC-1832: XDR: External
6256 + Data Representation Standard, August 1995.
6263 + EMail: treese@openmarket.com
6268 + Christopher Allen Tim Dierks
6271 + EMail: callen@certicom.com EMail: tdierks@certicom.com
6274 + Authors' Addresses
6276 + Tim Dierks Philip L. Karlton
6277 + Certicom Netscape Communications
6279 + EMail: tdierks@certicom.com
6284 +Dierks & Allen Standards Track [Page 77]
6286 +RFC 2246 The TLS Protocol Version 1.0 January 1999
6289 + Alan O. Freier Paul C. Kocher
6290 + Netscape Communications Independent Consultant
6292 + EMail: freier@netscape.com EMail: pck@netcom.com
6295 + Other contributors
6297 + Martin Abadi Robert Relyea
6298 + Digital Equipment Corporation Netscape Communications
6300 + EMail: ma@pa.dec.com EMail: relyea@netscape.com
6302 + Ran Canetti Jim Roskind
6303 + IBM Watson Research Center Netscape Communications
6305 + EMail: canetti@watson.ibm.com EMail: jar@netscape.com
6308 + Taher Elgamal Micheal J. Sabin, Ph. D.
6309 + Securify Consulting Engineer
6311 + EMail: elgamal@securify.com EMail: msabin@netcom.com
6314 + Anil R. Gangolli Dan Simon
6315 + Structured Arts Computing Corp. Microsoft
6317 + EMail: gangolli@structuredarts.com EMail: dansimon@microsoft.com
6320 + Kipp E.B. Hickman Tom Weinstein
6321 + Netscape Communications Netscape Communications
6323 + EMail: kipp@netscape.com EMail: tomw@netscape.com
6327 + IBM Watson Research Center
6329 + EMail: hugo@watson.ibm.com
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/>.
6340 +Dierks & Allen Standards Track [Page 78]
6342 +RFC 2246 The TLS Protocol Version 1.0 January 1999
6345 + Archives of the list can be found at:
6346 + <http://www.imc.org/ietf-tls/mail-archive/>
6396 +Dierks & Allen Standards Track [Page 79]
6398 +RFC 2246 The TLS Protocol Version 1.0 January 1999
6401 +Full Copyright Statement
6403 + Copyright (C) The Internet Society (1999). All Rights Reserved.
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
6419 + The limited permissions granted above are perpetual and will not be
6420 + revoked by the Internet Society or its successors or assigns.
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.
6452 +Dierks & Allen Standards Track [Page 80]
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
6464 +Network Working Group P. Hoffman
6465 +Request for Comments: 2487 Internet Mail Consortium
6466 +Category: Standards Track January 1999
6469 + SMTP Service Extension for Secure SMTP over TLS
6471 +Status of this Memo
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.
6481 + Copyright (C) The Internet Society (1999). All Rights Reserved.
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.
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.
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.
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.
6515 +Hoffman Standards Track [Page 1]
6517 +RFC 2487 SMTP Service Extension January 1999
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].
6526 +3. STARTTLS Extension
6528 + The STARTTLS extension to SMTP is laid out as follows:
6530 + (1) the name of the SMTP service defined here is STARTTLS;
6532 + (2) the EHLO keyword value associated with the extension is STARTTLS;
6534 + (3) the STARTTLS keyword has no parameters;
6536 + (4) a new SMTP verb, "STARTTLS", is defined;
6538 + (5) no additional parameters are added to any SMTP command.
6540 +4. The STARTTLS Keyword
6542 + The STARTTLS keyword is used to tell the SMTP client that the SMTP
6543 + server allows use of TLS. It takes no parameters.
6545 +5. The STARTTLS Command
6547 + The format for the STARTTLS command is:
6551 + with no parameters.
6553 + After the client gives the STARTTLS command, the server responds with
6554 + one of the following reply codes:
6556 + 220 Ready to start TLS
6557 + 501 Syntax error (no parameters allowed)
6558 + 454 TLS not available due to temporary reason
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.
6571 +Hoffman Standards Track [Page 2]
6573 +RFC 2487 SMTP Service Extension January 1999
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
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:
6586 + 530 Must issue a STARTTLS command first
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.
6592 + After receiving a 220 response to a STARTTLS command, the client
6593 + SHOULD start the TLS negotiation before giving any other SMTP
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.
6599 +5.1 Processing After the STARTTLS Command
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.
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").
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:
6627 +Hoffman Standards Track [Page 3]
6629 +RFC 2487 SMTP Service Extension January 1999
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
6641 +5.2 Result of the STARTTLS Command
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.
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.
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
6668 + The following dialog illustrates how a client and server can start a
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
6679 + C: <starts TLS negotiation>
6683 +Hoffman Standards Track [Page 4]
6685 +RFC 2487 SMTP Service Extension January 1999
6688 + C & S: <negotiate a TLS session>
6689 + C & S: <check result of negotiation>
6690 + C: <continues by sending an SMTP command>
6693 +7. Security Considerations
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.
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.
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.
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.
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.
6739 +Hoffman Standards Track [Page 5]
6741 +RFC 2487 SMTP Service Extension January 1999
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
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.
6795 +Hoffman Standards Track [Page 6]
6797 +RFC 2487 SMTP Service Extension January 1999
6802 + [RFC-821] Postel, J., "Simple Mail Transfer Protocol", RFC 821,
6805 + [RFC-1869] Klensin, J., Freed, N, Rose, M, Stefferud, E. and D.
6806 + Crocker, "SMTP Service Extensions", STD 10, RFC 1869,
6809 + [RFC-2034] Freed, N., "SMTP Service Extension for Returning Enhanced
6810 + Error Codes", RFC 2034, October 1996.
6812 + [RFC-2119] Bradner, S., "Key words for use in RFCs to Indicate
6813 + Requirement Levels", BCP 14, RFC 2119, March 1997.
6815 + [SASL] Myers, J., "Simple Authentication and Security Layer
6816 + (SASL)", RFC 2222, October 1997.
6818 + [SMTP-AUTH] "SMTP Service Extension for Authentication", Work in
6821 + [TLS] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0",
6822 + RFC 2246, January 1999.
6824 +B. Author's Address
6827 + Internet Mail Consortium
6829 + Santa Cruz, CA 95060
6831 + Phone: (831) 426-9827
6832 + EMail: phoffman@imc.org
6851 +Hoffman Standards Track [Page 7]
6853 +RFC 2487 SMTP Service Extension January 1999
6856 +C. Full Copyright Statement
6858 + Copyright (C) The Internet Society (1999). All Rights Reserved.
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
6874 + The limited permissions granted above are perpetual and will not be
6875 + revoked by the Internet Society or its successors or assigns.
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.
6907 +Hoffman Standards Track [Page 8]
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
6913 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
6916 +<meta name="generator" content="HTML Tidy, see www.w3.org">
6917 +<title>Postfix/TLS - Security Considerations</title>
6920 +<h1>Postfix/TLS - Security Considerations</h1>
6922 +The following sections cover some (possible) security issues with
6923 +regard to Postfix/TLS.
6925 +<h2>Server/Client private key file</h2>
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
6935 +<p>The only protection can therefore come from filesystem access
6936 +rights, which should be set to 'owner root' and 'readable for owner
6940 +-rw------- 1 root sys 887 Apr 29 1999 /etc/postfix/key.pem
6943 +<p>This protection is only as good as your host is protected
6944 +against root exploits.</p>
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>
6953 +<h2>Disk based session cache</h2>
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.
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>
6968 +<h2>DNS issues</h2>
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
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>
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>
6986 +important.dom.ain smtp:[mailserver.important.dom.ain]
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
6995 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
6998 +<meta name="generator" content="HTML Tidy, see www.w3.org">
6999 +<title>Postfix/TLS - Setting up the certificates</title>
7002 +<h1>Postfix/TLS - Setting up the certificates</h1>
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.
7012 +<h2>Server certificate</h2>
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
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>
7029 +<p>So for the server we do need:</p>
7032 +<li>1 <em>server private key</em></li>
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>
7038 +<li>1 <em>CA certificate</em> with the public key of the CA</li>
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!
7045 +<h3>Server certificate policy</h3>
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.
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>
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>
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
7073 +<h3>Using the certificates with Postfix/TLS</h3>
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:
7080 +<li>The private key:
7083 +smtp_tls_key_file = /etc/postfix/key.pem
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:
7093 +chown root /etc/postfix/key.pem ; chmod 400 /etc/postfix/key.pem
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>
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
7111 +smtp_tls_cert_file = /etc/postfix/cert.pem
7114 +If you like, you can put private key and cert into one file.</li>
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.
7121 +smtp_tls_CAfile = /etc/postfix/CAcert.pem
7126 +With these certificates you should already have enough to get
7127 +Postfix/TLS running.
7129 +<h3>Postfix/TLS client mode</h3>
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:
7139 +smtp_tls_key_file = /etc/postfix/key.pem
7140 +chown root /etc/postfix/key.pem ; chmod 400 /etc/postfix/key.pem
7144 +smtp_tls_cert_file = /etc/postfix/cert.pem
7148 +smtp_tls_CAfile = /etc/postfix/CAcert.pem
7151 +<h2>Client certificates</h2>
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.
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>
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>
7171 +<h3>Listing CA certificates</h3>
7173 +<p>You have two possibilities to perform this task.</p>
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>
7182 +<li>You can add the CA certificates in single files with adequate
7183 +names to a certificate directory specified in:
7186 +smtpd_tls_CApath = /etc/postfix/certs
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>
7195 +<h3>Adding client certificates</h3>
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.
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>
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
7218 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
7221 +<meta name="generator" content="HTML Tidy, see www.w3.org">
7222 +<title>Postfix/TLS - Testing</title>
7225 +<h1>Postfix/TLS - Testing</h1>
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 :-).
7233 +<h2>Included debugging aids</h2>
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).
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
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>
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>
7261 +<li>Development Platform:
7264 +<li>OS: HP-UX 10.20</li>
7266 +<li>OS: Linux 2.x (SuSE Linux)</li>
7270 +<li>Reported Success:
7273 +<li>OS: Solaris 2.5 - Walcir Fontanini
7274 +<walcir@densis.fee.unicamp.br></li>
7281 +<li>Software: Netscape 4.5x, Netscape 4.6x, Netscape 4.7x</li>
7283 +<li>OS: HP-UX 10.20, Linux 2.x, Win95</li>
7288 +Please don't comment on the stability of Netscape, especially not
7291 +<h2>Interoperability</h2>
7293 +Besides support by generic wrapper solutions, there exist specially
7294 +crafted extensions for other MTAs:
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.
7303 +<p>Testing: send mail to <tt>ping@linux.student.kuleuven.ac.be</tt>
7304 +(will send back complete email including headers).</p>
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>].
7311 +<p>Zmailer -> Postfix works fine,<br>
7312 +Postfix -> Zmailer does not work, since ESMTP is not recognized
7313 +(problem reported).</p>
7315 +<p>Testing: send mail to <tt>autoanswer@mea.tmt.tele.fi</tt> (will
7316 +send back headers).</p>
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>].
7325 +<p>Testing: send mail to <tt>bounce@esmtp.org</tt> (will bounce
7326 +error message including old headers).</p>
7329 +<li><strong>Postfix</strong> Can send emails to itself :-).
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>
7337 +Other reports are welcome.
7339 +<h2>Known bugs</h2>
7341 +This software is just at the beginning, so please be patient. By
7342 +now I have these points:
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
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
7359 +<p><strong>Should finally be fixed with OpenSSL 0.9.5.</strong></p>
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>
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>
7374 +<li>Server side: Outlook Express (Mac) seems not to support
7375 +RFC2487, you must use smtpd_tls_wrappermode on a different port(!)
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>
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>
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
7406 +Postfix TLS session cache and PRNG handling manager
7410 +\fBtlsmgr\fR [generic Postfix daemon options]
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.
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.
7427 +Tlsmgr can be run chrooted and with dropped privileges, as it will
7428 +connect to the entropy source at startup.
7430 +The PRNG is additionally seeded internally by the data found in the
7431 +session cache and timevalues.
7433 +Tlsmgr reads the old value of the exchange file at startup to keep
7434 +entropy already collected during previous runs.
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].
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.
7455 +Problems and transactions are logged to the syslog daemon.
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
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.
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
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).
7519 +smtp(8) SMTP client
7520 +smtpd(8) SMTP server
7526 +The Secure Mailer license must be distributed with this software.
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
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 \
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 \
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 \
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 \
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
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;
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,
7638 static CONFIG_STR_FN_TABLE function_str_defaults_2[] = {
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,
7648 static CONFIG_TIME_TABLE time_defaults[] = {
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,
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;
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;
7669 +#define VAR_TLS_RAND_SOURCE "tls_random_source"
7670 +#define DEF_TLS_RAND_SOURCE ""
7671 +extern char *var_tls_rand_source;
7673 +#define VAR_TLS_RAND_BYTES "tls_random_bytes"
7674 +#define DEF_TLS_RAND_BYTES 32
7675 +extern int var_tls_rand_bytes;
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;
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;
7685 +#define VAR_TLS_RESEED_PERIOD "tls_random_reseed_period"
7686 +#define DEF_TLS_RESEED_PERIOD "3600s"
7687 +extern int var_tls_reseed_period;
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;
7694 * Queue manager: relocated databases.
7696 @@ -647,6 +675,10 @@
7697 #define DEF_SMTP_HELO_TMOUT "300s"
7698 extern int var_smtp_helo_tmout;
7700 +#define VAR_SMTP_STARTTLS_TMOUT "smtp_starttls_timeout"
7701 +#define DEF_SMTP_STARTTLS_TMOUT "300s"
7702 +extern int var_smtp_starttls_tmout;
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;
7711 +#define VAR_SMTP_ALWAYS_EHLO "smtp_always_send_ehlo"
7712 +#define DEF_SMTP_ALWAYS_EHLO 0
7713 +extern bool var_smtp_always_ehlo;
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;
7722 +#define VAR_SMTPD_STARTTLS_TMOUT "smtpd_starttls_timeout"
7723 +#define DEF_SMTPD_STARTTLS_TMOUT "300s"
7724 +extern int var_smtpd_starttls_tmout;
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;
7733 +#define VAR_SMTPD_TLS_WRAPPER "smtpd_tls_wrappermode"
7734 +#define DEF_SMTPD_TLS_WRAPPER 0
7735 +extern bool var_smtpd_tls_wrappermode;
7737 +#define VAR_SMTPD_USE_TLS "smtpd_use_tls"
7738 +#define DEF_SMTPD_USE_TLS 0
7739 +extern bool var_smtpd_use_tls;
7741 +#define VAR_SMTPD_ENFORCE_TLS "smtpd_enforce_tls"
7742 +#define DEF_SMTPD_ENFORCE_TLS 0
7743 +extern bool var_smtpd_enforce_tls;
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;
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;
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;
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;
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;
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;
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;
7773 +#define VAR_SMTPD_TLS_CA_FILE "smtpd_tls_CAfile"
7774 +#define DEF_SMTPD_TLS_CA_FILE ""
7775 +extern char *var_smtpd_tls_CAfile;
7777 +#define VAR_SMTPD_TLS_CA_PATH "smtpd_tls_CApath"
7778 +#define DEF_SMTPD_TLS_CA_PATH ""
7779 +extern char *var_smtpd_tls_CApath;
7781 +#define VAR_SMTPD_TLS_CLIST "smtpd_tls_cipherlist"
7782 +#define DEF_SMTPD_TLS_CLIST ""
7783 +extern char *var_smtpd_tls_cipherlist;
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;
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;
7793 +#define VAR_SMTPD_TLS_LOGLEVEL "smtpd_tls_loglevel"
7794 +#define DEF_SMTPD_TLS_LOGLEVEL 0
7795 +extern int var_smtpd_tls_loglevel;
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;
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;
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;
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;
7813 +#define VAR_SMTP_USE_TLS "smtp_use_tls"
7814 +#define DEF_SMTP_USE_TLS 0
7815 +extern bool var_smtp_use_tls;
7817 +#define VAR_SMTP_ENFORCE_TLS "smtp_enforce_tls"
7818 +#define DEF_SMTP_ENFORCE_TLS 0
7819 +extern bool var_smtp_enforce_tls;
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;
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;
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;
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;
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;
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;
7845 +#define VAR_SMTP_TLS_CA_FILE "smtp_tls_CAfile"
7846 +#define DEF_SMTP_TLS_CA_FILE ""
7847 +extern char *var_smtp_tls_CAfile;
7849 +#define VAR_SMTP_TLS_CA_PATH "smtp_tls_CApath"
7850 +#define DEF_SMTP_TLS_CA_PATH ""
7851 +extern char *var_smtp_tls_CApath;
7853 +#define VAR_SMTP_TLS_CLIST "smtp_tls_cipherlist"
7854 +#define DEF_SMTP_TLS_CLIST ""
7855 +extern char *var_smtp_tls_cipherlist;
7857 +#define VAR_SMTP_TLS_LOGLEVEL "smtp_tls_loglevel"
7858 +#define DEF_SMTP_TLS_LOGLEVEL 0
7859 +extern int var_smtp_tls_loglevel;
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;
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;
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;
7874 * SASL authentication support, SMTP server side.
7876 @@ -1007,6 +1187,10 @@
7877 #define DEF_RELAY_DOMAINS "$mydestination"
7878 extern char *var_relay_domains;
7880 +#define VAR_RELAY_CCERTS "relay_clientcerts"
7881 +#define DEF_RELAY_CCERTS ""
7882 +extern char *var_relay_ccerts;
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
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
7915 +/* interface to openssl routines
7917 +/* #include <pfixtls.h>
7919 +/* const long scache_db_version;
7920 +/* const long openssl_version;
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;
7929 +/* int pfixtls_clientengine;
7930 +/* int pfixtls_clientactive;
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;
7939 +/* int pfixtls_timed_read(fd, buf, len, timeout, unused_context)
7946 +/* int pfixtls_timed_write(fd, buf, len, timeout, unused_context);
7953 +/* int pfixtls_init_serverengine(verifydepth, askcert);
7954 +/* int verifydepth;
7957 +/* int pfixtls_start_servertls(stream, timeout, peername, peeraddr,
7958 +/* tls_info, requirecert);
7959 +/* VSTREAM *stream;
7961 +/* const char *peername;
7962 +/* const char *peeraddr;
7963 +/* tls_info_t *tls_info;
7964 +/* int requirecert;
7966 +/* int pfixtls_stop_servertls(stream, failure, tls_info);
7967 +/* VSTREAM *stream;
7969 +/* tls_info_t *tls_info;
7971 +/* int pfixtls_init_clientengine(verifydepth);
7972 +/* int verifydepth;
7974 +/* int pfixtls_start_clienttls(stream, timeout, peername, peeraddr,
7976 +/* VSTREAM *stream;
7978 +/* const char *peername;
7979 +/* const char *peeraddr;
7980 +/* tls_info_t *tls_info;
7982 +/* int pfixtls_stop_clienttls(stream, failure, tls_info);
7983 +/* VSTREAM *stream;
7985 +/* tls_info_t *tls_info;
7988 +/* This module is the interface between Postfix and the OpenSSL library.
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.
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.
8000 +/* pfixtls_init_clientengine() is the corresponding function called
8001 +/* in smtp. Here we take the peer's (server's) certificate in any
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.
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.
8017 +/* pfixtls_start_clienttls() and pfixtls_stop_clienttls() are the
8018 +/* corresponding functions for smtp.
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
8027 +/* The last two values may be different when talking to a crippled
8028 +/* - ahem - export controled peer (e.g. 40/128).
8030 +/* The status of the peer certificate verification is available in
8031 +/* pfixtls_peer_verified. It is set to 1, when the certificate could
8033 +/* If the peer offered a certifcate, part of the certificate data are
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
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
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.
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.
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
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.
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
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.
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.
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.
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.
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.
8133 +/* Allgemeine Elektrotechnik
8134 +/* Universitaetsplatz 3-4
8135 +/* D-03044 Cottbus, Germany
8138 +/* System library. */
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>
8146 +#include <string.h>
8149 +/* Utility library. */
8151 +#include <iostuff.h>
8152 +#include <mymalloc.h>
8153 +#include <vstring.h>
8154 +#include <vstream.h>
8156 +#include <myflock.h>
8157 +#include <stringops.h>
8159 +/* Application-specific. */
8161 +#include "mail_params.h"
8162 +#include "pfixtls.h"
8164 +#define STR vstring_str
8166 +const tls_info_t tls_info_zero = {
8167 + 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0
8172 +/* OpenSSL library. */
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>
8181 +/* We must keep some of the info available */
8182 +static const char hexcodes[] = "0123456789ABCDEF";
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.
8193 +static const int id_maxlength = 64; /* Max ID length in bytes */
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.
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;
8206 +static rand_exch_fd = -1;
8208 +static DICT *scache_db = NULL;
8209 +const long scache_db_version = 0x00000002L;
8210 +const long openssl_version = OPENSSL_VERSION_NUMBER;
8213 +int pfixtls_serverengine = 0;
8214 +static int pfixtls_serveractive = 0; /* available or not */
8216 +int pfixtls_clientengine = 0;
8217 +static int pfixtls_clientactive = 0; /* available or not */
8220 + * Define a maxlength for certificate onelines. The length is checked by
8221 + * all routines when copying.
8223 +#define CCERT_BUFSIZ 256
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;
8242 + struct timeval tv;
8245 +static randseed_t randseed;
8246 +static struct stat seedfile_stat;
8249 + * Finally some "backup" DH-Parameters to be loaded, if no parameters are
8250 + * explicitely loaded from file.
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,
8261 +static unsigned char dh512_g[] = {
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,
8279 +static unsigned char dh1024_g[] = {
8284 + * DESCRIPTION: Keeping control of the network interface using BIO-pairs.
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:
8292 + * postfix | TLS-engine
8294 + * +--------> SSL_operations()
8297 + * | BIO-pair (internal_bio)
8298 + * +--------< BIO-pair (network_bio)
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
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!
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.
8326 +const ssize_t BIO_bufsiz = 8192;
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.
8335 +static int network_biopair_interop(int fd, int timeout, BIO *network_bio)
8344 +#define NETLAYER_BUFFERSIZE 8192
8345 + char buffer[8192];
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);
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).
8361 + if (timeout > 0 && write_wait(fd, timeout) < 0)
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);
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)
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");
8386 +static void pfixtls_print_errors(void);
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
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)
8409 + status = hsfunc(TLScontext->con);
8411 + status = rfunc(TLScontext->con, buf, num);
8413 + status = wfunc(TLScontext->con, (const char *)buf, num);
8414 + err = SSL_get_error(TLScontext->con, status);
8416 +#if (OPENSSL_VERSION_NUMBER <= 0x0090581fL)
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.
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.
8435 + * This workaround is secure, as verify_result is set to "failed"
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);
8448 + case SSL_ERROR_NONE: /* success */
8450 + done = 1; /* no break, flush buffer before */
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 */
8459 + case SSL_ERROR_ZERO_RETURN: /* connection was closed cleanly */
8460 + case SSL_ERROR_SYSCALL:
8461 + case SSL_ERROR_SSL:
8471 +int pfixtls_timed_read(int fd, void *buf, unsigned buf_len, int timeout,
8478 + TLScontext_t *TLScontext;
8480 + TLScontext = (TLScontext_t *)context;
8482 + msg_fatal("Called tls_timed_read() without TLS-context");
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;
8491 + while ((i < 39) && (i < ret) && (mybuf2[i] != 0)) {
8492 + mybuf[i] = mybuf2[i];
8496 + msg_info("Read %d chars: %s", ret, mybuf);
8502 +int pfixtls_timed_write(int fd, void *buf, unsigned len, int timeout,
8508 + TLScontext_t *TLScontext;
8510 + TLScontext = (TLScontext_t *)context;
8512 + msg_fatal("Called tls_timed_write() without TLS-context");
8514 + if ((pfixtls_serveractive && var_smtpd_tls_loglevel >= 4) ||
8515 + (pfixtls_clientactive && var_smtp_tls_loglevel >= 4)) {
8516 + mybuf2 = (char *) buf;
8519 + while ((i < 39) && (i < len) && (mybuf2[i] != 0)) {
8520 + mybuf[i] = mybuf2[i];
8524 + msg_info("Write %d chars: %s", len, mybuf);
8527 + return (do_tls_operation(fd, timeout, TLScontext, NULL, NULL, SSL_write,
8531 +/* Add some more entropy to the pool by adding the actual time */
8533 +static void pfixtls_stir_seed(void)
8535 + GETTIMEOFDAY(&randseed.tv);
8536 + RAND_seed(&randseed, sizeof(randseed_t));
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.
8545 +static void pfixtls_print_errors(void)
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);
8561 + msg_info("%lu:%s:%s:%d:", es, ERR_error_string(l, buf),
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.
8571 + * This function is taken from OpenSSL apps/s_cb.c
8574 +static int set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file)
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();
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();
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");
8600 +/* taken from OpenSSL apps/s_cb.c */
8602 +static RSA *tmp_rsa_cb(SSL * s, int export, int keylength)
8604 + static RSA *rsa_tmp = NULL;
8606 + if (rsa_tmp == NULL) {
8607 + rsa_tmp = RSA_generate_key(keylength, RSA_F4, NULL, NULL);
8613 +static DH *get_dh512(void)
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))
8630 +static DH *get_dh1024(void)
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))
8647 +/* partly inspired by mod_ssl */
8649 +static DH *tmp_dh_cb(SSL *s, int export, int keylength)
8651 + DH *dh_tmp = NULL;
8654 + if (keylength == 512)
8655 + dh_tmp = get_dh512(); /* export cipher */
8656 + else if (keylength == 1024)
8657 + dh_tmp = get_dh1024(); /* normal */
8659 + dh_tmp = get_dh1024(); /* not on-the-fly (too expensive) */
8660 + /* so use the 1024bit instead */
8663 + dh_tmp = get_dh1024(); /* sign-only certificate */
8670 + * Skeleton taken from OpenSSL apps/s_cb.c
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.
8677 + * Postfix/TLS has two modes, the "use" mode and the "enforce" mode:
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".
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).
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"... :-)
8705 +static int verify_callback(int ok, X509_STORE_CTX * ctx)
8708 + char *CN_lowercase;
8714 + TLScontext_t *TLScontext;
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);
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);
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);
8728 + verify_depth = SSL_get_verify_depth(con);
8729 + if (ok && (verify_depth >= 0) && (depth > verify_depth)) {
8731 + err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
8732 + X509_STORE_CTX_set_error(ctx, err);
8735 + msg_info("verify error:num=%d:%s", err,
8736 + X509_verify_cert_error_string(err));
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);
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);
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");
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");
8766 + if (((pfixtls_serverengine) && (var_smtpd_tls_loglevel >= 2)) ||
8767 + ((pfixtls_clientengine) && (var_smtp_tls_loglevel >= 2)))
8768 + msg_info("verify return:%d", ok);
8770 + if (TLScontext->enforce_verify_errors)
8776 +/* taken from OpenSSL apps/s_cb.c */
8778 +static void apps_ssl_info_callback(SSL * s, int where, int ret)
8783 + w = where & ~SSL_ST_MASK;
8785 + if (w & SSL_ST_CONNECT)
8786 + str = "SSL_connect";
8787 + else if (w & SSL_ST_ACCEPT)
8788 + str = "SSL_accept";
8790 + str = "undefined";
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) {
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));
8812 + * taken from OpenSSL crypto/bio/b_dump.c, modified to save a lot of strcpy
8813 + * and strcat by Matti Aarnio.
8817 +#define DUMP_WIDTH 16
8819 +static int pfixtls_dump(const char *s, int len)
8822 + char buf[160 + 1];
8833 + for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--)
8837 + rows = (len / DUMP_WIDTH);
8838 + if ((rows * DUMP_WIDTH) < len)
8841 + for (i = 0; i < rows; i++) {
8842 + buf[0] = '\0'; /* start with empty string */
8845 + sprintf(ss, "%04x ", i * DUMP_WIDTH);
8847 + for (j = 0; j < DUMP_WIDTH; j++) {
8848 + if (((i * DUMP_WIDTH) + j) >= len) {
8851 + ch = ((unsigned char) *((char *) (s) + i * DUMP_WIDTH + j))
8853 + sprintf(ss, "%02x%c", ch, j == 7 ? '|' : ' ');
8859 + for (j = 0; j < DUMP_WIDTH; j++) {
8860 + if (((i * DUMP_WIDTH) + j) >= len)
8862 + ch = ((unsigned char) *((char *) (s) + i * DUMP_WIDTH + j)) & 0xff;
8863 + *ss++ = (((ch >= ' ') && (ch <= '~')) ? ch : '.');
8864 + if (j == 7) *ss++ = ' ';
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
8871 + msg_info("%s", buf);
8872 + ret += strlen(buf);
8876 + sprintf(buf, "%04x - <SPACES/NULS>\n", len + trunc);
8877 + msg_info("%s", buf);
8878 + ret += strlen(buf);
8886 +/* taken from OpenSSL apps/s_cb.c */
8888 +static long bio_dump_cb(BIO * bio, int cmd, const char *argp, int argi,
8889 + long argl, long ret)
8894 + if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
8895 + msg_info("read from %08X [%08lX] (%d bytes => %ld (0x%X))", bio, argp,
8897 + pfixtls_dump(argp, (int) 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,
8902 + pfixtls_dump(argp, (int) ret);
8909 + * Callback to retrieve a session from the external session cache.
8911 +static SSL_SESSION *get_session_cb(SSL *ssl, unsigned char *SessionID,
8912 + int length, int *copy)
8914 + SSL_SESSION *session;
8919 + const char *session_hex;
8920 + pfixtls_scache_info_t scache_info;
8921 + unsigned char nibble, *data, *sess_data;
8923 + if (length > id_maxlength)
8924 + uselength = id_maxlength; /* Limit length of ID */
8926 + uselength = length;
8928 + idstring = (char *)mymalloc(2 * uselength + 1);
8930 + msg_info("could not allocate memory for IDstring");
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);
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);
8946 + msg_info("could not allocate memory for session reload");
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';
8956 + nibble = session_hex[n] - 'A' + 10;
8958 + data[n / 2] |= nibble;
8960 + data[n / 2] |= (nibble << 4);
8964 + * First check the version numbers, since wrong session data might
8965 + * hit us hard (SEGFAULT). We also have to check for expiry.
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);
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));
8977 + pfixtls_print_errors();
8979 + myfree((char *)data);
8982 + if (session && (var_smtpd_tls_loglevel >= 3))
8983 + msg_info("Successfully reloaded session from disc");
8990 +static SSL_SESSION *load_clnt_session(const char *hostname)
8992 + SSL_SESSION *session = NULL;
8998 + const char *session_hex;
8999 + pfixtls_scache_info_t scache_info;
9000 + unsigned char nibble, *data, *sess_data;
9002 + length = strlen(hostname);
9003 + if (length > id_maxlength)
9004 + uselength = id_maxlength; /* Limit length of ID */
9006 + uselength = length;
9008 + idstring = (char *)mymalloc(uselength + 1);
9010 + msg_info("could not allocate memory for IDstring");
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);
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);
9025 + msg_info("could not allocate memory for session reload");
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';
9035 + nibble = session_hex[n] - 'A' + 10;
9037 + data[n / 2] |= nibble;
9039 + data[n / 2] |= (nibble << 4);
9043 + * First check the version numbers, since wrong session data might
9044 + * hit us hard (SEGFAULT). We also have to check for expiry.
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);
9052 + sess_data = data + sizeof(pfixtls_scache_info_t);
9053 + session = d2i_SSL_SESSION(NULL, &sess_data,
9054 + hex_length / 2 - sizeof(time_t));
9056 + pfixtls_print_errors();
9058 + myfree((char *)data);
9063 + if (session && (var_smtp_tls_loglevel >= 3))
9064 + msg_info("Successfully reloaded session from disc");
9070 +static void remove_srvr_session(unsigned char *SessionID, int length)
9077 + if (length > id_maxlength)
9078 + uselength = id_maxlength; /* Limit length of ID */
9080 + uselength = length;
9082 + idstring = (char *)mymalloc(2 * uselength + 1);
9084 + msg_info("could not allocate memory for IDstring");
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);
9094 + dict_del(scache_db, idstring);
9100 +static void remove_clnt_session(const char *hostname)
9107 + length = strlen(hostname);
9108 + if (length > id_maxlength)
9109 + uselength = id_maxlength; /* Limit length of ID */
9111 + uselength = length;
9113 + idstring = (char *)mymalloc(uselength + 1);
9115 + msg_info("could not allocate memory for IDstring");
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);
9125 + dict_del(scache_db, idstring);
9131 + * Save a new session to the external cache
9133 +static int new_session_cb(SSL *ssl, SSL_SESSION *session)
9140 + unsigned char *data, *sess_data;
9141 + pfixtls_scache_info_t scache_info;
9144 + if (session->session_id_length > id_maxlength)
9145 + uselength = id_maxlength; /* Limit length of ID */
9147 + uselength = session->session_id_length;
9149 + idstring = (char *)mymalloc(2 * uselength + 1);
9151 + msg_info("could not allocate memory for IDstring");
9155 + for(n=0 ; n < uselength ; n++)
9156 + sprintf(idstring + 2 * n, "%02x", session->session_id[n]);
9158 + if (var_smtpd_tls_loglevel >= 3)
9159 + msg_info("Trying to save Session to disc: %s", idstring);
9162 + * Get the session and convert it into some "database" useable form.
9163 + * First, get the length of the session to allocate the memory.
9165 + dsize = i2d_SSL_SESSION(session, NULL);
9167 + msg_info("Could not access session");
9170 + data = (unsigned char *)mymalloc(dsize + sizeof(pfixtls_scache_info_t));
9172 + msg_info("could not allocate memory for SSL session");
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).
9182 + scache_info.scache_db_version = scache_db_version;
9183 + scache_info.openssl_version = openssl_version;
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.)
9190 + scache_info.timestamp = time(NULL);
9192 + memcpy(data, &scache_info, sizeof(pfixtls_scache_info_t));
9193 + sess_data = data + sizeof(pfixtls_scache_info_t);
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.
9201 + len = i2d_SSL_SESSION(session, &sess_data);
9202 + len += sizeof(pfixtls_scache_info_t);
9204 + hexdata = (char *)mymalloc(2 * len + 1);
9207 + msg_info("could not allocate memory for SSL session (HEX)");
9208 + myfree((char *)data);
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)];
9216 + hexdata[len * 2] = '\0';
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
9225 + if (strlen(idstring) + strlen(hexdata) < 8000)
9226 + dict_put(scache_db, idstring, hexdata);
9229 + myfree((char *)data);
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.
9248 +static void save_clnt_session(SSL_SESSION *session, const char *hostname)
9256 + unsigned char *data, *sess_data;
9257 + pfixtls_scache_info_t scache_info;
9260 + length = strlen(hostname);
9261 + if (length > id_maxlength)
9262 + uselength = id_maxlength; /* Limit length of ID */
9264 + uselength = length;
9266 + idstring = (char *)mymalloc(uselength + 1);
9268 + msg_info("could not allocate memory for IDstring");
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);
9279 + * Get the session and convert it into some "database" useable form.
9280 + * First, get the length of the session to allocate the memory.
9282 + dsize = i2d_SSL_SESSION(session, NULL);
9284 + msg_info("Could not access session");
9287 + data = (unsigned char *)mymalloc(dsize + sizeof(pfixtls_scache_info_t));
9289 + msg_info("could not allocate memory for SSL session");
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).
9299 + scache_info.scache_db_version = scache_db_version;
9300 + scache_info.openssl_version = openssl_version;
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.)
9307 + scache_info.timestamp = time(NULL);
9309 + memcpy(data, &scache_info, sizeof(pfixtls_scache_info_t));
9310 + sess_data = data + sizeof(pfixtls_scache_info_t);
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.
9318 + len = i2d_SSL_SESSION(session, &sess_data);
9319 + len += sizeof(pfixtls_scache_info_t);
9321 + hexdata = (char *)mymalloc(2 * len + 1);
9324 + msg_info("could not allocate memory for SSL session (HEX)");
9325 + myfree((char *)data);
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)];
9333 + hexdata[len * 2] = '\0';
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
9342 + if (strlen(idstring) + strlen(hexdata) < 8000)
9343 + dict_put(scache_db, idstring, hexdata);
9346 + myfree((char *)data);
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
9356 +static void pfixtls_exchange_seed(void)
9358 + unsigned char buffer[1024];
9360 + if (rand_exch_fd == -1)
9363 + if (myflock(rand_exch_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) != 0)
9364 + msg_info("Could not lock random exchange file: %s",
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);
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");
9377 + if (myflock(rand_exch_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) != 0)
9378 + msg_fatal("Could not unlock random exchange file: %s",
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.
9386 + * The skeleton of this function is taken from OpenSSL apps/s_server.c.
9389 +int pfixtls_init_serverengine(int verifydepth, int askcert)
9392 + int verify_flags = SSL_VERIFY_NONE;
9394 + int rand_source_dev_fd;
9395 + int rand_source_socket_fd;
9396 + unsigned char buffer[255];
9399 + char *s_cert_file;
9401 + char *s_dcert_file;
9402 + char *s_dkey_file;
9405 + if (pfixtls_serverengine)
9406 + return (0); /* already running */
9408 + if (var_smtpd_tls_loglevel >= 2)
9409 + msg_info("starting TLS engine");
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.
9417 + SSL_load_error_strings();
9418 + OpenSSL_add_ssl_algorithms();
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).
9425 +#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
9426 + needs_openssl_095_or_later();
9430 + * Initialize the PRNG Pseudo Random Number Generator with some seed.
9432 + randseed.pid = getpid();
9433 + GETTIMEOFDAY(&randseed.tv);
9434 + RAND_seed(&randseed, sizeof(randseed_t));
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.
9446 + if (*var_tls_daemon_rand_source) {
9447 + if (!strncmp(var_tls_daemon_rand_source, "dev:", 4)) {
9449 + * Source is a random device
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);
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);
9462 + } else if (!strncmp(var_tls_daemon_rand_source, "egd:", 4)) {
9464 + * Source is a EGD compatible socket
9466 + rand_source_socket_fd = unix_connect(var_tls_daemon_rand_source +4,
9468 + if (rand_source_socket_fd == -1)
9469 + msg_info("Could not connect to %s", var_tls_daemon_rand_source);
9471 + if (var_tls_daemon_rand_bytes > 255)
9472 + var_tls_daemon_rand_bytes = 255;
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);
9482 + rand_bytes = buffer[0];
9483 + read(rand_source_socket_fd, buffer, rand_bytes);
9484 + RAND_seed(buffer, rand_bytes);
9486 + close(rand_source_socket_fd);
9489 + RAND_load_file(var_tls_daemon_rand_source,
9490 + var_tls_daemon_rand_bytes);
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();
9500 + randseed.pid = getpid();
9501 + GETTIMEOFDAY(&randseed.tv);
9502 + RAND_seed(&randseed, sizeof(randseed_t));
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.
9514 + ctx = SSL_CTX_new(SSLv23_server_method());
9515 + if (ctx == NULL) {
9516 + pfixtls_print_errors();
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.
9526 + off |= SSL_OP_ALL; /* Work around all known bugs */
9527 + SSL_CTX_set_options(ctx, off);
9530 + * Set the info_callback, that will print out messages during
9531 + * communication on demand.
9533 + if (var_smtpd_tls_loglevel >= 2)
9534 + SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
9537 + * Set the list of ciphers, if explicitely given; otherwise the
9538 + * (reasonable) default list is kept.
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();
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.
9560 + if (strlen(var_smtpd_tls_CAfile) == 0)
9563 + CAfile = var_smtpd_tls_CAfile;
9564 + if (strlen(var_smtpd_tls_CApath) == 0)
9567 + CApath = var_smtpd_tls_CApath;
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();
9575 + if (!SSL_CTX_set_default_verify_paths(ctx)) {
9576 + msg_info("TLS engine: cannot set verify paths");
9577 + pfixtls_print_errors();
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.
9596 + if (strlen(var_smtpd_tls_cert_file) == 0)
9597 + s_cert_file = NULL;
9599 + s_cert_file = var_smtpd_tls_cert_file;
9600 + if (strlen(var_smtpd_tls_key_file) == 0)
9601 + s_key_file = NULL;
9603 + s_key_file = var_smtpd_tls_key_file;
9605 + if (strlen(var_smtpd_tls_dcert_file) == 0)
9606 + s_dcert_file = NULL;
9608 + s_dcert_file = var_smtpd_tls_dcert_file;
9609 + if (strlen(var_smtpd_tls_dkey_file) == 0)
9610 + s_dkey_file = NULL;
9612 + s_dkey_file = var_smtpd_tls_dkey_file;
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();
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();
9628 + if (!s_cert_file && !s_dcert_file) {
9629 + msg_info("TLS engine: do need at least RSA _or_ DSA cert/key data");
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
9639 + SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb);
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.
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();
9659 + msg_info("TLS engine: cannot load 1024bit DH parameters: %s: %s",
9660 + var_smtpd_tls_dh1024_param_file, strerror(errno));
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();
9672 + msg_info("TLS engine: cannot load 512bit DH parameters: %s: %s",
9673 + var_smtpd_tls_dh512_param_file, strerror(errno));
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
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.
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));
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.
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".
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));
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.
9725 + if (*var_smtpd_tls_scache_db) {
9727 + * Insert a test against other dbms here, otherwise while writing
9728 + * a session (content to large), we will receive a fatal error!
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);
9734 + scache_db = dict_open(var_smtpd_tls_scache_db, O_RDWR,
9735 + DICT_FLAG_DUP_REPLACE | DICT_FLAG_LOCK | DICT_FLAG_SYNC_UPDATE);
9737 + SSL_CTX_sess_set_get_cb(ctx, get_session_cb);
9738 + SSL_CTX_sess_set_new_cb(ctx, new_session_cb);
9741 + msg_warn("Could not open session cache %s",
9742 + var_smtpd_tls_scache_db);
9746 + * Finally create the global index to access TLScontext information
9747 + * inside verify_callback.
9749 + TLScontext_index = SSL_get_ex_new_index(0, "TLScontext ex_data index",
9750 + NULL, NULL, NULL);
9752 + pfixtls_serverengine = 1;
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.
9762 +int pfixtls_start_servertls(VSTREAM *stream, int timeout,
9763 + const char *peername, const char *peeraddr,
9764 + tls_info_t *tls_info, int requirecert)
9770 + TLScontext_t *TLScontext;
9771 + SSL_SESSION *session;
9772 + SSL_CIPHER *cipher;
9775 + if (!pfixtls_serverengine) { /* should never happen */
9776 + msg_info("tls_engine not running");
9779 + if (var_smtpd_tls_loglevel >= 1)
9780 + msg_info("setting up TLS connection from %s[%s]", peername, peeraddr);
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().
9787 + TLScontext = (TLScontext_t *)mymalloc(sizeof(TLScontext_t));
9788 + if (!TLScontext) {
9789 + msg_fatal("Could not allocate 'TLScontext' with mymalloc");
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);
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);
9806 + * Set the verification parameters to be checked in verify_callback().
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);
9815 + TLScontext->enforce_verify_errors = 0;
9817 + TLScontext->enforce_CN = 0;
9820 + * The TLS connection is realized by a BIO_pair, so obtain the pair.
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);
9832 + * Before really starting anything, try to seed the PRNG a little bit
9835 + pfixtls_stir_seed();
9836 + pfixtls_exchange_seed();
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.
9843 + SSL_set_accept_state(TLScontext->con);
9846 + * Connect the SSL-connection with the postfix side of the BIO-pair for
9847 + * reading and writing.
9849 + SSL_set_bio(TLScontext->con, TLScontext->internal_bio,
9850 + TLScontext->internal_bio);
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.
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.
9860 + if (var_smtpd_tls_loglevel >= 3)
9861 + BIO_set_callback(SSL_get_rbio(TLScontext->con), bio_dump_cb);
9864 + /* Dump the negotiation for loglevels 3 and 4 */
9865 + if (var_smtpd_tls_loglevel >= 3)
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
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.
9880 + sts = do_tls_operation(vstream_fileno(stream), timeout, TLScontext,
9881 + SSL_accept, NULL, NULL, NULL, 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");
9893 + SSL_free(TLScontext->con);
9894 + myfree((char *)TLScontext);
9898 + /* Only loglevel==4 dumps everything */
9899 + if (var_smtpd_tls_loglevel < 4)
9903 + * Lets see, whether a peer certificate is available and what is
9904 + * the actual information. We want to save it for later use.
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;
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] = ':';
9930 + TLScontext->fingerprint[(j * 3) + 2] = '\0';
9932 + if (var_smtpd_tls_loglevel >= 1)
9933 + msg_info("fingerprint=%s", TLScontext->fingerprint);
9934 + tls_info->peer_fingerprint = TLScontext->fingerprint;
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);
9946 + msg_info("Unverified: subject_CN=%s, issuer_CN=%s",
9947 + TLScontext->peer_CN, TLScontext->issuer_CN);
9949 + tls_info->issuer_CN = TLScontext->issuer_CN;
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.
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);
9969 + * Finally, collect information about protocol and cipher for logging
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));
9977 + pfixtls_serveractive = 1;
9980 + * The TLS engine is active, switch to the pfixtls_timed_read/write()
9981 + * functions and store the context.
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,
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();
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
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
10010 +int pfixtls_stop_servertls(VSTREAM *stream, int timeout, int failure,
10011 + tls_info_t *tls_info)
10013 + SSL_SESSION *session;
10014 + TLScontext_t *TLScontext;
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);
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");
10028 + SSL_CTX_remove_session(ctx, session);
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.
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));
10046 + pfixtls_stir_seed();
10047 + pfixtls_exchange_seed();
10049 + *tls_info = tls_info_zero;
10050 + pfixtls_serveractive = 0;
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.
10062 + * The skeleton of this function is taken from OpenSSL apps/s_client.c.
10065 +int pfixtls_init_clientengine(int verifydepth)
10068 + int verify_flags = SSL_VERIFY_NONE;
10070 + int rand_source_dev_fd;
10071 + int rand_source_socket_fd;
10072 + unsigned char buffer[255];
10075 + char *c_cert_file;
10076 + char *c_key_file;
10079 + if (pfixtls_clientengine)
10080 + return (0); /* already running */
10082 + if (var_smtp_tls_loglevel >= 2)
10083 + msg_info("starting TLS engine");
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.
10091 + SSL_load_error_strings();
10092 + OpenSSL_add_ssl_algorithms();
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).
10099 +#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
10100 + needs_openssl_095_or_later();
10104 + * Initialize the PRNG Pseudo Random Number Generator with some seed.
10106 + randseed.pid = getpid();
10107 + GETTIMEOFDAY(&randseed.tv);
10108 + RAND_seed(&randseed, sizeof(randseed_t));
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.
10120 + if (*var_tls_daemon_rand_source) {
10121 + if (!strncmp(var_tls_daemon_rand_source, "dev:", 4)) {
10123 + * Source is a random device
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);
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);
10136 + } else if (!strncmp(var_tls_daemon_rand_source, "egd:", 4)) {
10138 + * Source is a EGD compatible socket
10140 + rand_source_socket_fd = unix_connect(var_tls_daemon_rand_source +4,
10142 + if (rand_source_socket_fd == -1)
10143 + msg_info("Could not connect to %s", var_tls_daemon_rand_source);
10145 + if (var_tls_daemon_rand_bytes > 255)
10146 + var_tls_daemon_rand_bytes = 255;
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);
10156 + rand_bytes = buffer[0];
10157 + read(rand_source_socket_fd, buffer, rand_bytes);
10158 + RAND_seed(buffer, rand_bytes);
10160 + close(rand_source_socket_fd);
10163 + RAND_load_file(var_tls_daemon_rand_source,
10164 + var_tls_daemon_rand_bytes);
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();
10174 + randseed.pid = getpid();
10175 + GETTIMEOFDAY(&randseed.tv);
10176 + RAND_seed(&randseed, sizeof(randseed_t));
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.
10187 + ctx = SSL_CTX_new(SSLv23_client_method());
10188 + if (ctx == NULL) {
10189 + pfixtls_print_errors();
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.
10199 + off |= SSL_OP_ALL; /* Work around all known bugs */
10200 + SSL_CTX_set_options(ctx, off);
10203 + * Set the info_callback, that will print out messages during
10204 + * communication on demand.
10206 + if (var_smtp_tls_loglevel >= 2)
10207 + SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
10210 + * Set the list of ciphers, if explicitely given; otherwise the
10211 + * (reasonable) default list is kept.
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();
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.
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.
10240 + if (strlen(var_smtp_tls_CAfile) == 0)
10243 + CAfile = var_smtp_tls_CAfile;
10244 + if (strlen(var_smtp_tls_CApath) == 0)
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();
10254 + if (!SSL_CTX_set_default_verify_paths(ctx)) {
10255 + msg_info("TLS engine: cannot set verify paths");
10256 + pfixtls_print_errors();
10261 + if (strlen(var_smtp_tls_cert_file) == 0)
10262 + c_cert_file = NULL;
10264 + c_cert_file = var_smtp_tls_cert_file;
10265 + if (strlen(var_smtp_tls_key_file) == 0)
10266 + c_key_file = NULL;
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();
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
10282 + SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb);
10285 + * Finally, the setup for the server certificate checking, done
10288 + SSL_CTX_set_verify(ctx, verify_flags, verify_callback);
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.
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.
10298 + SSL_CTX_sess_set_cache_size(ctx, 1);
10299 + SSL_CTX_set_timeout(ctx, var_smtp_tls_scache_timeout);
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.
10307 + if (*var_smtp_tls_scache_db) {
10309 + * Insert a test against other dbms here, otherwise while writing
10310 + * a session (content to large), we will receive a fatal error!
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);
10316 + scache_db = dict_open(var_smtp_tls_scache_db, O_RDWR,
10317 + DICT_FLAG_DUP_REPLACE | DICT_FLAG_LOCK | DICT_FLAG_SYNC_UPDATE);
10319 + msg_warn("Could not open session cache %s",
10320 + var_smtp_tls_scache_db);
10324 + * Finally create the global index to access TLScontext information
10325 + * inside verify_callback.
10327 + TLScontext_index = SSL_get_ex_new_index(0, "TLScontext ex_data index",
10328 + NULL, NULL, NULL);
10330 + pfixtls_clientengine = 1;
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.
10340 +int pfixtls_start_clienttls(VSTREAM *stream, int timeout,
10341 + int enforce_peername,
10342 + const char *peername,
10343 + tls_info_t *tls_info)
10348 + SSL_SESSION *session, *old_session;
10349 + SSL_CIPHER *cipher;
10351 + int save_session;
10353 + int verify_flags;
10354 + char *lowercase_CN;
10355 + unsigned char *old_session_id;
10356 + TLScontext_t *TLScontext;
10358 + if (!pfixtls_clientengine) { /* should never happen */
10359 + msg_info("tls_engine not running");
10362 + if (var_smtpd_tls_loglevel >= 1)
10363 + msg_info("setting up TLS connection to %s", peername);
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().
10370 + TLScontext = (TLScontext_t *)mymalloc(sizeof(TLScontext_t));
10371 + if (!TLScontext) {
10372 + msg_fatal("Could not allocate 'TLScontext' with mymalloc");
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);
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);
10389 + * Set the verification parameters to be checked in verify_callback().
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);
10398 + TLScontext->enforce_verify_errors = 0;
10399 + TLScontext->enforce_CN = 0;
10403 + * The TLS connection is realized by a BIO_pair, so obtain the pair.
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);
10414 + old_session_id = NULL; /* make sure no old info is kept */
10415 + old_session = NULL;
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.
10423 + strncpy(TLScontext->peername_save, peername, 128);
10424 + TLScontext->peername_save[128] = '\0'; /* in case name is too long */
10426 + old_session = load_clnt_session(peername);
10427 + if (old_session) {
10428 + SSL_set_session(TLScontext->con, old_session);
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)
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.
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.
10444 + SSL_set_verify_result(TLScontext->con, old_session->verify_result);
10451 + * Before really starting anything, try to seed the PRNG a little bit
10454 + pfixtls_stir_seed();
10455 + pfixtls_exchange_seed();
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.
10462 + SSL_set_connect_state(TLScontext->con);
10465 + * Connect the SSL-connection with the postfix side of the BIO-pair for
10466 + * reading and writing.
10468 + SSL_set_bio(TLScontext->con, TLScontext->internal_bio,
10469 + TLScontext->internal_bio);
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.
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.
10479 + if (var_smtp_tls_loglevel >= 3)
10480 + BIO_set_callback(SSL_get_rbio(TLScontext->con), bio_dump_cb);
10483 + /* Dump the negotiation for loglevels 3 and 4 */
10484 + if (var_smtp_tls_loglevel >= 3)
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.
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.
10498 + sts = do_tls_operation(vstream_fileno(stream), timeout, TLScontext,
10499 + SSL_connect, NULL, NULL, NULL, 0);
10501 + msg_info("SSL_connect error to %s: %d", peername, sts);
10502 + pfixtls_print_errors();
10503 + session = SSL_get_session(TLScontext->con);
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");
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);
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.
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;
10532 + myfree((char *)old_session_id);
10534 + if (save_session) {
10535 +#if (OPENSSL_VERSION_NUMBER < 0x00906011L) || (OPENSSL_VERSION_NUMBER == 0x00907000L)
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.
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.
10547 + session->verify_result = SSL_get_verify_result(TLScontext->con);
10549 + save_clnt_session(session, peername);
10552 + if ((old_session) && (session != old_session))
10553 + SSL_SESSION_free(old_session); /* Remove unused session */
10555 + /* Only loglevel==4 dumps everything */
10556 + if (var_smtp_tls_loglevel < 4)
10560 + * Lets see, whether a peer certificate is available and what is
10561 + * the actual information. We want to save it for later use.
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;
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);
10578 + msg_info("Unverified: subject_CN=%s, issuer_CN=%s",
10579 + TLScontext->peer_CN, TLScontext->issuer_CN);
10581 + tls_info->issuer_CN = TLScontext->issuer_CN;
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.
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);
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);
10604 + myfree(lowercase_CN);
10608 + * Finally, collect information about protocol and cipher for logging
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));
10616 + pfixtls_clientactive = 1;
10619 + * The TLS engine is active, switch to the pfixtls_timed_read/write()
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);
10628 + msg_info("TLS connection established to %s: %s with cipher %s (%d/%d bits)",
10630 + tls_info->protocol, tls_info->cipher_name,
10631 + tls_info->cipher_usebits, tls_info->cipher_algbits);
10633 + pfixtls_stir_seed();
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
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
10650 +int pfixtls_stop_clienttls(VSTREAM *stream, int timeout, int failure,
10651 + tls_info_t *tls_info)
10653 + SSL_SESSION *session;
10654 + TLScontext_t *TLScontext;
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);
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");
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.
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));
10684 + pfixtls_stir_seed();
10685 + pfixtls_exchange_seed();
10687 + *tls_info = tls_info_zero;
10688 + pfixtls_clientactive = 0;
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
10707 +/* include "pfixtls.h"
10712 +#ifndef PFIXTLS_H_INCLUDED
10713 +#define PFIXTLS_H_INCLUDED
10716 + int peer_verified;
10717 + char *peer_subject;
10718 + char *peer_issuer;
10719 + char *peer_fingerprint;
10723 + const char *protocol;
10724 + const char *cipher_name;
10725 + int cipher_usebits;
10726 + int cipher_algbits;
10729 +extern const tls_info_t tls_info_zero;
10734 + long scache_db_version;
10735 + long openssl_version;
10736 + time_t timestamp; /* We could add other info here... */
10737 +} pfixtls_scache_info_t;
10739 +extern const long scache_db_version;
10740 +extern const long openssl_version;
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);
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);
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);
10764 +#endif /* PFIXTLS_H_INCLUDED */
10773 +/* Allgemeine Elektrotechnik
10774 +/* Universitaetsplatz 3-4
10775 +/* D-03044 Cottbus, Germany
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
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
10786 smtp.o: smtp_sasl.h
10787 smtp_addr.o: smtp_addr.c
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>
10863 /* Single server skeleton. */
10865 @@ -227,6 +228,7 @@
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;
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);
10891 + * Initialize the TLS data before entering the chroot jail
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();
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,
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,
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,
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,
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
10939 #include <deliver_request.h>
10940 +#include <pfixtls.h>
10943 * State information associated with each SMTP delivery. We're bundling the
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 */
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 *);
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 @@
10965 #include <mail_params.h>
10966 #include <own_inet_addr.h>
10967 +#include <pfixtls.h>
10971 @@ -128,7 +129,7 @@
10973 /* smtp_connect_addr - connect to explicit address */
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,
10979 char *myname = "smtp_connect_addr";
10980 @@ -262,7 +263,7 @@
10981 vstream_fclose(stream);
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)));
10988 /* smtp_connect_host - direct connection to host */
10989 @@ -280,7 +281,7 @@
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) {
10998 @@ -309,7 +310,7 @@
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);
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
11011 #include <off_cvt.h>
11012 #include <mark_corrupt.h>
11013 #include <quote_821_local.h>
11014 +#include <pfixtls.h>
11016 /* Application-specific. */
11018 @@ -153,6 +154,8 @@
11026 * Prepare for disaster.
11027 @@ -206,7 +209,8 @@
11029 translit(resp->str, "\n", " ")));
11032 + if (var_smtp_always_ehlo)
11033 + state->features |= SMTP_FEATURE_ESMTP;
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.
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 @@
11056 msg_info("server features: 0x%x", state->features);
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))
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
11073 + return (smtp_site_fail(state, 450, "Could not start TLS: not offered"));
11075 + if ((session->tls_enforce_tls) && !pfixtls_clientengine) {
11077 + * We would like to start client TLS, but our own TLS-engine is
11080 + return (smtp_site_fail(state, 450,
11081 + "Could not start TLS: our TLS-engine not running"));
11083 + if ((state->features & SMTP_FEATURE_STARTTLS) &&
11084 + ((session->tls_use_tls && pfixtls_clientengine) ||
11085 + (session->tls_enforce_tls))) {
11087 + * Try to use the TLS feature
11089 + smtp_chat_cmd(state, "STARTTLS");
11090 + if ((resp = smtp_chat_resp(state))->code / 100 != 2) {
11091 + state->features &= ~SMTP_FEATURE_STARTTLS;
11093 + * At this point a political decision is necessary. If we
11094 + * enforce usage of tls, we have to close the connection
11097 + if (session->tls_enforce_tls)
11098 + return (smtp_site_fail(state, resp->code,
11099 + "host %s refused to start TLS: %s",
11101 + translit(resp->str, "\n", " ")));
11103 + if (rval = pfixtls_start_clienttls(session->stream,
11104 + var_smtp_starttls_tmout,
11105 + session->tls_enforce_peername,
11107 + &(session->tls_info)))
11108 + return (smtp_site_fail(state, 450,
11109 + "Could not start TLS: client failure"));
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!
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"));
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,
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"));
11144 + * At this point we have to re-negotiate the "EHLO" to reget
11145 + * the feature-list
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;
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);
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?
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>
11191 +#include <mail_params.h>
11193 +#include <pfixtls.h>
11195 /* Application-specific. */
11200 +/* static lists */
11201 +static MAPS *tls_per_site;
11203 +/* smtp_tls_list_init - initialize lists */
11205 +void smtp_tls_list_init(void)
11207 + tls_per_site = maps_create(VAR_SMTP_TLS_PER_SITE, var_smtp_tls_per_site,
11212 /* smtp_session_alloc - allocate and initialize SMTP_SESSION structure */
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)
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;
11229 session = (SMTP_SESSION *) mymalloc(sizeof(*session));
11230 session->stream = stream;
11232 session->addr = mystrdup(addr);
11233 session->namaddr = concatenate(host, "[", addr, "]", (char *) 0);
11235 + session->tls_use_tls = session->tls_enforce_tls = 0;
11236 + session->tls_enforce_peername = 0;
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"))
11244 + else if (!strcasecmp(lookup, "MUST"))
11245 + host_enforce = host_enforce_peername = 1;
11246 + else if (!strcasecmp(lookup, "MUST_NOPEERMATCH"))
11247 + host_enforce = 1;
11249 + msg_warn("Unknown TLS state for receiving host %s: '%s', using default policy", session->host, lookup);
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;
11263 + msg_warn("Unknown TLS state for recipient domain %s: '%s', using default policy", dest, lookup);
11265 + myfree(lookup_key);
11267 + if ((var_smtp_enforce_tls && !host_dont_use) || host_enforce ||
11268 + recipient_enforce)
11269 + session->tls_enforce_tls = session->tls_use_tls = 1;
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.
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;
11286 + else if ((var_smtp_use_tls && !host_dont_use) || host_use || recipient_use)
11287 + session->tls_use_tls = 1;
11289 + session->tls_info = tls_info_zero;
11293 @@ -65,6 +147,11 @@
11295 void smtp_session_free(SMTP_SESSION *session)
11298 + vstream_fflush(session->stream);
11299 + pfixtls_stop_clienttls(session->stream, var_smtp_starttls_tmout, 0,
11300 + &(session->tls_info));
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
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>
11362 /* Single-threaded server skeleton. */
11364 @@ -307,6 +308,7 @@
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;
11386 * Global state, for stand-alone mode queue file cleanup. When this is
11387 @@ -445,11 +455,21 @@
11389 smtpd_chat_reply(state, "250-SIZE");
11390 smtpd_chat_reply(state, "250-ETRN");
11392 + if ((state->tls_use_tls || state->tls_enforce_tls) && (!state->tls_active))
11393 + smtpd_chat_reply(state, "250-STARTTLS");
11395 #ifdef USE_SASL_AUTH
11396 if (var_smtpd_sasl_enable) {
11398 + if (!state->tls_enforce_tls || state->tls_active) {
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);
11408 smtpd_chat_reply(state, "250 8BITMIME");
11409 @@ -807,11 +827,76 @@
11410 state->rcpt_count = 0;
11413 +/* CN_sanitize - make sure, the CN-string is well behaved */
11415 +static void CN_sanitize(char *CNstring)
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.
11427 + len = strlen(CNstring);
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.
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] = '?';
11455 + * This information will go into the Received: header inside a comment.
11456 + * Since comments can be nested, parentheses '(' and ')' must match.
11459 + for (i = 0; i < len; i++) {
11460 + if (CNstring[i] == '(')
11462 + else if (CNstring[i] == ')')
11466 + * The necessary condition is violated. Do YOU know, where to correct?
11467 + * I don't know, so I will practically remove all parentheses.
11469 + if (parencount != 0) {
11470 + for (i = 0; i < len; i++)
11471 + if ((CNstring[i] == '(') || (CNstring[i] == ')'))
11472 + CNstring[i] = '/';
11476 /* data_cmd - process DATA command */
11478 static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
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);
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);
11512 + else if (var_smtpd_tls_ask_ccert)
11513 + rec_fprintf(state->cleanup, REC_TYPE_NORM,
11514 + "\t(Client did not present a certificate)");
11516 + rec_fprintf(state->cleanup, REC_TYPE_NORM,
11517 + "\t(No client certificate requested)");
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 @@
11526 +static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
11532 + state->error_mask |= MAIL_ERROR_PROTOCOL;
11533 + smtpd_chat_reply(state, "501 Syntax: STARTTLS");
11536 + if (state->tls_active != 0) {
11537 + state->error_mask |= MAIL_ERROR_PROTOCOL;
11538 + smtpd_chat_reply(state, "554 Error: TLS already active");
11541 + if (state->tls_use_tls == 0) {
11542 + state->error_mask |= MAIL_ERROR_PROTOCOL;
11543 + smtpd_chat_reply(state, "502 Error: command not implemented");
11546 + if (!pfixtls_serverengine) {
11547 + smtpd_chat_reply(state, "454 TLS not available due to temporary reason");
11550 + smtpd_chat_reply(state, "220 Ready to start TLS");
11551 + vstream_fflush(state->client);
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.
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))) {
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!
11570 + state->tls_active = 1;
11571 + helo_reset(state);
11572 + mail_reset(state);
11573 + rcpt_reset(state);
11576 + state->error_mask |= MAIL_ERROR_PROTOCOL;
11577 + smtpd_chat_reply(state, "502 Error: command not implemented");
11582 +static void tls_reset(SMTPD_STATE *state)
11586 + if (state->reason && state->where && strcmp(state->where, SMTPD_AFTER_DOT))
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));
11594 + state->tls_active = 0;
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,
11605 + "STARTTLS", starttls_cmd, 0,
11608 #ifdef USE_SASL_AUTH
11609 "AUTH", smtpd_sasl_auth_cmd, 0,
11611 @@ -1250,9 +1439,28 @@
11612 state->error_count++;
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++;
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++;
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.
11635 + if (cmdp->action == starttls_cmd)
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
11645 + tls_reset(state);
11647 #ifdef USE_SASL_AUTH
11648 if (var_smtpd_sasl_enable)
11649 @@ -1321,6 +1530,36 @@
11652 smtpd_state_init(&state, stream);
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) {
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.
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)) {
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!
11673 + state.tls_active = 1;
11676 + state.tls_use_tls = 0;
11677 + state.tls_enforce_tls = 0;
11681 + * Provide the SMTP service.
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);
11692 - * Provide the SMTP service.
11694 smtpd_proto(&state);
11697 @@ -1408,7 +1643,6 @@
11699 static void pre_jail_init(char *unused_name, char **unused_argv)
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);
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);
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,
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,
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,
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,
11752 @@ -1501,3 +1750,4 @@
11753 MAIL_SERVER_PRE_ACCEPT, pre_accept,
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
11763 #include <mail_stream.h>
11764 +#include <pfixtls.h>
11767 * Variables that keep track of conversation state. There is only one SMTP
11769 VSTRING *sasl_encoded;
11770 VSTRING *sasl_decoded;
11774 + int tls_enforce_tls;
11775 + tls_info_t tls_info;
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 @@
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 @@
11792 static DOMAIN_LIST *relay_domains;
11793 static NAMADR_LIST *mynetworks;
11795 +static MAPS *relay_ccerts;
11799 * Pre-parsed restriction lists.
11800 @@ -445,6 +449,10 @@
11802 mynetworks = namadr_list_init(var_mynetworks);
11803 relay_domains = domain_list_init(var_relay_domains);
11805 + relay_ccerts = maps_create(VAR_RELAY_CCERTS, var_relay_ccerts,
11810 * Pre-parse and pre-open the recipient maps.
11811 @@ -771,6 +779,36 @@
11813 static int permit_auth_destination(char *recipient);
11815 +/* permit_tls_clientcerts - OK/DUNNO for message relaying */
11818 +static int permit_tls_clientcerts(SMTPD_STATE *state, int permit_all_certs)
11821 + const char *found;
11823 + if (state->tls_info.peer_verified && permit_all_certs) {
11825 + msg_info("Relaying allowed for all verified client certificates");
11826 + return(SMTPD_CHECK_OK);
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);
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);
11841 + return (SMTPD_CHECK_DUNNO);
11845 /* check_relay_domains - OK/FAIL for message relaying */
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);
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);
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 = "";
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
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;
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
11892 +WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
11893 + -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
11895 +DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
11896 +CFLAGS = $(DEBUG) $(OPT) $(DEFS)
11899 +INC_DIR = ../../include
11900 +LIBS = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libutil.a
11902 +.c.o:; $(CC) $(CFLAGS) -c $*.c
11904 +$(PROG): $(OBJS) $(LIBS)
11905 + $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
11907 +Makefile: Makefile.in
11908 + (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs; cat $?) >$@
11912 +update: ../../libexec/$(PROG)
11914 +../../libexec/$(PROG): $(PROG)
11915 + cp $(PROG) ../../libexec
11917 +printfck: $(OBJS) $(PROG)
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`
11926 + lint $(DEFS) $(SRCS) $(LINTFIX)
11929 + rm -f *.o *core $(PROG) $(TESTPROG) junk
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
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
11970 +/* Postfix TLS session cache and PRNG handling manager
11972 +/* \fBtlsmgr\fR [generic Postfix daemon options]
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.
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.
11987 +/* Tlsmgr can be run chrooted and with dropped privileges, as it will
11988 +/* connect to the entropy source at startup.
11990 +/* The PRNG is additionally seeded internally by the data found in the
11991 +/* session cache and timevalues.
11993 +/* Tlsmgr reads the old value of the exchange file at startup to keep
11994 +/* entropy already collected during previous runs.
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].
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.
12009 +/* Problems and transactions are logged to the syslog daemon.
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
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
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
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).
12067 +/* smtp(8) SMTP client
12068 +/* smtpd(8) SMTP server
12072 +/* The Secure Mailer license must be distributed with this software.
12076 +/* System library. */
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 */
12086 +/* OpenSSL library. */
12088 +#include <openssl/rand.h> /* For the PRNG */
12091 +/* Utility library. */
12094 +#include <events.h>
12096 +#include <stringops.h>
12097 +#include <mymalloc.h>
12098 +#include <connect.h>
12099 +#include <myflock.h>
12101 +/* Global library. */
12103 +#include <mail_conf.h>
12104 +#include <mail_params.h>
12105 +#include <pfixtls.h>
12107 +/* Master process interface */
12109 +#include <master_proto.h>
12110 +#include <mail_server.h>
12112 +/* Application-specific. */
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;
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;
12130 +static void tlsmgr_prng_upd_event(int unused_event, char *dummy)
12132 + struct timeval tv;
12133 + unsigned char buffer[1024];
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.
12141 + GETTIMEOFDAY(&tv);
12142 + RAND_seed(&tv, sizeof(struct timeval));
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));
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);
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");
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));
12163 + * Make prediction difficult for outsiders and calculate the time for the
12164 + * next execution randomly.
12166 + next_period = (var_tls_prng_upd_period * buffer[0]) / 255;
12167 + event_request_timer(tlsmgr_prng_upd_event, dummy, next_period);
12172 +static void tlsmgr_reseed_event(int unused_event, char *dummy)
12177 + char buffer[255];
12178 + struct timeval tv;
12179 + unsigned char randbyte;
12183 + * It is time to reseed the PRNG.
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);
12196 + } else if (rand_source_socket_fd != -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);
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);
12210 + RAND_seed(buffer, rand_bytes);
12213 + if (!egd_success) {
12214 + msg_info("Lost connection to EGD-device, exiting to reconnect.");
12217 + } else if (*var_tls_rand_source) {
12218 + rand_bytes = RAND_load_file(var_tls_rand_source, var_tls_rand_bytes);
12222 + * Make prediction difficult for outsiders and calculate the time for the
12223 + * next execution randomly.
12225 + RAND_bytes(&randbyte, 1);
12226 + next_period = (var_tls_reseed_period * randbyte) / 255;
12227 + event_request_timer(tlsmgr_reseed_event, dummy, next_period);
12232 +static int tlsmgr_do_scache_check(DICT *scache_db, int scache_timeout,
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;
12248 + GETTIMEOFDAY(&tv);
12249 + RAND_seed(&tv, sizeof(struct timeval));
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.
12257 + func = DICT_SEQ_FUN_FIRST;
12259 + func = DICT_SEQ_FUN_NEXT;
12260 + result = dict_seq(scache_db, func, &member, &value);
12263 + return 0; /* End of list reached */
12264 + else if (result < 0)
12265 + msg_fatal("Database fault, should already be caught.");
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);
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';
12281 + nibble = value[n] - 'A' + 10;
12283 + data[n / 2] |= nibble;
12285 + data[n / 2] |= (nibble << 4);
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)))
12294 + result = dict_del(scache_db, member_copy);
12295 + myfree(member_copy);
12298 + if (delete && result)
12299 + msg_info("Could not delete %s", member);
12307 +static void tlsmgr_clnt_cache_run_event(int unused_event, char *dummy)
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.
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);
12321 +static void tlsmgr_srvr_cache_run_event(int unused_event, char *dummy)
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.
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);
12335 +static DICT *tlsmgr_cache_open(const char *dbname)
12342 + * First, try to find out the real name of the database file, so that
12343 + * it can be removed.
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);
12354 + msg_warn("Only type sdbm: supported: %s", dbname);
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
12363 + retval = dict_open(dbname, O_RDWR | O_CREAT | O_EXCL,
12364 + DICT_FLAG_DUP_REPLACE | DICT_FLAG_LOCK | DICT_FLAG_SYNC_UPDATE);
12366 + msg_warn("Could not create dictionary %s", dbname);
12370 +/* tlsmgr_trigger_event - respond to external trigger(s) */
12372 +static void tlsmgr_trigger_event(char *buf, int len,
12373 + char *unused_service, char **argv)
12376 + * Sanity check. This service takes no command-line arguments.
12379 + msg_fatal("unexpected command-line argument: %s", argv[0]);
12383 +/* tlsmgr_loop - queue manager main loop */
12385 +static int tlsmgr_loop(char *unused_name, char **unused_argv)
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.
12394 +#define DONT_WAIT 0
12395 +#define WAIT_FOR_EVENT (-1)
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);
12408 +/* pre_accept - see if tables have changed */
12410 +static void pre_accept(char *unused_name, char **unused_argv)
12412 + if (dict_changed()) {
12413 + msg_info("table has changed -- exiting");
12418 +/* tlsmgr_pre_init - pre-jail initialization */
12420 +static void tlsmgr_pre_init(char *unused_name, char **unused_argv)
12423 + unsigned char buffer[255];
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.
12431 + if (*var_tls_rand_source) {
12432 + if (!strncmp(var_tls_rand_source, "dev:", 4)) {
12434 + * Source is a random device
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)) {
12446 + * Source is a EGD compatible socket
12448 + rand_source_socket_fd = unix_connect(var_tls_rand_source +4,
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;
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);
12465 + rand_bytes = RAND_load_file(var_tls_rand_source,
12466 + var_tls_rand_bytes);
12472 + * Now open the PRNG exchange file
12474 + if (*var_tls_rand_exch_name) {
12475 + rand_exch_fd = open(var_tls_rand_exch_name, O_RDWR | O_CREAT, 0600);
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!!
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);
12489 +/* qmgr_post_init - post-jail initialization */
12491 +static void tlsmgr_post_init(char *unused_name, char **unused_argv)
12493 + unsigned char buffer[1024];
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.
12500 + var_use_limit = 0;
12501 + var_idle_limit = 0;
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.
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);
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);
12531 +/* main - the main program */
12533 +int main(int argc, char **argv)
12535 + static CONFIG_STR_TABLE str_table[] = {
12536 + VAR_TLS_RAND_SOURCE, DEF_TLS_RAND_SOURCE, &var_tls_rand_source, 0, 0,
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,
12544 + static CONFIG_INT_TABLE int_table[] = {
12545 + VAR_TLS_RAND_BYTES, DEF_TLS_RAND_BYTES, &var_tls_rand_bytes, 0, 0,
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.
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,
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
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 \
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 \
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
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 @@
12625 DICT_TYPE_TCP, dict_tcp_open,
12627 + "sdbm", dict_sdbm_open,
12629 DICT_TYPE_DBM, dict_dbm_open,
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
12639 +/* dictionary manager interface to SDBM files
12641 +/* #include <dict_sdbm.h>
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;
12649 +/* dict_sdbm_open() opens the named SDBM database and makes it available
12650 +/* via the generic interface described in dict_open(3).
12652 +/* Fatal errors: cannot open file, file write error, out of memory.
12654 +/* dict(3) generic dictionary manager
12655 +/* sdbm(3) data base subroutines
12659 +/* The Secure Mailer license must be distributed with this software.
12662 +/* IBM T.J. Watson Research
12664 +/* Yorktown Heights, NY 10598, USA
12667 +#include "sys_defs.h"
12669 +/* System library. */
12671 +#include <sys/stat.h>
12672 +#include <string.h>
12673 +#include <unistd.h>
12675 +/* Utility library. */
12678 +#include "mymalloc.h"
12679 +#include "htable.h"
12680 +#include "iostuff.h"
12681 +#include "vstring.h"
12682 +#include "myflock.h"
12683 +#include "stringops.h"
12685 +#include "dict_sdbm.h"
12688 +/* Application-specific. */
12691 + DICT dict; /* generic members */
12692 + SDBM *dbm; /* open database */
12693 + char *path; /* pathname */
12696 +/* dict_sdbm_lookup - find database entry */
12698 +static const char *dict_sdbm_lookup(DICT *dict, const char *name)
12700 + DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
12703 + static VSTRING *buf;
12704 + const char *result = 0;
12709 + * Acquire an exclusive lock.
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);
12716 + * See if this DBM file was written with one null byte appended to key
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;
12730 + * See if this DBM file was written with no null byte appended to key and
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) {
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);
12747 + * Release the exclusive lock.
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);
12756 +/* dict_sdbm_update - add or update database entry */
12758 +static void dict_sdbm_update(DICT *dict, const char *name, const char *value)
12760 + DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
12765 + dbm_key.dptr = (void *) name;
12766 + dbm_value.dptr = (void *) value;
12767 + dbm_key.dsize = strlen(name);
12768 + dbm_value.dsize = strlen(value);
12771 + * If undecided about appending a null byte to key and value, choose a
12772 + * default depending on the platform.
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;
12779 + dict->flags &= ~DICT_FLAG_TRY0NULL;
12784 + * Optionally append a null byte to key and value.
12786 + if (dict->flags & DICT_FLAG_TRY1NULL) {
12788 + dbm_value.dsize++;
12792 + * Acquire an exclusive lock.
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);
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);
12805 + if (dict->flags & DICT_FLAG_DUP_IGNORE)
12807 + else if (dict->flags & DICT_FLAG_DUP_WARN)
12808 + msg_warn("%s: duplicate entry: \"%s\"", dict_sdbm->path, name);
12810 + msg_fatal("%s: duplicate entry: \"%s\"", dict_sdbm->path, name);
12814 + * Release the exclusive lock.
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);
12822 +/* dict_sdbm_delete - delete one entry from the dictionary */
12824 +static int dict_sdbm_delete(DICT *dict, const char *name)
12826 + DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
12832 + * Acquire an exclusive lock.
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);
12839 + * See if this DBM file was written with one null byte appended to key
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 */
12851 + dict->flags &= ~DICT_FLAG_TRY0NULL; /* found */
12856 + * See if this DBM file was written with no null byte appended to key and
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 */
12868 + dict->flags &= ~DICT_FLAG_TRY1NULL; /* found */
12873 + * Release the exclusive lock.
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);
12882 +/* traverse the dictionary */
12884 +static int dict_sdbm_sequence(DICT *dict, const int function,
12885 + const char **key, const char **value)
12887 + char *myname = "dict_sdbm_sequence";
12888 + DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
12892 + static VSTRING *key_buf;
12893 + static VSTRING *value_buf;
12896 + * Acquire an exclusive lock.
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);
12903 + * Determine and execute the seek function. It returns the key.
12905 + switch (function) {
12906 + case DICT_SEQ_FUN_FIRST:
12907 + dbm_key = sdbm_firstkey(dict_sdbm->dbm);
12909 + case DICT_SEQ_FUN_NEXT:
12910 + dbm_key = sdbm_nextkey(dict_sdbm->dbm);
12913 + msg_panic("%s: invalid function: %d", myname, function);
12917 + * Release the exclusive lock.
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);
12923 + if (dbm_key.dptr != 0 && dbm_key.dsize > 0) {
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.
12929 + if (((char *) dbm_key.dptr)[dbm_key.dsize - 1] == 0) {
12930 + *key = dbm_key.dptr;
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);
12939 + * Fetch the corresponding value.
12941 + dbm_value = sdbm_fetch(dict_sdbm->dbm, dbm_key);
12943 + if (dbm_value.dptr != 0 && dbm_value.dsize > 0) {
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.
12949 + if (((char *) dbm_value.dptr)[dbm_value.dsize - 1] == 0) {
12950 + *value = dbm_value.dptr;
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);
12960 + * Determine if we have hit the last record or an error
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!) */
12971 + * Determine if we have hit the last record or an error condition.
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 */
12980 +/* dict_sdbm_close - disassociate from data base */
12982 +static void dict_sdbm_close(DICT *dict)
12984 + DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
12986 + sdbm_close(dict_sdbm->dbm);
12987 + myfree(dict_sdbm->path);
12988 + myfree((char *) dict_sdbm);
12991 +/* dict_sdbm_open - open SDBM data base */
12993 +DICT *dict_sdbm_open(const char *path, int open_flags, int dict_flags)
12995 + DICT_SDBM *dict_sdbm;
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);
13010 + * XXX SunOS 5.x has no const in dbm_open() prototype.
13012 + if ((dbm = sdbm_open((char *) path, open_flags, 0644)) == 0)
13013 + msg_fatal("open database %s.{dir,pag}: %m", path);
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);
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);
13040 + return (&dict_sdbm->dict);
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
13046 +#ifndef _DICT_SDBM_H_INCLUDED_
13047 +#define _DICT_SDBM_H_INCLUDED_
13053 +/* dictionary manager interface to DBM files
13055 +/* #include <dict_dbm.h>
13060 + * Utility library.
13065 + * External interface.
13067 +extern DICT *dict_sdbm_open(const char *, int, int);
13072 +/* The Secure Mailer license must be distributed with this software.
13075 +/* IBM T.J. Watson Research
13077 +/* Yorktown Heights, NY 10598, USA
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
13089 +/* SDBM Simple DBM: ndbm work-alike hashed database library
13091 +/* include "sdbm.h"
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.
13105 +#include <stdio.h>
13106 +#include <stdlib.h>
13109 +#include <errno.h>
13111 +#include <unistd.h>
13113 +#include <sys/types.h>
13114 +#include <sys/stat.h>
13115 +#include <fcntl.h>
13116 +#include <errno.h>
13117 +#include <string.h>
13119 +#include <stddef.h>
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)
13131 +#define OFF_PAG(off) (long) (off) * PBLKSIZ
13132 +#define OFF_DIR(off) (long) (off) * DBLKSIZ
13134 +static long masks[] =
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
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 */
13167 +/* ************************* */
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.
13175 + * hashing routine
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.
13185 +static long sdbm_hash (char *str, int len)
13187 + unsigned long n = 0;
13190 +#define HASHC n = *str++ + 65599 * n
13193 + int loop = (len + 8 - 1) >> 3;
13195 + switch (len & (8 - 1))
13222 + n = *str++ + 65599 * n;
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.
13233 +static int chkpage (char *pag)
13237 + short *ino = (short *) pag;
13239 + if ((n = ino[0]) < 0 || n > PBLKSIZ / sizeof (short))
13245 + for (ino++; n > 0; ino += 2)
13247 + if (ino[0] > off || ino[1] > off ||
13258 + * search for the key in the page.
13259 + * return offset index in the range 0 < i < n.
13260 + * return 0 if not found.
13262 +static int seepair (char *pag, int n, char *key, int siz)
13265 + int off = PBLKSIZ;
13266 + short *ino = (short *) pag;
13268 + for (i = 1; i < n; i += 2)
13270 + if (siz == off - ino[i] &&
13271 + memcmp (key, pag + ino[i], siz) == 0)
13273 + off = ino[i + 1];
13279 +static int duppair (char *pag, datum key)
13281 + short *ino = (short *) pag;
13283 + return ino[0] > 0 && seepair (pag, ino[0], key.dptr, key.dsize) > 0;
13288 +/* ************************* */
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.
13296 + * page-level routines
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 + * +--------+----------+----------+
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.
13319 +static int fitpair (char *pag, int need)
13324 + short *ino = (short *) pag;
13326 + off = ((n = ino[0]) > 0) ? ino[n] : PBLKSIZ;
13327 + avail = off - (n + 1) * sizeof (short);
13328 + need += 2 * sizeof (short);
13330 + return need <= avail;
13333 +static void putpair (char *pag, datum key, datum val)
13337 + short *ino = (short *) pag;
13339 + off = ((n = ino[0]) > 0) ? ino[n] : PBLKSIZ;
13341 + * enter the key first
13343 + off -= key.dsize;
13344 + (void) memcpy (pag + off, key.dptr, key.dsize);
13345 + ino[n + 1] = off;
13349 + off -= val.dsize;
13350 + (void) memcpy (pag + off, val.dptr, val.dsize);
13351 + ino[n + 2] = off;
13353 + * adjust item count
13358 +static datum getpair (char *pag, datum key)
13363 + short *ino = (short *) pag;
13365 + if ((n = ino[0]) == 0)
13368 + if ((i = seepair (pag, n, key.dptr, key.dsize)) == 0)
13371 + val.dptr = pag + ino[i + 1];
13372 + val.dsize = ino[i] - ino[i + 1];
13376 +static datum getnkey (char *pag, int num)
13380 + short *ino = (short *) pag;
13382 + num = num * 2 - 1;
13383 + if (ino[0] == 0 || num > ino[0])
13386 + off = (num > 1) ? ino[num - 1] : PBLKSIZ;
13388 + key.dptr = pag + ino[num];
13389 + key.dsize = off - ino[num];
13394 +static int delpair (char *pag, datum key)
13398 + short *ino = (short *) pag;
13400 + if ((n = ino[0]) == 0)
13403 + if ((i = seepair (pag, n, key.dptr, key.dsize)) == 0)
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]
13415 + char *dst = pag + (i == 1 ? PBLKSIZ : ino[i - 1]);
13416 + char *src = pag + ino[i + 1];
13417 + int zoo = dst - src;
13420 + * shift data/keys down
13422 + m = ino[i + 1] - ino[n];
13424 +#define MOVB *--dst = *--src
13427 + int loop = (m + 8 - 1) >> 3;
13429 + switch (m & (8 - 1))
13456 + memmove (dst, src, m);
13459 + * adjust offset index up
13461 + while (i < n - 1)
13463 + ino[i] = ino[i + 2] + zoo;
13471 +static void splpage (char *pag, char *new, long sbit)
13477 + int off = PBLKSIZ;
13478 + char cur[PBLKSIZ];
13479 + short *ino = (short *) cur;
13481 + (void) memcpy (cur, pag, PBLKSIZ);
13482 + (void) memset (pag, 0, PBLKSIZ);
13483 + (void) memset (new, 0, PBLKSIZ);
13486 + for (ino++; n > 0; ino += 2)
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];
13493 + * select the page pointer (by looking at sbit) and insert
13495 + (void) putpair ((exhash (key) & sbit) ? new : pag, key, val);
13502 +static int getdbit (DBM * db, long dbit)
13507 + c = dbit / BYTESIZ;
13508 + dirb = c / DBLKSIZ;
13510 + if (dirb != db->dirbno)
13512 + if (lseek (db->dirf, OFF_DIR (dirb), SEEK_SET) < 0
13513 + || read (db->dirf, db->dirbuf, DBLKSIZ) < 0)
13515 + db->dirbno = dirb;
13518 + return db->dirbuf[c % DBLKSIZ] & (1 << dbit % BYTESIZ);
13521 +static int setdbit (DBM * db, long dbit)
13526 + c = dbit / BYTESIZ;
13527 + dirb = c / DBLKSIZ;
13529 + if (dirb != db->dirbno)
13531 + if (lseek (db->dirf, OFF_DIR (dirb), SEEK_SET) < 0
13532 + || read (db->dirf, db->dirbuf, DBLKSIZ) < 0)
13534 + db->dirbno = dirb;
13537 + db->dirbuf[c % DBLKSIZ] |= (1 << dbit % BYTESIZ);
13539 + if (dbit >= db->maxbno)
13540 + db->maxbno += DBLKSIZ * BYTESIZ;
13542 + if (lseek (db->dirf, OFF_DIR (dirb), SEEK_SET) < 0
13543 + || write (db->dirf, db->dirbuf, DBLKSIZ) < 0)
13550 + * getnext - get the next key in the page, and if done with
13551 + * the page, try the next page in sequence
13553 +static datum getnext (DBM * db)
13560 + key = getnkey (db->pagbuf, db->keyptr);
13561 + if (key.dptr != NULL)
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.
13569 + if (db->pagbno != db->blkptr++)
13570 + if (lseek (db->pagf, OFF_PAG (db->blkptr), SEEK_SET) < 0)
13572 + db->pagbno = db->blkptr;
13573 + if (read (db->pagf, db->pagbuf, PBLKSIZ) <= 0)
13575 + if (!chkpage (db->pagbuf))
13579 + return ioerr (db), nullitem;
13583 + * all important binary trie traversal
13585 +static int getpage (DBM * db, long hash)
13593 + while (dbit < db->maxbno && getdbit (db, dbit))
13594 + dbit = 2 * dbit + ((hash & (1 << hbit++)) ? 2 : 1);
13596 + db->curbit = dbit;
13597 + db->hmask = masks[hbit];
13599 + pagb = hash & db->hmask;
13601 + * see if the block we need is already in memory.
13602 + * note: this lookaside cache has about 10% hit rate.
13604 + if (pagb != db->pagbno)
13607 + * note: here, we assume a "hole" is read as 0s.
13608 + * if not, must zero pagbuf first.
13610 + if (lseek (db->pagf, OFF_PAG (pagb), SEEK_SET) < 0
13611 + || read (db->pagf, db->pagbuf, PBLKSIZ) < 0)
13613 + if (!chkpage (db->pagbuf))
13615 + db->pagbno = pagb;
13621 + * makroom - make room by splitting the overfull page
13622 + * this routine will attempt to make room for SPLTMAX times before
13625 +static int makroom (DBM * db, long hash, int need)
13628 + char twin[PBLKSIZ];
13629 + char *pag = db->pagbuf;
13630 + char *new = twin;
13631 + int smax = SPLTMAX;
13636 + * split the current page
13638 + (void) splpage (pag, new, db->hmask + 1);
13640 + * address of the new page
13642 + newp = (hash & db->hmask) | (db->hmask + 1);
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.
13652 + if (hash & (db->hmask + 1))
13654 + if (lseek (db->pagf, OFF_PAG (db->pagbno), SEEK_SET) < 0
13655 + || write (db->pagf, db->pagbuf, PBLKSIZ) < 0)
13657 + db->pagbno = newp;
13658 + (void) memcpy (pag, new, PBLKSIZ);
13660 + else if (lseek (db->pagf, OFF_PAG (newp), SEEK_SET) < 0
13661 + || write (db->pagf, new, PBLKSIZ) < 0)
13664 + if (!setdbit (db, db->curbit))
13667 + * see if we have enough room now
13669 + if (fitpair (pag, need))
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.
13677 + db->curbit = 2 * db->curbit +
13678 + ((hash & (db->hmask + 1)) ? 2 : 1);
13679 + db->hmask |= db->hmask + 1;
13681 + if (lseek (db->pagf, OFF_PAG (db->pagbno), SEEK_SET) < 0
13682 + || write (db->pagf, db->pagbuf, PBLKSIZ) < 0)
13688 + * if we are here, this is real bad news. After SPLTMAX splits,
13689 + * we still cannot fit the key. say goodnight.
13692 + (void) write (2, "sdbm: cannot insert after SPLTMAX attempts.\n", 44);
13698 +static SDBM *sdbm_prep (char *dirname, char *pagname, int flags, int mode)
13701 + struct stat dstat;
13703 + if ((db = (SDBM *) mymalloc (sizeof (SDBM))) == NULL)
13704 + return errno = ENOMEM, (SDBM *) NULL;
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.
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;
13723 + * Make sure to ignore the O_EXCL option, as the file might exist due
13724 + * to the locking.
13726 + flags &= ~O_EXCL;
13729 + * open the files in sequence, and stat the dirfile.
13730 + * If we fail anywhere, undo everything, return NULL.
13733 + if ((db->pagf = open (pagname, flags, mode)) > -1)
13735 + if ((db->dirf = open (dirname, flags, mode)) > -1)
13738 + * need the dirfile size to establish max bit number.
13740 + if (fstat (db->dirf, &dstat) == 0)
13747 + msg_info ("closing dirf");
13748 + (void) close (db->dirf);
13750 + msg_info ("closing pagf");
13751 + (void) close (db->pagf);
13753 + myfree ((char *) db);
13754 + return (SDBM *) NULL;
13757 +static DBM *sdbm_internal_open (SDBM * sdbm)
13760 + struct stat dstat;
13762 + if ((db = (DBM *) mymalloc (sizeof (DBM))) == NULL)
13763 + return errno = ENOMEM, (DBM *) NULL;
13765 + db->flags = sdbm->flags;
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;
13775 + * need the dirfile size to establish max bit number.
13777 + if (fstat (db->dirf, &dstat) == 0)
13780 + * zero size: either a fresh database, or one with a single,
13781 + * unsplit data page: dirpage is all zeros.
13783 + db->dirbno = (!dstat.st_size) ? 0 : -1;
13785 + db->maxbno = dstat.st_size * BYTESIZ;
13787 + (void) memset (db->pagbuf, 0, PBLKSIZ);
13788 + (void) memset (db->dirbuf, 0, DBLKSIZ);
13791 + myfree ((char *) db);
13792 + return (DBM *) NULL;
13795 +static void sdbm_internal_close (DBM * db)
13801 + myfree ((char *) db);
13805 +datum sdbm_fetch (SDBM * sdb, datum key)
13810 + if (sdb == NULL || bad (key))
13811 + return errno = EINVAL, nullitem;
13813 + if (!(db = sdbm_internal_open (sdb)))
13814 + return errno = EINVAL, nullitem;
13816 + if (getpage (db, exhash (key)))
13818 + retval = getpair (db->pagbuf, key);
13819 + sdbm_internal_close (db);
13823 + sdbm_internal_close (db);
13825 + return ioerr (sdb), nullitem;
13828 +int sdbm_delete (SDBM * sdb, datum key)
13833 + if (sdb == NULL || bad (key))
13834 + return errno = EINVAL, -1;
13835 + if (sdbm_rdonly (sdb))
13836 + return errno = EPERM, -1;
13838 + if (!(db = sdbm_internal_open (sdb)))
13839 + return errno = EINVAL, -1;
13841 + if (getpage (db, exhash (key)))
13843 + if (!delpair (db->pagbuf, key))
13846 + * update the page file
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;
13855 + retval = ioerr (sdb), -1;
13857 + sdbm_internal_close (db);
13862 +int sdbm_store (SDBM * sdb, datum key, datum val, int flags)
13869 + if (sdb == NULL || bad (key))
13870 + return errno = EINVAL, -1;
13871 + if (sdbm_rdonly (sdb))
13872 + return errno = EPERM, -1;
13874 + need = key.dsize + val.dsize;
13876 + * is the pair too big (or too small) for this database ??
13878 + if (need < 0 || need > PAIRMAX)
13879 + return errno = EINVAL, -1;
13881 + if (!(db = sdbm_internal_open (sdb)))
13882 + return errno = EINVAL, -1;
13884 + if (getpage (db, (hash = exhash (key))))
13887 + * if we need to replace, delete the key/data pair
13888 + * first. If it is not there, ignore.
13890 + if (flags == DBM_REPLACE)
13891 + (void) delpair (db->pagbuf, key);
13893 + else if (duppair (db->pagbuf, key))
13895 + sdbm_internal_close (db);
13900 + * if we do not have enough room, we have to split.
13902 + if (!fitpair (db->pagbuf, need))
13903 + if (!makroom (db, hash, need))
13905 + sdbm_internal_close (db);
13906 + return ioerr (db), -1;
13909 + * we have enough room or split is successful. insert the key,
13910 + * and update the page file.
13912 + (void) putpair (db->pagbuf, key, val);
13914 + if (lseek (db->pagf, OFF_PAG (db->pagbno), SEEK_SET) < 0
13915 + || write (db->pagf, db->pagbuf, PBLKSIZ) < 0)
13917 + sdbm_internal_close (db);
13918 + return ioerr (db), -1;
13923 + sdbm_internal_close (db);
13927 + sdbm_internal_close (db);
13928 + return ioerr (sdb), -1;
13932 + * the following two routines will break if
13933 + * deletions aren't taken into account. (ndbm bug)
13935 +datum sdbm_firstkey (SDBM * sdb)
13941 + return errno = EINVAL, nullitem;
13943 + if (!(db = sdbm_internal_open (sdb)))
13944 + return errno = EINVAL, nullitem;
13947 + * start at page 0
13949 + if (lseek (db->pagf, OFF_PAG (0), SEEK_SET) < 0
13950 + || read (db->pagf, db->pagbuf, PBLKSIZ) < 0)
13952 + sdbm_internal_close (db);
13953 + return ioerr (sdb), nullitem;
13959 + retval = getnext (db);
13960 + sdb->blkptr = db->blkptr;
13961 + sdb->keyptr = db->keyptr;
13962 + sdbm_internal_close (db);
13966 +datum sdbm_nextkey (SDBM * sdb)
13972 + return errno = EINVAL, nullitem;
13974 + if (!(db = sdbm_internal_open (sdb)))
13975 + return errno = EINVAL, nullitem;
13977 + retval = getnext (db);
13978 + sdb->blkptr = db->blkptr;
13979 + sdb->keyptr = db->keyptr;
13980 + sdbm_internal_close (db);
13984 +void sdbm_close (SDBM * db)
13990 + (void) close (db->dirf);
13991 + (void) close (db->pagf);
13992 + myfree ((char *) db);
13996 +SDBM *sdbm_open (char *file, int flags, int mode)
14003 + if (file == NULL || !*file)
14004 + return errno = EINVAL, (SDBM *) NULL;
14006 + * need space for two seperate filenames
14008 + n = strlen (file) * 2 + strlen (DIRFEXT) + strlen (PAGFEXT) + 2;
14010 + if ((dirname = (char *) mymalloc ((unsigned) n)) == NULL)
14011 + return errno = ENOMEM, (SDBM *) NULL;
14013 + * build the file names
14015 + dirname = strcat (strcpy (dirname, file), DIRFEXT);
14016 + pagname = strcpy (dirname + strlen (dirname) + 1, file);
14017 + pagname = strcat (pagname, PAGFEXT);
14019 + db = sdbm_prep (dirname, pagname, flags, mode);
14020 + myfree ((char *) dirname);
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
14032 +/* SDBM Simple DBM: ndbm work-alike hashed database library
14034 +/* include "sdbm.h"
14039 +#ifndef UTIL_SDBM_H
14040 +#define UTIL_SDBM_H
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.
14049 +#define DUFF /* go ahead and use the loop-unrolled version */
14051 +#include <stdio.h>
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"
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 */
14071 +#define DBM_RDONLY 0x1 /* data base open read-only */
14072 +#define DBM_IOERR 0x2 /* data base I/O error */
14077 +#define sdbm_rdonly(db) ((db)->flags & DBM_RDONLY)
14078 +#define sdbm_error(db) ((db)->flags & DBM_IOERR)
14080 +#define sdbm_clearerr(db) ((db)->flags &= ~DBM_IOERR) /* ouch */
14082 +#define sdbm_dirfno(db) ((db)->dirf)
14083 +#define sdbm_pagfno(db) ((db)->pagf)
14090 +extern datum nullitem;
14093 + * flags to sdbm_store
14095 +#define DBM_INSERT 0
14096 +#define DBM_REPLACE 1
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 *);
14110 + * sdbm - ndbm work-alike hashed database library
14111 + * tuning and portability constructs [not nearly enough]
14112 + * author: oz@nexus.yorku.ca
14118 + * important tuning parms (hah)
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
14129 /* int vstream_fileno(stream)
14130 /* VSTREAM *stream;
14132 +/* void *vstream_context(stream)
14133 +/* VSTREAM *stream;
14135 /* int vstream_ferror(stream)
14136 /* VSTREAM *stream;
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.
14143 +/* vstream_context() returns the application context that is passed on to
14144 +/* the application-specified read/write routines.
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
14152 #define VSTREAM_GETCHAR() VSTREAM_GETC(VSTREAM_IN)
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)