2 @c This is part of the SXEmacs Lisp Reference Manual.
3 @c Copyright (C) 2005 Sebastian Freundt
4 @c See the file lispref.texi for copying conditions.
5 @setfilename ../../info/openssl.info
7 @node OpenSSL Support, Enhanced Number Types, PostgreSQL Support, top
8 @comment node-name, next, previous, up
9 @chapter OpenSSL Support
12 SXEmacs can be linked with OpenSSL libcrypto and libssl to provide
13 a comprehensive gateway to cryptographic and related functions.
15 @comment HINT FOR EXPERIMENTAL STATUS
16 Note: Currently the API provided for SXEmacs is experimental.
17 Conceptional changes, renaming, and changes in the behaviour of
18 functions are highly likely.
19 @comment REMOVE ME WHEN I AM STABLE
23 * Building SXEmacs with OpenSSL support::
24 * SXEmacs OpenSSL API::
28 @node Building SXEmacs with OpenSSL support
29 @section Building SXEmacs with OpenSSL support
31 SXEmacs OpenSSL support requires linking to the OpenSSL libcrypto and libssl
32 libraries. We recommend the most recent stable version, which is
33 0.9.8b as of writing this documentation. Nonetheless, we have
34 successfully tested each version since 0.9.6d (May 2002). OpenSSL can
37 @url{http://www.openssl.org}
40 For most systems the following snippet can be used to build a
41 reasonably feature-rich and yet fast library:
44 ./config --prefix=/usr/local/ threads enable-mdc2 enable-gmp \
45 enable-rc5 enable-shared enable-zlib enable-zlib-dynamic enable-dso \
46 enable-krb5 enable-asm
49 Some of the above options depend in turn on external resources, like
50 GMP and zlib. However, describing in detail how to build and install
51 OpenSSL is beyond the scope of this document. See the OpenSSL manual
54 If you plan to build SXEmacs with OpenSSL support you need to install
55 OpenSSL first. On some systems, OpenSSL will come pre-installed in
56 /usr. In this case, all you need to do is passing
57 @samp{--with-openssl} to configure.
59 If the configure script fails to detect your installation of OpenSSL,
60 make sure you supplied header files, or try to explicitly name the
61 location of your OpenSSL installation via the @samp{--site-prefixes}
62 flag when you run the SXEmacs configure script.
65 @node SXEmacs OpenSSL API
66 @section SXEmacs OpenSSL API
68 @c Explaining cryptographical details behind OpenSSL API functions is
69 @c beyond the scope of this document. Ask Professor Google.
70 @c @comment erm, again: Why? maybe some alice-bob examples?
72 The SXEmacs OpenSSL API is intended to be an exact copy of the OpenSSL
73 API functions in libcrypto and libssl. The intent is to provide elisp
74 for everything you have told your OpenSSL library to contain. Then,
75 at stage 2, let higher level Lisp code come up with policies and
76 remove the guts of libcrypto and libssl.
78 Despite this rather noble intention of giving access to anything in
79 OpenSSL there are conceptional limits. Auxiliary stuff from OpenSSL
80 such as BIO or BN will not be accessible to elisp, though the C
81 implementation might use them directly or indirectly as well.
83 On the one hand this is due to their very special purpose (like finding
84 prime numbers), on the other hand due to their obsoleteness (like
85 BIO_gets, BIO_do_connect, etc.) when SXEmacs already provides a similar
86 or more powerful implementation.
88 For convenience, we denote the elisp implementation of OpenSSL with openssl
89 whereas the distributed library package from @url{http://www.openssl.org}
94 * openssl General:: General Information
95 * openssl RAND:: (Pseudo) Random Numbers
96 * openssl MD:: Message Digests (aka hashes)
97 * openssl HMAC:: Message Authentication Codes (aka keyed hashes)
98 * openssl CIPHER:: Symmetric Cryptography
99 * openssl PKEY:: Public Key Crypto Systems (aka asymmetric ciphers)
100 * openssl SSL/TLS:: Secure Network Layers
104 @node openssl General
105 @subsection General information
107 In this section we deal with informative functions which kind of
108 reflect the underlying library capabilities. It is very hard to say
109 which of the capabilities are guaranteed to exist since it is possible
110 to strip certain cryptographic stuff from the OpenSSL installation,
111 for instance due to license, patent, or legal issues.
114 Return a descriptive version number of the OpenSSL in use.
116 The version string should be identical to the output of @code{openssl
122 @result{} "OpenSSL 0.9.9-dev XX xxx XXXX"
127 @defun ossl-available-digests
128 Return a list of digest algorithms in the underlying crypto library.
129 This yields a plain list of symbols.
132 @defun ossl-available-ciphers
133 Return a list of cipher algorithms in the underlying crypto library.
134 This yields a list of symbols.
139 (ossl-available-digests)
140 @result{} '(UNDEF MD2 MD5 RSA-MD2 RSA-MD5 SHA RSA-SHA SHA1 RSA-SHA1 DSA-SHA
141 DSA-SHA1-old MDC2 RSA-MDC2 DSA-SHA1 RSA-SHA1-2 DSA RIPEMD160
142 RSA-RIPEMD160 MD4 RSA-MD4 ecdsa-with-SHA1 RSA-SHA256 RSA-SHA384
143 RSA-SHA512 RSA-SHA224 SHA256 SHA384 SHA512 SHA224 whirlpool)
147 (ossl-available-ciphers)
148 @result{} '(RC4 DES-ECB DES-CFB DES-CBC DES-EDE DES-EDE3 IDEA-CBC IDEA-CFB
149 IDEA-ECB RC2-CBC RC2-ECB RC2-CFB RC2-OFB DES-EDE-CBC
150 DES-EDE3-CBC DES-OFB IDEA-OFB DES-EDE-CFB DES-EDE3-CFB
151 DES-EDE-OFB DES-EDE3-OFB DESX-CBC BF-CBC BF-ECB BF-CFB BF-OFB
152 RC4-40 RC2-40-CBC CAST5-CBC CAST5-ECB CAST5-CFB CAST5-OFB
153 RC5-CBC RC5-ECB RC5-CFB RC5-OFB RC2-64-CBC AES-128-ECB
154 AES-128-CBC AES-128-OFB AES-128-CFB AES-192-ECB AES-192-CBC
155 AES-192-OFB AES-192-CFB AES-256-ECB AES-256-CBC AES-256-OFB
156 AES-256-CFB AES-128-CFB1 AES-192-CFB1 AES-256-CFB1 AES-128-CFB8
157 AES-192-CFB8 AES-256-CFB8 DES-CFB1 DES-CFB8 CAMELLIA-128-CBC
158 CAMELLIA-192-CBC CAMELLIA-256-CBC CAMELLIA-128-ECB
159 CAMELLIA-192-ECB CAMELLIA-256-ECB CAMELLIA-128-CFB
160 CAMELLIA-192-CFB CAMELLIA-256-CFB CAMELLIA-128-CFB1
161 CAMELLIA-192-CFB1 CAMELLIA-256-CFB1 CAMELLIA-128-CFB8
162 CAMELLIA-192-CFB8 CAMELLIA-256-CFB8 CAMELLIA-128-OFB
163 CAMELLIA-192-OFB CAMELLIA-256-OFB)
168 These two functions are most useful to conditionalise like
170 (when (member 'MD4 (ossl-available-digests))
174 The aforementioned functions work at run-time (not compile time) so it
175 is possible when building a dynamically linked SXEmacs to update
176 OpenSSL on the fly. A very rough estimate is to assume to have
177 support for the MD5 and SHA1 message digests, and the BF-* symmetric
178 cipher systems, any installation of OpenSSL without those is purely
179 ridiculous although not impossible.
182 Furthermore we provide convenience functions which, given a digest or
183 cipher algorithm symbol, allow to obtain information about the hash
184 result size of a digest, and the key size of a cipher, respectively.
186 @defun ossl-digest-size digest
187 Return the hash length of @var{digest} in bytes.
190 (ossl-digest-size 'MD5)
192 (ossl-digest-size 'SHA512)
197 @defun ossl-digest-block-size digest
198 Return the block size of @var{digest} in bytes.
201 (ossl-digest-block-size 'MD5)
203 (ossl-digest-block-size 'SHA512)
208 @defun ossl-cipher-key-length cipher
209 Return the effective key size of @var{cipher} in bytes.
212 (ossl-cipher-key-length 'RC4)
214 (ossl-cipher-key-length 'CAMELLIA-256-CBC)
219 @defun ossl-cipher-iv-length cipher
220 Return the initialisation vector length of @var{cipher} in bytes.
223 (ossl-cipher-iv-length 'idea-cbc)
225 (ossl-cipher-iv-length 'aes-256-cbc)
230 @defun ossl-cipher-block-size cipher
231 Return the block size of @var{cipher} in bytes.
234 (ossl-cipher-block-size 'aes-256-cbc)
236 (ossl-cipher-block-size 'rc4)
241 @defun ossl-cipher-mode cipher
242 Return the operation mode of @var{cipher}.
245 (ossl-cipher-mode 'rc4)
247 (ossl-cipher-mode 'aes-192-ofb)
253 The openssl API provides following features:
256 @code{'openssl} when fundamental functions are available
258 @code{'openssl-rsa} when RSA keys are available
260 @code{'openssl-dsa} when DSA keys are available
262 @code{'openssl-ec} when elliptic curves are available
264 @code{'openssl-dh} when DH keys are available
266 @code{'openssl-ssl} when the TLS/SSL and X509 capabilities are
272 @subsection (Pseudo) Random Numbers
274 Random numbers are necessary for cryptographically secure
275 implementations. The term number here indeed means a string. OpenSSL
276 itself provides random number generators which fulfill the the demands
279 @defun ossl-rand-bytes count
280 Return @var{count} bytes of randomness.
282 Note: You probably want to put a wrapping encoder function
283 (like @code{base16-encode-string}) around it, since this returns
289 (base16-encode-string (ossl-rand-bytes 8))
290 @result{} "5a78acd572984bdf"
295 Modern systems supply more sophisticated sources for random data, so
296 called entropy gathering daemons.
298 @defun ossl-rand-bytes-egd count egd
299 Return @var{count} bytes of randomness from an EGD socket.
300 By default use the socket @file{/var/run/egd-pool}.
302 Note: You probably want to put a wrapping encoder function
303 (like @code{base16-encode-string}) around it, since this returns
309 (base16-encode-string (ossl-rand-bytes-egd 8 "/var/run/egd-pool"))
310 @result{} "59342a240b356a04"
314 Please note that the system's random sources are used only for seeding
315 OpenSSL's pseudo-random number generator. So even large amounts of
316 random data should be feasible. In contrast querying for large
317 amounts of random data directly most likely freezes your process since
318 the size of random devices or pools, and hence the size of cached
319 random data, is quite limited.
321 Random numbers generated this way, can be used as ``passwords'' or
322 salt values in various encryption and decryption functions. As stated
323 above, whenever security is concerned one of the above functions,
324 @code{ossl-rand-bytes} or @code{ossl-rand-bytes-egd} should be used to
325 obtain random numbers. The built-in @code{random} function of SXEmacs
326 is @emph{not} cryptographically secure.
330 @subsection Message Digests (aka hashes)
332 Message digests are widely used in modern information
333 infrastructure. They are derived from (collision free) one-way hash
336 A hash function (such as @samp{md5} or @samp{sha1}) is a function
337 with following properties:
340 @item reduction: data of arbitrary length is mapped onto data
342 @item dispersion: a change of one bit in input data changes
343 (ideally) half the bits of the hash value.
344 @item well definedness: computing a hash value from the same
345 source data twice yields the same result
346 @item efficiency: computing hash values is efficient (ideally
347 with complexity O(n)) on the input, but it is hard to
348 compute a preimage for a given hash value.
351 Often, the last property is too weak in practice, therefore
352 most hash functions comply with the even stronger:
355 @item collision-freeness: it is hard to compute two different
356 source data which result in the same hash value.
359 Message digests fulfill several tasks in daily use. Most commonly
360 used are so called checksums. In modern days hash functions are used
361 almost exclusively for their error detecting facilities in contrast to
362 other checksum algorithms like CRC32.
364 Beyond that, message digests play an important role in digital
365 signatures. Since public key crypto systems map long plaintexts on
366 long ciphertexts, message digests are used to obscure the length of a
369 Therefore in digital signatures not the message itself is signed but
370 the hash value of that message. That also assures a certain upper
371 bound of the length of a digital signature which is (as in real life)
372 rather short compared to the message that was signed.
374 Okay, after this short introduction to message digests, here are the
375 functions to access them from elisp.
377 @defun ossl-digest digest string
378 Return the message digest of @var{string} computed by @var{digest}.
379 @var{digest} may be one of the OpenSSL digests you have compiled.
380 See @code{ossl-available-digests}.
382 Note: You probably want to put a wrapping encoder function (like
383 @code{base16-encode-string}) around it, since this returns binary
387 In order to compute digest sums from files without actually looking
388 at the file contents explicitly, there is the companion function
389 @code{ossl-digest-file} which works similarly.
391 @defun ossl-digest digest file
392 Return the message digest of the contents of @var{file} computed by
394 @var{digest} may be one of the OpenSSL digests you have compiled.
395 See @code{ossl-available-digests}.
397 Note: You probably want to put a wrapping encoder function (like
398 @code{base16-encode-string}) around it, since this returns binary
402 The current implementation of the OpenSSL API in SXEmacs uses the
403 EVP layer of OpenSSL to access the digests.
407 (base16-encode-string (ossl-digest 'md5 "hash me"))
408 @result{} "17b31dce96b9d6c6d0a6ba95f47796fb"
412 (base16-encode-string (ossl-digest 'SHA1 "hash me"))
413 @result{} "43f932e4f7c6ecd136a695b7008694bb69d517bd""
417 Let's do some performance tests.
421 ;; @r{this is the SXEmacs built-in implementation of MD5}
422 (let ((st (current-btime)))
424 (md5 "Some test string to hash"))
425 (- (current-btime) st))
427 ;; @r{time in microseconds, so this is about 6 seconds}
431 ;; @r{now compare to the OpenSSL implementation}
432 (let ((st (current-btime)))
434 (ossl-digest 'md5 "Some test string to hash"))
435 (- (current-btime) st))
437 ;; @r{which is about 10 seconds}
441 As we can see, the built-in implementation has slightly better
442 performance when hashing short strings. The following example shows
443 performance on long strings, like the buffer string here.
447 (length (buffer-string))
452 ;; @r{we begin with the built-in implementation}
453 (let ((st (current-btime))
457 (- (current-btime) st))
459 ;; @r{which is about 74 seconds}
463 ;; @r{compare to the OpenSSL API}
464 (let ((st (current-btime))
467 (base16-encode-string
468 (ossl-digest 'md5 b)))
469 (- (current-btime) st))
471 ;; @r{which is about 31 seconds}
475 This latter example shows digest hashing ``under real conditions''
476 since in practice messages to be hashed are typically in the range of
477 1000 to 30000 characters. This range is even vastly exceeded when
478 dealing with checksums for files.
480 Since the built-in md5 implementation cannot handle file streams, we
481 have to turn them into strings. A possible way to achieve this has
482 been suggested by Steve Youngs. I shall illustrate it with a tarball
487 freundt@@muck:~> ls -sh ~/temp/pdftex-1.30.3.tar.bz2
488 3.2M /home/freundt/temp/pdftex-1.30.3.tar.bz2
492 (let ((st (current-btime))
494 (insert-file-contents-literally
495 "~/temp/pdftex-1.30.3.tar.bz2")
499 (- (current-btime) st))
501 ;; @r{which is about 22 seconds}
505 Compared to the file stream function @code{ossl-digest-file}:
509 (let ((st (current-btime)))
511 (ossl-digest-file 'md5 "~/temp/pdftex-1.30.3.tar.bz2"))
512 (- (current-btime) st))
514 ;; @r{which is about 4 seconds}
518 Another performance test which compares the elisp implementation of
519 sha1 (taken from `No Gnus v0.4') to the one from the OpenSSL API
523 (let ((st (current-btime)))
525 (sha1-binary "a short test string"))
526 (- (current-btime) st))
528 ;; @r{which is about 2.5 seconds}
532 ;; @r{the same with the OpenSSL API}
533 (let ((st (current-btime)))
535 (ossl-digest 'sha1 "a short test string"))
536 (- (current-btime) st))
538 ;; @r{which is about 0.03 seconds}
542 These results suggest to always use the openssl interface in favour of
543 other implementations.
547 @subsection Message Authentication Codes (aka keyed hashes)
549 Ordinary message digests only offer data integrity verification,
550 while HMACs may be used to simultaneously verify both the data
551 integrity and the authenticity of a message. This is accomplished by
552 using a secret key. Now whenever two parties have agreed upon a
553 common secret key, one of them can verify that a message hash was
554 indeed computed by the other one.
556 @defun ossl-hmac digest message password
557 Return the message authentication code of @var{message}
558 using the hash function @var{digest} and the key @var{password}.
560 Note: You probably want to put a wrapping encoder function
561 (like @code{base16-encode-string}) around it, since this returns
565 Unlike in public-key cryptography, this technique requires a new
566 secret key for any two parties which want to communicate. On the
567 other hand, this technique works symmetrically, that is the same
568 function can be used for both generating and verifying a keyed message
573 (base16-encode-string
574 (ossl-hmac 'SHA512 "string to hash" "secret"))
575 @result{} "62351dfae2030fb28058a2aeba6ce3597d803575c120109ed6cfee240d7
576 50e71ffff1d8dfc8d52e666549dcb6ba95fb4d550bdc9f31178c19fecb4
581 ;; @r{now hashing with a false password}
582 (base16-encode-string
583 (ossl-hmac 'SHA512 "string to hash" "false"))
584 @result{} "44afb8f67ea7f66693e891e79b7295569163e3e6faebd47d2a63e564778
585 c72221cbb4cdff01ff1052ea98d2058f33c1ecf48f0c45bb64e526a81d8
592 @subsection Symmetric Cryptography
594 Symmetric-key algorithms can be divided into stream ciphers and
595 block ciphers. Stream ciphers encrypt the bits of the message one at
596 a time, and block ciphers take a number of bits and encrypt them as a
599 In order to use symmetric-key cryptography some preparations have to
600 be done, mostly due to the block-oriented operation of the algorithms.
601 The following function, given a cipher and digest algorithm, computes
602 a valid key suitable for the given cipher algorithm.
604 @defun ossl-bytes-to-key cipher digest salt password count
605 Derive a key and initialisation vector (iv) suitable for a cipher.
606 Return a string @var{key} being the key. The initialisation vector is
607 put into @var{key}'s property list as @code{'iv}.
609 @var{cipher} (a symbol) is the cipher to derive the key and IV for.
610 Valid ciphers can be obtained by @code{ossl-available-ciphers}.
612 @var{digest} (a symbol) is the message digest to use.
613 Valid digests can be obtained by @code{ossl-available-digests}.
615 @var{salt} (string or @code{nil}) is used as a salt in the derivation.
616 Use @code{nil} here to indicate that no salt is used.
618 @var{password} is an arbitrary string which is processed to derive a
621 @var{count} (a positive integer) is the iteration count to use. This
622 indicates how often the hash algorithm is called recursively.
624 Note: You probably want to put a wrapping encoder function
625 (like @code{base16-encode-string}) around it, since this returns
629 Note: It is disregarded to use the key/iv pair of, say, AES-128 cipher
630 for e.g. a blowfish (BF) cipher, although it seems possible and is not
631 explicitly forbidden. Such malpractices may result in severe
636 (base16-encode-string
637 (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "somesalt" "secret" 1))
638 @result{} "bd2b1aaf7ef4f09be9f52ce2d8d599674d81aa9d6a4421696dc4d93dd0619d68"
642 (base16-encode-string
643 (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "diffsalt" "secret" 1))
644 @result{} "bd2b1aaf7ef4f09be9f52ce2d8d599674d81aa9d6a4421696dc4d93dd0619d68"
648 (base16-encode-string
649 (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "diffsalt" "retsec" 1))
650 @result{} "38515c1868bcab470075ec32bc79b0ed1aa945de95d2261991ea840921e7747b"
654 These examples show how different passwords yield different keys, and
655 that different salts do not affect the result. As mentioned in the
656 doc string the result carries an object-plist with the initialisation
662 (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "somesalt" "secret" 1))
663 @result{} (iv "????????????????")
667 (base16-encode-string
669 (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "somesalt" "secret" 1)
671 @result{} "2ce56b4d64a9ef097761ced99e0f6726"
676 @defun ossl-encrypt cipher string key &optional iv
677 Return the cipher of @var{string} computed by @var{cipher} under
680 @var{cipher} (a symbol) may be one of the OpenSSL cipher algorithms
681 you have compiled. See @code{ossl-available-ciphers}.
683 @var{string} is the text to be encrypted.
685 @var{key} should be a key generated suitably for this cipher, for
686 example by @code{ossl-bytes-to-key}.
688 Optional fourth argument @var{iv} should be an initialisation vector
689 suitable for this cipher. Normally the initialisation vector from
690 @var{key}'s property list is used. However, if @var{iv} is
691 non-@code{nil}, use this IV instead.
693 Note: You probably want to put a wrapping encoder function
694 (like @code{base16-encode-string}) around it, since this returns
698 @defun ossl-decrypt cipher string key &optional iv
699 Return the deciphered version of @var{string} computed by @var{cipher}
702 @var{cipher} (a symbol) may be one of the OpenSSL cipher algorithms
703 you have compiled. See @code{ossl-available-ciphers}.
705 @var{string} is the text to be decrypted.
707 @var{key} should be a key generated suitably for this cipher, for
708 example by @code{ossl-bytes-to-key}.
710 Optional fourth argument @var{iv} should be an initialisation vector
711 suitable for this cipher. Normally the initialisation vector from
712 @var{key}'s property list is used. However, if @var{iv} is
713 non-@code{nil}, use this IV instead.
718 (base16-encode-string
720 (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "salt" "secret" 10)))
721 (ossl-encrypt 'AES-256-OFB "Very secret text." key)))
722 @result{} "bbedc78c88eddea29c8653f551da391091"
727 (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "salt" "secret" 10))
728 (s (base16-decode-string "bbedc78c88eddea29c8653f551da391091")))
729 (ossl-decrypt 'AES-256-OFB s key))
730 @result{} "Very secret text."
735 (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "salt" "dontknow" 1))
736 (s (base16-decode-string "bbedc78c88eddea29c8653f551da391091")))
737 (ossl-decrypt 'AES-256-OFB s key))
738 @result{} "?????????????????"
742 The above example shows a complete cycle of encryption and decryption,
743 as well as an attempt to decrypt a string using a wrong password.
745 As for message digests, there are two companion functions which
746 directly work on files.
748 @defun ossl-encrypt-file cipher file key &optional iv outfile
749 Return the encrypted contents of @var{file} computed by @var{cipher}
752 @var{cipher} (a symbol) may be one of the OpenSSL cipher algorithms
753 you have compiled. See @code{ossl-available-ciphers}.
755 @var{file} is the file to be encrypted.
757 @var{key} should be a key generated suitably for this
758 cipher, for example by @code{ossl-bytes-to-key}.
760 Optional fourth argument @var{iv} should be an initialisation vector
761 suitable for this cipher. Normally the initialisation vector from
762 @var{key}'s property list is used. However, if @var{iv} is
763 non-@code{nil}, use this IV instead.
765 Optional fifth argument @var{outfile} may specify a file to have the
766 encrypted data redirected.
768 Note: You probably want to put a wrapping encoder function
769 (like @code{base16-encode-string}) around it, since this returns
774 @defun ossl-decrypt-file cipher file key &optional iv outfile
775 Return the deciphered version of @var{file} computed by @var{cipher}
778 @var{cipher} (a symbol) may be one of the OpenSSL cipher algorithms
779 you have compiled. See @code{ossl-available-ciphers}.
781 @var{file} is the file to be decrypted.
783 @var{key} should be a key generated suitably for this
784 cipher, for example by @code{ossl-bytes-to-key}.
786 Optional fourth argument @var{iv} should be an initialisation vector
787 suitable for this cipher. Normally the initialisation vector from
788 @var{key}'s property list is used. However, if @var{iv} is
789 non-@code{nil}, use this IV instead.
791 Optional fifth argument @var{outfile} may specify a file to have the
792 decrypted data redirected.
798 @subsection public key crypto systems
800 While keys for symmetric ciphers can be easily stored as strings, keys
801 for asymmetric algorithms are more complex. The openssl API therefore
802 provides a dedicated primitive type, called pkey. Pkey objects can
803 contain key pairs -- i.e. pairs of public keys and corresponding
804 private keys, public keys, and also certificates. They are general
805 container object for various subtypes such as RSA, DSA, EC, and DH
808 However, you cannot directly create such a pkey object nor access nor
809 modify parts of it. Pkey objects are actually meant as transporter
810 objects to simplify those functions which need them.
812 @defun ossl-pkey-p object
813 Return @code{t} if @var{object} is a pkey, @code{nil} otherwise.
816 @defun ossl-pkey-size pkey
817 Return the size a public key @var{pkey} in bits.
820 @defun ossl-pkey-private-p pkey
821 Return non-@code{nil} if @var{pkey} contains private data.
823 Note: This function is not native OpenSSL.
826 @defun ossl-pkey-get-public pkey
827 Return a copy of @var{pkey} stripped by the private data.
829 Note: This function is not native OpenSSL.
832 The above functions have a generic character because they are
833 independent from the choice of algorithm, see below. For each of
834 these algorithms we provide a constructor function
835 @code{ossl-@var{algo}-generate-key} and a subtype predicate, named
836 @code{ossl-@var{algo}-pkey-p}. In case of RSA and DSA we also support
840 Note: At the moment we do not provide the creation of DH-keys.
842 Now the first important asymmetric algorithm is RSA. As mentioned in
843 the general introduction OpenSSL can be built without it. The
844 following functions therefore exist iff @code{(featurep 'openssl-rsa)}
845 evaluates to @code{t}.
847 @defun ossl-rsa-generate-key bits exp
848 Return an RSA public key with of length @var{bits} and exponent @var{exp}.
851 @defun ossl-rsa-pkey-p pkey
852 Return @code{t} iff @var{pkey} is of RSA type.
855 @defun ossl-rsa-subkey-p pkey1 pkey2
856 Return @code{t} if @var{pkey1} is a subkey of @var{pkey2}, @code{nil}
857 otherwise, i.e. if @var{pkey1} has the same public key data as
858 @var{pkey2} and @var{pkey2} has all private data.
860 Note: This function is not native OpenSSL.
865 (setq rsaexmpl (ossl-rsa-generate-key 2048 3))
866 @result{} #<OpenSSL RSA private/public key, size 2048>
867 (ossl-rsa-pkey-p rsaexmpl)
869 (ossl-pkey-private-p rsaexmpl)
874 (setq rsapub (ossl-pkey-get-public rsaexmpl))
875 @result{} #<OpenSSL RSA public key, size 2048>
876 (ossl-pkey-private-p rsapub)
878 (ossl-rsa-subkey-p rsapub rsaexmpl)
884 Another important asymmetric algorithm is DSA. The presence of DSA
885 support in the underlying library can be checked by @code{(featurep
886 'openssl-dsa)}. Nonetheless, it is very unlikely to face an OpenSSL
887 installation without DSA or RSA.
889 @defun ossl-dsa-generate-key bits &optional seed
890 Return a DSA public key with of length @var{bits} seeded with
891 (optional) @var{seed}.
894 @defun ossl-dsa-pkey-p pkey
895 Return @code{t} if @var{pkey} is of DSA type, @code{nil} otherwise.
898 @defun ossl-dsa-subkey-p pkey1 pkey2
899 Return @code{t} if @var{pkey1} is a subkey of @var{pkey2}, @code{nil}
900 otherwise, i.e. if @var{pkey1} has the same public key data as
901 @var{pkey2} and @var{pkey2} has all private data.
903 Note: This function is not native OpenSSL.
908 (setq dsaexmpl (ossl-dsa-generate-key 1024))
909 @result{} #<OpenSSL DSA private/public key, size 384>
910 (ossl-dsa-pkey-p dsaexmpl)
912 (ossl-pkey-private-p dsaexmpl)
917 (setq dsapub (ossl-pkey-get-public dsaexmpl))
918 @result{} #<OpenSSL DSA public key, size 384>
919 (ossl-pkey-private-p dsapub)
921 (ossl-dsa-subkey-p dsapub dsaexmpl)
927 Elliptic curve cryptography is quite new and is possibly missing on
928 many systems. Use @code{(featurep 'openssl-ec)} to check for elliptic
929 curve support. Another particularity of the ec system is that it is
930 based on a fixed set of curves which can be referred to by name. At
931 the moment we do not support creating custom curves.
933 @defun ossl-ec-available-curves
934 Return a list of builtin elliptic curves.
937 @defun ossl-ec-generate-key curve
938 Return a EC public key on @var{curve}.
939 @var{curve} may be any symbol from @code{(ossl-ec-available-curves)}.
941 Note: At the moment we do not support creating custom curves.
944 @defun ossl-ec-pkey-p pkey
945 Return @code{t} if @var{pkey} is of EC type, @code{nil} otherwise.
950 (ossl-ec-available-curves)
951 @result{} (Oakley-EC2N-4 Oakley-EC2N-3 wap-wsg-idm-ecid-wtls12
952 wap-wsg-idm-ecid-wtls11 wap-wsg-idm-ecid-wtls10
953 wap-wsg-idm-ecid-wtls9 wap-wsg-idm-ecid-wtls8
954 wap-wsg-idm-ecid-wtls7 wap-wsg-idm-ecid-wtls6
955 wap-wsg-idm-ecid-wtls5 wap-wsg-idm-ecid-wtls4
956 wap-wsg-idm-ecid-wtls3 wap-wsg-idm-ecid-wtls1 c2tnb431r1
957 c2pnb368w1 c2tnb359v1 c2pnb304w1 c2pnb272w1 c2tnb239v3
958 c2tnb239v2 c2tnb239v1 c2pnb208w1 c2tnb191v3 c2tnb191v2
959 c2tnb191v1 c2pnb176v1 c2pnb163v3 c2pnb163v2 c2pnb163v1 sect571r1
960 sect571k1 sect409r1 sect409k1 sect283r1 sect283k1 sect239k1
961 sect233r1 sect233k1 sect193r2 sect193r1 sect163r2 sect163r1
962 sect163k1 sect131r2 sect131r1 sect113r2 sect113r1 prime256v1
963 prime239v3 prime239v2 prime239v1 prime192v3 prime192v2
964 prime192v1 secp521r1 secp384r1 secp256k1 secp224r1 secp224k1
965 secp192k1 secp160r2 secp160r1 secp160k1 secp128r2 secp128r1
970 (setq ecexmpl (ossl-ec-generate-key 'secp224r1))
971 @result{} #<OpenSSL EC private/public key, size 512>
972 (ossl-ec-pkey-p ecexmpl)
974 (ossl-pkey-private-p ecexmpl)
979 (setq ecpub (ossl-pkey-get-public ecexmpl))
980 @result{} #<OpenSSL EC public key, size 512>
981 (ossl-pkey-private-p ecpub)
987 Finally, there is the DH key exchange. Its presence can be checked
988 by @code{(featurep 'openssl-dh)}. At the moment we do not provide
989 constructor functions.
991 @defun ossl-dh-pkey-p pkey
992 Return @code{t} if @var{pkey} is of DH type, @code{nil} otherwise.
996 Once you have a pkey object you can use it for encryption/decryption,
997 and/or signing/verification. Talking in OpenSSL hybrid encryption and
998 decryption is referred to as sealing and opening, respectively.
1000 @defun ossl-seal cipher string pkey
1001 Return an envelope derived from encrypting @var{string} by
1002 @var{cipher} under @var{pkey} with the hybrid technique.
1004 That is, create a random key/iv pair for the symmetric encryption with
1005 @var{cipher} and encrypt that key/iv asymmetrically with the provided
1008 The envelope returned is a list
1009 @code{(@var{encrypted_string} @var{encrypted_key} @var{encrypted_iv})}
1011 @var{encrypted_string} is the (symmetrically) encrypted message
1012 @var{encrypted_key} is the (asymmetrically) encrypted random key
1013 @var{encrypted_iv} is the (asymmetrically) encrypted random iv
1015 Note: You probably want to put a wrapping encoder function
1016 (like @code{base16-encode-string}) around it, since this function
1017 returns binary string data.
1020 @defun ossl-open cipher string pkey ekey eiv
1021 Return the deciphered message @var{string} from an envelope obtained
1022 by @code{ossl-seal}.
1026 @var{cipher} is the cipher to use (the same as in @code{ossl-seal})
1028 @var{string} is the encrypted message
1030 @var{pkey} is the private key
1032 @var{ekey} is the encrypted random key
1034 @var{eiv} is the encrypted iv
1039 @c * ossl-seal - gateway to public key hybrid (envelope) encryption
1040 @c * ossl-open - gateway to public key hybrid (envelope) decryption
1042 In the following example we reuse the keys generated above.
1047 (ossl-seal 'AES-256-CBC "I do not want to tell" rsaexmpl)))
1048 (setq str (car envl)
1051 (mapcar #'base16-encode-string envl))
1052 @result{} ("0e6a38b28efea3ca4901b268c141d7ac23ed5f8fa598d23d9846fe3ec1
1054 "167911a73b0a228b24e78bdd37197ec95b21bed3bbd62d1915d8fac791
1055 7915fd49fdd9774e7906ca53ed3bf4fb20de8339e628d469a496f7351c
1056 06fddda49b71c90e73e31c406cfb0f0fb7411d1c9d49842603c45415cc
1057 3a8f660c728e8f05c6479d004f5068a7969294b4cc81e13dd257df37dc
1058 886b11266a3ccba576396d200ebb1a3e8f7185fdbc6de40b63964562f9
1059 1cbe39118a07415c030fd4c3e25bbe2a64b2ab635b2ef9a71a5ddeeaf0
1060 4a73d7cd04ad334d1de04228db5a9fb9aebfa6a9dc9d76af5ec329b360
1061 d1cd8da45868450a3bc5c41bba95a0ad74439f7d5edffcdf7dff09c296
1062 35ae13215be1ae55f5d2b5e97d6a4d523470eef050b07193"
1063 "ab458ccb46cbc092c31614e997cd176b")
1067 (ossl-open 'AES-256-CBC str rsaexmpl key iv)
1068 @result{} "I do not want to tell"
1073 The above example is nice but does not demonstrate the real power of
1074 hybrid encryption. In the following example we reuse the public
1075 subkey @code{rsapub} of @code{rsaexmpl} from above. Also you will
1076 notice that the random key/iv pair has changed and thus the resulting
1077 encrypted string is not the same.
1082 (ossl-seal 'AES-256-CBC "I do not want to tell" rsapub)))
1083 (setq str (car envl)
1086 (mapcar #'base16-encode-string envl))
1087 @result{} ("93a5b3f2eb5a2eaee44805150717bb325b4e90be947591cc46b7819d3f
1089 "300b9ab5a79524fdcb40fbed6bae7e9c470baa0d230f9b97c9b35de442
1090 62f82b626ef7668329d34cffc3eeddf535a879e974825e984c7e045c0a
1091 526b3b58453ae55926af519400f32c4aee7115088068fcb6fc75ce78c5
1092 b6d61bbaf90f0c4aff1d83efd63c45c62989c29efda187bcbd94edf9f1
1093 427ec8dce22cd6333e8196120285dc5bb224b9d7e9ecfb23e016475706
1094 5da6f999560d010adaf0465b108b2a84989ff8bd17778b61875f633a35
1095 a02c2cc1fdf3a3e50ad4a5fb7ad9a05b1a3a1818a21f3d7c71a33949f6
1096 437ee64bee60e1ae92ebea43ca524b15344a7fc2712e9758b98f1b2c9d
1097 c8ad3d074486f0d35fece7bf7b6ce979fa760aa7bd5854b2"
1098 "6979d574e8bc10dfddefd4cb017186a2")
1102 (ossl-open 'AES-256-CBC str rsaexmpl key iv)
1103 @result{} "I do not want to tell"
1107 ;; @r{try with just the public part}
1108 (ossl-open 'AES-256-CBC str rsapub key iv)
1109 @error{} cannot open, key has no private key data
1114 Also note you cannot use DSA keys for sealing. They are exclusively
1118 Signing and verifying works similar to sealing and opening. Instead
1119 of a cipher algorithm you need to specify a message digest algorithm.
1120 However, in this case the signature step requires a pkey with private
1121 data and the verification step can be done with only the public part
1124 @defun ossl-sign digest string pkey
1125 Return a signature obtained by signing @var{string} under @var{digest}
1128 That is, hash the message @var{string} with the message digest
1129 @var{digest} and encrypt the result with the private key @var{pkey}.
1131 Note: Due to some relationship between the public key system and the
1132 message digest you cannot use every digest algorithm with every
1134 The most certain results will be achieved using
1135 RSA keys with RSA-* digests, DSA keys with DSA-* digests.
1137 See @code{ossl-available-digests}.
1139 Note: You probably want to put a wrapping encoder function
1140 (like @code{base16-encode-string}) around it, since this returns
1144 @defun ossl-verify digest string sig pkey
1145 Return @code{t} iff @var{sig} is a valid signature of @var{string}
1146 under @var{digest} obtained by @var{pkey}.
1148 That is, hash the message @var{string} with the message digest
1149 @var{digest}, then decrypt the signature @var{sig} with the public key
1150 @var{pkey}. Compare the results and return @code{t} iff both hashes
1155 @var{digest} is the digest to use (the same as in @code{ossl-sign})
1157 @var{string} is the message
1159 @var{sig} is the signature of message
1161 @var{pkey} is the public key
1166 @c * ossl-sign - gateway to public key signature
1167 @c * ossl-verify - gateway to public key signature verification
1169 Again we reuse the keys defined above.
1174 (setq sig (ossl-sign 'SHA1 "I owe you a beer" dsaexmpl))
1175 (base16-encode-string sig))
1176 @result{} "302d021500c2e5197d266573216e4daa85e0a7e43424d0f031021451186
1177 24043517e0cd24f381d0e6c92f96198f297"
1181 (ossl-verify 'SHA1 "I owe you a beer" sig dsapub)
1186 ;; @r{we try to fake the signed text}
1187 (ossl-verify 'SHA1 "I owe you 10 beer" sig dsapub)
1192 Note that you cannot use all combinations of pkey and digest
1193 algorithm. Suitable digests can be found in the
1194 @code{(ossl-available-digests)} list. Given a digest @var{dgst} there
1195 must be an entry @code{RSA-@var{dgst}} in order to use an RSA key for
1196 signatures under @var{dgst}. Respectively there must be an entry
1197 @code{DSA-@var{dgst}} for DSA key pairs and all DSA-suitable digests can
1198 also be used for EC keys.
1200 In order to persistently store generated keys the openssl API provides
1201 a simple interface to the PEM routines. PEM is @emph{the} format for
1202 key pairs or public keys.
1204 @defun ossl-pem-read-public-key file
1205 Return a key (the public part) stored in a PEM structure from
1209 @defun ossl-pem-read-key file &optional password
1210 Return a key stored in a PEM structure from @var{file}.
1211 If the (private part of the) key is protected with a password
1212 provide (optional) @var{password}.
1215 @defun ossl-pem-write-public-key file pkey
1216 Write @var{pkey} (the public part) in a PEM structure to @var{file}.
1219 @defun ossl-pem-write-key file pkey &optional cipher password
1220 Write @var{pkey} in a PEM structure to @var{file}. The key itself is
1221 protected by (optional) @var{cipher} with @var{password}.
1223 @var{cipher} can be set to @code{nil} and the key will not be
1224 encrypted. @var{password} is ignored in this case.
1227 @defun ossl-pem-public-key pkey
1228 Return @var{pkey} as PEM encoded string.
1231 @defun ossl-pem-key pkey &optional cipher password
1232 Return @var{pkey} as PEM encoded string. The key itself is
1233 protected by (optional) @var{cipher} with @var{password}.
1235 @var{cipher} can be set to @code{nil} and the key will not be
1236 encrypted. @var{password} is ignored in this case.
1241 (ossl-pem-write-key "/tmp/mykey.pem" dsaexmpl)
1245 (let ((stored (ossl-pem-read-key "/tmp/mykey.pem")))
1246 (ossl-verify 'SHA1 "I owe you a beer" sig stored))
1251 (ossl-pem-public-key rsapub)
1252 @result{} "-----BEGIN PUBLIC KEY-----
1253 MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAtGE7JaGUsVIfLUJmzlkR
1254 qfB7CJjFlYU7tGmD7C1rBiGz0sjTlPwsMjwwCLP6byRvebVeDxGrxbeyZE3sSB4q
1255 oVbevhbwwBMY5+j/8q+3l7KbqoP9CGG40ZbEC6IOqFn8kOmliPdWUlogI1Gr4b7U
1256 R4F+TM6m3r3AQoxeqq+rR5kHat2mvBpxm0o8FZ2KW6ZCAkAXoA3NNCXtSUF9zA6A
1257 u3acUP4eiFAkS4Q6hIuZli4PzxvUugB5/ekyaa5cRzIEqIhh90mkpqjM9qpR15hk
1258 39qiM/SxXmLlncU534byldSgnoIse3tnia4WRBm2qK3zTr24zaBtTTXfmRJMWQwZ
1260 -----END PUBLIC KEY-----
1265 (ossl-pem-public-key rsaexmpl)
1266 @result{} "-----BEGIN PUBLIC KEY-----
1267 MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAtGE7JaGUsVIfLUJmzlkR
1268 qfB7CJjFlYU7tGmD7C1rBiGz0sjTlPwsMjwwCLP6byRvebVeDxGrxbeyZE3sSB4q
1269 oVbevhbwwBMY5+j/8q+3l7KbqoP9CGG40ZbEC6IOqFn8kOmliPdWUlogI1Gr4b7U
1270 R4F+TM6m3r3AQoxeqq+rR5kHat2mvBpxm0o8FZ2KW6ZCAkAXoA3NNCXtSUF9zA6A
1271 u3acUP4eiFAkS4Q6hIuZli4PzxvUugB5/ekyaa5cRzIEqIhh90mkpqjM9qpR15hk
1272 39qiM/SxXmLlncU534byldSgnoIse3tnia4WRBm2qK3zTr24zaBtTTXfmRJMWQwZ
1274 -----END PUBLIC KEY-----
1279 (ossl-pem-key rsaexmpl 'AES-256-CBC "foobar")
1280 @result{} "-----BEGIN ENCRYPTED PRIVATE KEY-----
1281 MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIk4VVj28lKIgCAggA
1282 MB0GCWCGSAFlAwQBKgQQ0uzDwfFB2m5ZUCt8K1YSvwSCBNCcQuY1S1c7Blsm7QlH
1283 iHji7xWcigj6U7U6IQ0y/a6+U/ku2/IQc4I/sjsYNj1ZKBjkHxuWqVtGvKD/AB/r
1284 2XFYkOpg7X2SvpVXuCkHk/B7l8ifQViqwu3k8r+8jHmLuxa21xysrTLOef8LmCkg
1285 ePaOArDKascJngpkUtMM269owh1ZBUSmKqQqR+jnpXw+dummdlr2tA0t3Bl+899q
1286 e6L7sZ330XRTnzyQUuZvBpV8bV0AlaI3jlPROu56MKiUiDU0n9lvzYegWGAJjOvS
1287 qYW3FPY/B7MczXCFQOmg3XWXWJ/2szRQnWvuM5imhwVF4YbPO30H6KG2sRc5u4Bs
1288 vym71CdlD77+YEw2dQ36bgjLE2v9aFIuuqqRlbNO1wUo1D0JFrN0ivGnliA6tCQ2
1289 tADHeEqKeXjCk4GM+rZB9d/kx2RqTgqu+JolaO1+8lxWRMT+aLj5EPN8zHOaRhDL
1290 3farG89PEOUvPRzkn+18laPBJ0o9AvwYC9Bmi072Lq7XtOIH0iELxY2RyQD0PLD2
1291 cLdt5tkQDfuUhrUJuhh3waMDa7qe9lMGnxsmlapZn5FY1kZ6gBO79BBu9sFmsr1x
1292 IRDT5PJc2V+BU9fn3Vu6WM3P56x7WfUjycqpvmu7yshW8D/8KRNYbeBIAXuRKCoJ
1293 dRIp/c+UWSPDVb68NikRvTRvj0vVrGMsesRkl89uL6liGarGghEV9lwNDQB5XN0q
1294 wZ+4LXP4DZQlBK3g9Bq7rL6F3ZuxGdThjQO6IAve6MltfOIN/x/schcoE41g2y0D
1295 0hn8vnDkGwWKFE59qOZ7/iQOOKJisF6MjxnkhlcTvG3ev2mrSsJHdiIoN9u8Zm6o
1296 Xca/k7JEs3rkr5MhrjxpGznq6Z5skEWEFFGD5XlXKYsHlP5YDxVXLED1cQHKcydC
1297 t2uPsB/Uqj4zl/lBc0/asQ8gyZiR2Fc5DHjUkmQ/5kH4LulvVLJgCC8JRs2AutBu
1298 DsqfvEj8uhmCuNYlsrOGrrOo/m2HPQ1DeoJcoL+H8KQG1WjPo0bnaV0Xlf6o+IkI
1299 G42pDGVeNSZDc+gqbXTzHDF0snOVDO7nfJ+kWmTFpHhI8Ht5H6SaaAIcgIQcWZgZ
1300 vA7e54XQ6HBUARFaPdw8kXyilu3lGunacjfipCdsOaF3WxGgdPmQTfuQOqglYhlc
1301 v/WPjyV9WgpEaJKM2Vcwb+CiOeteKnqp9ZLdmb4fZJNP2oIlKLtQSHsmdFGEr7BP
1302 7hxoi/kcD9QpuC9CHn1rZC99ZwWBa+UmK5s+P8LJRfi6a8qhR3gA6H/JGZLFiW0C
1303 Vrmir9u33UkroKfn+JTuMZV5e+U7YNFSJhX95nbLTIx44ItyztGlE5+lHMPA+N/p
1304 +OQM2F0kzfSZ2F1M3x3iO4VPzfEC6vNBpOOhhssSoL9ThNYlCQOVa+QemEjmVuEs
1305 PLluotrTI3Cetk4nanvj4HGb6KjnkU1JdQ6iKSEl2JnYWrmNNoB3N06/h/7DQpiy
1306 p/tevEVZQxK2cOklJrgcuNtVXe3c/9OVRKDuu3m1GstbQ4pcqijc55kuEtA0tmvn
1307 S5WFFj4/cVucd2K3IOHCttEfgDwVNDDzG2shBsKT1JDY4aDOBD3xe+ggstVkGmRL
1308 ocNNE7QyxF/GOgW9iTQr/yOp9A==
1309 -----END ENCRYPTED PRIVATE KEY-----
1315 @node openssl SSL/TLS
1316 @subsection Secure Network Layers
1318 The SSL/TLS support in this API is definitely not a copy of the
1319 underlying libssl functions. Instead we chose a higher level of access
1320 methods because for example @code{SSL_connect} does not work
1321 standalone, and having an elisp loop to check socket messages is
1322 probably not desirable.
1324 Also we chose to actually do what SSL/TLS stands for, namely to
1325 establish a transparent security layer on top of an existing network
1326 connection. That is, you can use the usual @code{open-network-stream}+
1327 @code{set-process-filter} + @code{process-send-string} chain and at some
1328 point after the establishment of the connection you can coat that
1329 connection with a secure layer. Of course, this is done transparently
1330 and your existing process filter or send-string commands will not notice
1333 @defun ossl-ssl-handshake process &optional method ca cert key serverp
1334 Perform a handshake on the network connection @var{process}.
1336 Return a ssl-conn object, or @code{nil} if the handshake failed.
1337 In the latter case, most likely the remote site cannot handle
1338 the specified method, requires a client certificate, or cannot
1341 Optional argument @var{method} indicates the SSL connection method,
1342 it can be one of @code{tls1} which is the default, @code{ssl23},
1343 @code{ssl2}, or @code{ssl3}.
1345 Optional argument @var{ca} indicates a CA certificate.
1346 See @code{ossl-ssl-inject-ca}.
1348 Optional arguments @var{cert} and @var{key} indicate a peer
1349 certificate and possibly a separate key file respectively.
1350 See @code{ossl-ssl-inject-peer-cert}.
1352 Optional argument @var{serverp} indicates whether to perform the
1353 handshake as a server if non-@code{nil}, and as a client otherwise.
1354 Note: In case of a handshake as server it is mandatory to provide
1355 a valid certificate and a corresponding key.
1358 Currently there are no high level `@code{open-ssl-stream}' (and such)
1359 functions. You have to invoke @code{open-network-stream} first and
1360 after establishing that connection @code{ossl-ssl-handshake} should
1363 Also, be sure to store the returned SSL-CONN object for later
1366 @defun ossl-ssl-finish ssl-conn
1367 Finish an SSL connection @var{ssl-conn}.
1369 Note: This may also finish the network connection.
1372 As noted above, not all peers finish the connection after finishing
1373 the SS-Layer but it is highly suggested to do so. Unpredictible
1374 results may occur when you keep using that connection.
1376 @defun ossl-ssl-inject-cert ssl_conn cert &optional key
1377 Add @var{cert} as the local certificate of @var{ssl-conn}.
1378 Optional argument @var{key} specifies a key file or evp-pkey,
1379 if @var{cert} does not contain it.
1381 Both, @var{cert} and @var{key} may be either a filename pointing
1382 to a PEM-encoded certificate and key respectively, or may be an
1386 @defun ossl-ssl-inject-ca ssl-conn ca
1387 Add @var{ca} to the pile of certificate authorities of @var{ssl-conn}.
1388 Also force a (re)verification of the remote peer certificate
1389 against @var{ca}. Return @code{t} if the injection was successful,
1390 @code{nil} otherwise.
1392 @var{ca} may be either a file name pointing to a PEM-encoded
1393 CA certificate, or may be a directory containing a valid
1394 bunch of CA certificates according to OpenSSL's CA path
1395 layout, or may also be an evp-pkey object.
1398 While @code{ossl-ssl-inject-ca} may be used even after handshaking
1399 with the remote peer, for example to introduce a certificate authority
1400 to verify the remote peer's identity with hindsight, the same does not
1401 apply to @code{ossl-ssl-inject-peer-cert} since local peer
1402 verification at the remote site can only take place at handshake time.
1403 Regard that function as convenience function.
1407 ;; @r{open a https connection to addons.mozilla.org}
1408 (setq p (open-network-stream "moz" "moz" "addons.mozilla.org" 443))
1409 @result{} #<network connection "moz" (443 . "addons.mozilla.org") state:run>
1411 (setq m (ossl-ssl-handshake p))
1412 @result{} #<OpenSSL socket layer: TLSv1 on top of
1413 #<secure network connection "moz"
1414 (443 . "addons.mozilla.org") state:run>>
1416 ;; @r{Let's examine @samp{p}}
1418 @result{} #<secure network connection "moz"
1419 (443 . "addons.mozilla.org") state:run>
1422 @result{} #<OpenSSL socket layer: dead>
1424 ;; @r{Let's examine @samp{p} again}
1426 @result{} #<network connection "moz"
1427 (443 . "addons.mozilla.org") state:exit>
1432 Offering a secure listening socket works quite similar as the
1433 following example shows.
1437 ;; @r{build the acceptor function}
1438 (defun my-acceptor (proc)
1439 (ossl-ssl-handshake proc 'ssl23 nil
1440 "/path/to/server.cert" "/path/to/server.key" t))
1441 @result{} my-acceptor
1443 ;; @r{establish the listening socket}
1444 (open-network-server-stream "listen" "listen"
1445 "localhost" 4432 'tcp #'my-acceptor)
1446 @result{} #<network server accepting connections "listen"
1447 (4432 . "localhost") state:run>
1451 @r{We connect using the OpenSSL command line interface.}
1453 freundt@@hlid:~$ openssl s_client -ssl3 -connect localhost:4432 \
1454 -CAfile /etc/ssl/CA/cacert.pem
1456 depth=1 /C=DE/ST=Berlin/O=hlidskjalf.org/OU=local CA/CN=hlid.hli
1457 dskjalf.org/emailAddress=freundt@@hlidskjalf.org
1459 depth=0 /C=DE/ST=Berlin/O=hlidskjalf.org/OU=ldap client freundt/
1460 CN=hlid.hlidskjalf.org/emailAddress=freundt@@hlidskjalf.org
1464 0 s:/C=DE/ST=Berlin/O=hlidskjalf.org/OU=ldap client freundt/CN=
1465 hlid.hlidskjalf.org/emailAddress=freundt@@hlidskjalf.org
1466 i:/C=DE/ST=Berlin/O=hlidskjalf.org/OU=local CA/CN=hlid.hlidsk
1467 jalf.org/emailAddress=freundt@@hlidskjalf.org
1470 -----BEGIN CERTIFICATE-----
1471 MIIEQzCCAyugAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBjzELMAkGA1UEBhMCREUx
1472 DzANBgNVBAgMBkJlcmxpbjEXMBUGA1UECgwOaGxpZHNramFsZi5vcmcxETAPBgNV
1473 BAsMCGxvY2FsIENBMRwwGgYDVQQDDBNobGlkLmhsaWRza2phbGYub3JnMSUwIwYJ
1474 KoZIhvcNAQkBFhZmcmV1bmR0QGhsaWRza2phbGYub3JnMB4XDTA2MDcxMjIxMDYy
1475 MloXDTA3MDcxMjIxMDYyMlowgZoxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJs
1476 aW4xFzAVBgNVBAoMDmhsaWRza2phbGYub3JnMRwwGgYDVQQLDBNsZGFwIGNsaWVu
1477 dCBmcmV1bmR0MRwwGgYDVQQDDBNobGlkLmhsaWRza2phbGYub3JnMSUwIwYJKoZI
1478 hvcNAQkBFhZmcmV1bmR0QGhsaWRza2phbGYub3JnMIIBIjANBgkqhkiG9w0BAQEF
1479 AAOCAQ8AMIIBCgKCAQEA5CYPHlmyemdoAdNsiemskMm33GYBSCOx1KZEWQ1cfgf0
1480 vVtpwue+/Nw4UbxYvtnS4ES8pWWEx/YeRyrEtbXg9SzXLSsNTrPT35xmysL87kIN
1481 nm8F4xGdlFQnvHJ4/55ieUVYi5aSlQtMKOON5HWUWmmWIscNnf3KyGy1lX1mEwhW
1482 xFYQ01npIz9az0zdBBqhV6mMejEul2vgwqL9lQy7khmwDwzoVdyyAz7C6Nj/7E6i
1483 gaxad9tc8luQJdMw+E6c67Stz68Om7CWfR7IMoqIx/ag7Ycy56dI8Td5LWvZ+JUG
1484 KMgHcbJ2mJIjQv3fgp7pIG2McPi91DwNLZhwJheshQIDAQABo4GcMIGZMAkGA1Ud
1485 EwQCMAAwEQYJYIZIAYb4QgEBBAQDAgTwMAsGA1UdDwQEAwIF4DAsBglghkgBhvhC
1486 AQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFKc+
1487 UFGPNVlARKv02s3Agq2q/2YfMB8GA1UdIwQYMBaAFAZIDPDiOBUx1RM67GJRPh+k
1488 y90DMA0GCSqGSIb3DQEBBQUAA4IBAQAAr8FoMuRaP7YVcnsYVR9Vv6wbjuSlO0rk
1489 /CtYs5V8QGa7TsGBz+0aBCHeDKegwhEkNowcJrqSlHiLYd4o2sXMqwAyszz1CKF6
1490 9PpZKXlhwZP5A9Hct9R0THV98f2qNCDOTTj9zxObnMIYJW4WLxGpgPTRTiERRdt3
1491 VP0aC2vEKb9xblfUQNAyBZKh6bkeKJVvd9WmnUwYkwGfH1+alNIhqCkRPjv8sw31
1492 ivzqspr2z19mtaYUKIN2u+mddJk7oeJIWNWwpaYicPR0rz9GOmVkgxIxMQAmtLnd
1493 ka47rxgbVZXtINcOZCNIcvX1hntqE5ItABunG3PGnNJwnqEQEfqJ
1494 -----END CERTIFICATE-----
1495 @c subject=/C=DE/ST=Berlin/O=hlidskjalf.org/OU=ldap client freundt/
1496 @c CN=hlid.hlidskjalf.org/emailAddress=freundt@@hlidskjalf.org
1497 @c issuer=/C=DE/ST=Berlin/O=hlidskjalf.org/OU=local CA/CN=hlid.hlid
1498 @c skjalf.org/emailAddress=freundt@@hlidskjalf.org
1500 @c No client certificate CA names sent
1502 @c SSL handshake has read 1289 bytes and written 489 bytes
1504 @c New, TLSv1/SSLv3, Cipher is AES256-SHA
1505 @c Server public key is 2048 bit
1506 @c Compression: zlib compression
1507 @c Expansion: zlib compression
1510 @c Cipher : AES256-SHA
1511 @c Session-ID: 05818FC08CA2A2A27157B4E33A568FA2CE0453633099DB03
1514 @c Master-Key: 8D8FEE3EAF1A85BB664AE779A4A4A0F6944EAA355497E162
1515 @c BAF60A7CD3DEAE6633C24116CC4BAF1013F78D2BFC919199
1517 @c PSK identity: None
1518 @c PSK identity hint: None
1519 @c Compression: 1 (zlib compression)
1520 @c Start Time: 1155549729
1521 @c Timeout : 7200 (sec)
1522 @c Verify return code: 0 (ok)
1529 which is exactly the expected output.
1531 At the moment it is @emph{not} possible to establish a server socket
1532 with an SSL acceptor @emph{and} connect to this with another network
1533 stream from within the same SXEmacs instance. This is because the SSL
1534 handshake is entirely on top of the process system and the event
1535 stream does not know about a special treatmeant of handshakes. In the
1536 above scenario both connections would block each other since the
1537 handshake is a multiple turn procedure with a fixed order, but the
1538 event loop does not know about the correct order, hence both networks
1539 streams would exit prematurely because of timeouts.
1541 However, the above examples are actually all you need to acquire
1542 secure sockets. In order to communicate over the socket the usual
1543 tools can be used. @xref{Processes}.
1547 ;; @r{invoke a local postfix and negotiate a TLSv1 session}
1548 (let ((p (open-network-stream "smtps" "smtps" "localhost" 25)))
1549 (process-send-string p "STARTTLS\r\n")
1550 (ossl-ssl-handshake p)
1551 (process-send-string p "EHLO foo.bar.tld\r\n")
1552 (process-send-string p "QUIT\r\n"))
1557 @r{we look at the resulting process buffer}
1558 @r{TLS becomes active at the third line (reply code 250)}
1559 ---------- Buffer: smtps ----------
1560 220 fluch.fresse.org ESMTP Postfix
1561 220 2.0.0 Ready to start TLS
1562 250-fluch.fresse.org
1567 250-ENHANCEDSTATUSCODES
1572 Process smtps exited abnormally with code 256
1574 ---------- Buffer: smtps ----------
1578 Once a successful handshake has been done the returned ssl-conn object
1579 can be used to determine and tune useful things. The following two
1580 functions affect the interlinkage between the secure socket and the
1581 ordinary network socket.
1583 @defun ossl-ssl-proselytise-process ssl-conn
1584 Convert the underlying process of @var{ssl-conn} into a secure
1585 network connection object.
1588 @defun ossl-ssl-unproselytise-process ssl-conn
1589 Convert the underlying process of @var{ssl-conn} into an ordinary
1590 network connection object.
1593 After handshaking the secure layer is transparently linked to the
1594 network socket automatically hence @code{ossl-ssl-proselytise-process}
1595 need not be called explicitly. That is also why the buffer output in
1596 the above example remained readable. In contrast
1597 @code{ossl-ssl-unproselytise-process} unleashes the link between
1598 secure socket and network stream. Having access to the raw
1599 (encrypted) SSL stream may have advantages when a program is supposed
1600 to just forward the stream to somewhere.
1604 (let ((p (open-network-stream "smtps" "smtps" "localhost" 25)))
1605 (process-send-string p "STARTTLS\r\n")
1606 (let ((sock (ossl-ssl-handshake p)))
1607 (ossl-ssl-unproselytise-process sock)
1608 (ossl-ssl-write sock "EHLO foo.bar.tld\r\n")
1609 (ossl-ssl-write sock "QUIT\r\n")))
1614 ---------- Buffer: smtps ----------
1615 220 fluch.fresse.org ESMTP Postfix
1616 220 2.0.0 Ready to start TLS
1621 Process smtps exited abnormally with code 256
1623 ---------- Buffer: smtps ----------
1627 The snipped portion is a bunch of binary data. Nonetheless, as can be
1628 seen in the example sending data via @code{process-send-string} will
1629 not work after unproselytising. There are special I/O functions for
1632 @defun ossl-ssl-read ssl-conn string
1633 Return the cleartext of @var{string} which is assumed to be a complete
1634 block of data sent through @var{ssl-conn}.
1636 @c does not work at the moment
1638 @defun ossl-ssl-write ssl-conn string
1639 Send @var{string} to the tunnel @var{ssl-conn}.
1642 After all, unlinking the two layers currently only works in one
1643 direction. The ssl-conn object will always know its parent
1646 @defun ossl-ssl-parent ssl-conn
1647 Return the underlying parent layer of @var{ssl-conn}.
1651 In the linked case the converse can be determined by
1652 @code{process-type-data}, @pxref{Processes}.
1655 In order to obtain information about the ciphers which protect the
1656 tunnel communication we provide a bunch of useful functions. At the
1657 moment ssl-ciphers are automatically negotiated with the remote site
1658 during the handshake procedure and cannot be explicitly requested or
1661 @defun ossl-ssl-cipher-version ssl-conn
1662 Return the protocol version of the tunnel @var{ssl-conn}.
1665 @defun ossl-ssl-cipher-name ssl-conn
1666 Return the name of the current cipher used in the tunnel @var{ssl-conn}.
1669 @defun ossl-ssl-cipher-names ssl-conn
1670 Return the names of all supported ciphers in the tunnel @var{ssl-conn}.
1673 @defun ossl-ssl-cipher-bits ssl-conn
1674 Return the number of effective bits of the current cipher
1678 @defun ossl-ssl-cipher-description ssl-conn
1679 Return a description of the current cipher used in the tunnel
1684 Nowadays secure socket layers not only provide security but also
1685 authenticity. While ciphers are the atoms for the former,
1686 certificates play the major role for the latter. However,
1687 authenticity is quite optional within the SSL protocol. That is why
1688 we often append the phrase ``if present'' in the documentation strings
1689 of the following functions.
1691 @defun ossl-ssl-cert ssl-conn
1692 Return the local peer's certificate of @var{ssl-conn} if present,
1693 @code{nil} otherwise.
1696 @defun ossl-ssl-peer-cert ssl-conn
1697 Return the remote peer's certificate of @var{ssl-conn} if present,
1698 @code{nil} otherwise.
1701 @defun ossl-ssl-peer-cert-chain ssl-conn
1702 Return the certificate chain of @var{ssl-conn} as a list of
1706 @defun ossl-ssl-verify-certificate ssl-conn
1707 Return a verify code of @var{ssl-conn}.
1709 The result is a cons cell with the numeric verify code in the car and
1710 a verbose string in the cdr.
1715 (let* ((str (open-network-stream "th" "th" "www.thawte.com" 443))
1716 (sslc (ossl-ssl-handshake str 'ssl3)))
1717 (ossl-ssl-peer-cert-chain sslc)
1718 @result{} (#<OpenSSL X509 Certificate iss:/C=ZA/
1719 O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
1720 sub:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary
1721 Certification Authority; RSA public key, size 1024>
1722 #<OpenSSL X509 Certificate iss:/C=ZA/ST=Western Cape/
1723 L=Cape Town/O=Thawte Consulting (Pty) Ltd/OU=Security/
1724 CN=www.thawte.com sub:/C=ZA/O=Thawte Consulting (Pty) Ltd./
1725 CN=Thawte SGC CA; RSA public key, size 1024>)
1730 Certificates which stem from one of these functions are usually
1731 wrapped in an evp-pkey object. In contrast to the public-key handling
1732 functions above, certificates usually carry a lot more information.
1733 Hence evp-pkey objects with certificate data occupy an additional
1734 slot to store X509- and ASN1-specific data. Nonetheless, passing
1735 evp-pkey objects without X509/ASN1 data will not do harm.
1737 Again, certificate specific data in an SSL connection are read-only at
1738 the moment. Only the two injection functions, and the handshake
1739 function provide a limited form of influence.
1741 @defun ossl-x509-subject cert
1742 Return the certificate subject of @var{cert} (an evp-pkey object).
1744 This will return a string in LDAP syntax.
1747 @defun ossl-x509-issuer cert
1748 Return the certificate issuer of @var{cert} (an evp-pkey object),
1749 that is the organisation which signed the certificate.
1751 This will return a string in LDAP syntax.
1754 @defun ossl-x509-serial cert
1755 Return the certificate serial of @var{cert} (an evp-pkey object).
1758 @defun ossl-x509-not-before cert
1759 Return the certificate valid-not-before time of @var{cert}.
1762 @defun ossl-x509-not-after cert
1763 Return the certificate valid-not-after time of @var{cert}.
1766 @defun ossl-x509-signature-type cert
1767 Return the signature type of @var{cert}.
1772 (let ((p (open-network-stream "go" "go" "gna.org" 443))
1773 (s (ossl-ssl-handshake p 'tls1)))
1774 (setq c (ossl-ssl-peer-cert s)))
1775 @result{} #<OpenSSL X509 Certificate iss:/ST=The Internet/
1776 O=The OpenSSL Project/CN=www.openssl.org/
1777 emailAddress=openssl-team@@openssl.org
1778 sub:/ST=The Internet/O=The OpenSSL Project/
1779 OU=Certificate Authority/CN=OpenSSL CA/
1780 emailAddress=openssl-team@@openssl.org;
1781 RSA public key, size 1024>
1785 (ossl-x509-subject c)
1786 @result{} "/ST=The Internet/O=The OpenSSL Project/CN=www.openssl.org/
1787 emailAddress=openssl-team@@openssl.org"
1791 (ossl-x509-issuer c)
1792 @result{} "/ST=The Internet/O=The OpenSSL Project/
1793 OU=Certificate Authority/CN=OpenSSL CA/
1794 emailAddress=openssl-team@@openssl.org"
1798 (ossl-x509-serial c)
1803 (ossl-x509-not-before c)
1804 @result{} "020802062727Z"
1808 (ossl-x509-not-after c)
1809 @result{} "030802062727Z"
1813 (ossl-x509-signature-type c)