Build Fix -- compatibility issue with newer autoconf
[sxemacs] / info / lispref / openssl.texi
1 @c -*-texinfo-*-
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
6
7 @node OpenSSL Support, Enhanced Number Types, PostgreSQL Support, Top
8 @comment  node-name,  next,  previous,  up
9 @chapter OpenSSL Support
10 @cindex OpenSSL
11
12 SXEmacs can be linked with OpenSSL libcrypto and libssl to provide
13 a comprehensive gateway to cryptographic and related functions.
14
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
20
21
22 @menu
23 * Building SXEmacs with OpenSSL support::
24 * SXEmacs OpenSSL API::
25 @end menu
26
27
28 @node Building SXEmacs with OpenSSL support, SXEmacs OpenSSL API, OpenSSL Support, OpenSSL Support
29 @section Building SXEmacs with OpenSSL support
30
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
35 be obtained at
36 @example
37 @url{http://www.openssl.org}
38 @end example
39
40 For most systems the following snippet can be used to build a
41 reasonably feature-rich and yet fast library:
42
43 @example
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
47 @end example
48
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
52 for details.
53
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.
58
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.
63
64
65 @node SXEmacs OpenSSL API,  , Building SXEmacs with OpenSSL support, OpenSSL Support
66 @section SXEmacs OpenSSL API
67
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?
71
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.
77
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.
82
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.
87
88 For convenience, we denote the elisp implementation of OpenSSL with openssl
89 whereas the distributed library package from @url{http://www.openssl.org}
90 is denoted OpenSSL.
91
92
93 @menu
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
101 @end menu
102
103
104 @node openssl General, openssl RAND, SXEmacs OpenSSL API, SXEmacs OpenSSL API
105 @subsection General information
106
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.
112
113 @defun ossl-version
114 Return a descriptive version number of the OpenSSL in use.
115
116 The version string should be identical to the output of @code{openssl
117 version} in a shell.
118
119 @example
120 @group
121 (ossl-version)
122   @result{} "OpenSSL 0.9.9-dev XX xxx XXXX"
123 @end group
124 @end example
125 @end defun
126
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.
130 @end defun
131
132 @defun ossl-available-ciphers
133 Return a list of cipher algorithms in the underlying crypto library.
134 This yields a list of symbols.
135 @end defun
136
137 @example
138 @group
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)
144 @end group
145
146 @group
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)
164 @end group
165 @end example
166
167 @noindent
168 These two functions are most useful to conditionalise like
169 @example
170 (when (member 'MD4 (ossl-available-digests))
171   @dots{})
172 @end example
173
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.
180
181
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.
185
186 @defun ossl-digest-size digest
187 Return the hash length of @var{digest} in bytes.
188
189 @example
190 (ossl-digest-size 'MD5)
191   @result{} 16
192 (ossl-digest-size 'SHA512)
193   @result{} 64
194 @end example
195 @end defun
196
197 @defun ossl-digest-block-size digest
198 Return the block size of @var{digest} in bytes.
199
200 @example
201 (ossl-digest-block-size 'MD5)
202   @result{} 64
203 (ossl-digest-block-size 'SHA512)
204   @result{} 128
205 @end example
206 @end defun
207
208 @defun ossl-cipher-key-length cipher
209 Return the effective key size of @var{cipher} in bytes.
210
211 @example
212 (ossl-cipher-key-length 'RC4)
213   @result{} 16
214 (ossl-cipher-key-length 'CAMELLIA-256-CBC)
215   @result{} 32
216 @end example
217 @end defun
218
219 @defun ossl-cipher-iv-length cipher
220 Return the initialisation vector length of @var{cipher} in bytes.
221
222 @example
223 (ossl-cipher-iv-length 'idea-cbc)
224   @result{} 8
225 (ossl-cipher-iv-length 'aes-256-cbc)
226   @result{} 16
227 @end example
228 @end defun
229
230 @defun ossl-cipher-block-size cipher
231 Return the block size of @var{cipher} in bytes.
232
233 @example
234 (ossl-cipher-block-size 'aes-256-cbc)
235   @result{} 16
236 (ossl-cipher-block-size 'rc4)
237   @result{} 1
238 @end example
239 @end defun
240
241 @defun ossl-cipher-mode cipher
242 Return the operation mode of @var{cipher}.
243
244 @example
245 (ossl-cipher-mode 'rc4)
246   @result{} stream
247 (ossl-cipher-mode 'aes-192-ofb)
248   @result{} ofb
249 @end example
250 @end defun
251
252
253 The openssl API provides following features:
254 @itemize
255 @item
256 @code{'openssl} when fundamental functions are available
257 @item
258 @code{'openssl-rsa} when RSA keys are available
259 @item
260 @code{'openssl-dsa} when DSA keys are available
261 @item
262 @code{'openssl-ec} when elliptic curves are available
263 @item
264 @code{'openssl-dh} when DH keys are available
265 @item
266 @code{'openssl-ssl} when the TLS/SSL and X509 capabilities are
267 available
268 @end itemize
269
270
271 @node openssl RAND, openssl MD, openssl General, SXEmacs OpenSSL API
272 @subsection (Pseudo) Random Numbers
273
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
277 of cryptography.
278
279 @defun ossl-rand-bytes count
280 Return @var{count} bytes of randomness.
281
282 Note: You probably want to put a wrapping encoder function
283 (like @code{base16-encode-string}) around it, since this returns
284 binary string data.
285 @end defun
286
287 @example
288 @group
289 (base16-encode-string (ossl-rand-bytes 8))
290   @result{} "5a78acd572984bdf"
291 @end group
292 @end example
293
294 @noindent
295 Modern systems supply more sophisticated sources for random data, so
296 called entropy gathering daemons.
297
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}.
301
302 Note: You probably want to put a wrapping encoder function
303 (like @code{base16-encode-string}) around it, since this returns
304 binary string data.
305 @end defun
306
307 @example
308 @group
309 (base16-encode-string (ossl-rand-bytes-egd 8 "/var/run/egd-pool"))
310   @result{} "59342a240b356a04"
311 @end group
312 @end example
313
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.
320
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.
327
328
329 @node openssl MD, openssl HMAC, openssl RAND, SXEmacs OpenSSL API
330 @subsection Message Digests (aka hashes)
331
332   Message digests are widely used in modern information
333 infrastructure.  They are derived from (collision free) one-way hash
334 functions.
335
336   A hash function (such as @samp{md5} or @samp{sha1}) is a function
337 with following properties:
338
339 @enumerate
340 @item reduction: data of arbitrary length is mapped onto data
341   of fixed length
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.
349 @end enumerate
350
351 Often, the last property is too weak in practice, therefore
352 most hash functions comply with the even stronger:
353
354 @itemize
355 @item collision-freeness: it is hard to compute two different
356   source data which result in the same hash value.
357 @end itemize
358
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.
363
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
367 plaintext.
368
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.
373
374   Okay, after this short introduction to message digests, here are the
375 functions to access them from elisp.
376
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}.
381
382 Note: You probably want to put a wrapping encoder function (like
383 @code{base16-encode-string}) around it, since this returns binary
384 string data.
385 @end defun
386
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.
390
391 @defun ossl-digest digest file
392 Return the message digest of the contents of @var{file} computed by
393 @var{digest}.
394 @var{digest} may be one of the OpenSSL digests you have compiled.
395 See @code{ossl-available-digests}.
396
397 Note: You probably want to put a wrapping encoder function (like
398 @code{base16-encode-string}) around it, since this returns binary
399 string data.
400 @end defun
401
402   The current implementation of the OpenSSL API in SXEmacs uses the
403 EVP layer of OpenSSL to access the digests.
404
405 @example
406 @group
407 (base16-encode-string (ossl-digest 'md5 "hash me"))
408   @result{} "17b31dce96b9d6c6d0a6ba95f47796fb"
409 @end group
410
411 @group
412 (base16-encode-string (ossl-digest 'SHA1 "hash me"))
413   @result{} "43f932e4f7c6ecd136a695b7008694bb69d517bd""
414 @end group
415 @end example
416
417 Let's do some performance tests.
418
419 @example
420 @group
421 ;; @r{this is the SXEmacs built-in implementation of MD5}
422 (let ((st (current-btime)))
423   (dotimes (i 100000)
424     (md5 "Some test string to hash"))
425   (- (current-btime) st))
426   @result{} 6194289
427   ;; @r{time in microseconds, so this is about 6 seconds}
428 @end group
429
430 @group
431 ;; @r{now compare to the OpenSSL implementation}
432 (let ((st (current-btime)))
433   (dotimes (i 100000)
434     (ossl-digest 'md5 "Some test string to hash"))
435   (- (current-btime) st))
436   @result{} 10589408
437   ;; @r{which is about 10 seconds}
438 @end group
439 @end example
440
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.
444
445 @example
446 @group
447 (length (buffer-string))
448   @result{} 16861
449 @end group
450
451 @group
452 ;; @r{we begin with the built-in implementation}
453 (let ((st (current-btime))
454       (b (buffer-string)))
455   (dotimes (i 100000)
456     (md5 b))
457   (- (current-btime) st))
458   @result{} 74350982
459   ;; @r{which is about 74 seconds}
460 @end group
461
462 @group
463 ;; @r{compare to the OpenSSL API}
464 (let ((st (current-btime))
465       (b (buffer-string)))
466   (dotimes (i 100000)
467     (base16-encode-string
468       (ossl-digest 'md5 b)))
469   (- (current-btime) st))
470   @result{} 31697926
471   ;; @r{which is about 31 seconds}
472 @end group
473 @end example
474
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.
479
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
483 file.
484
485 @example
486 @group
487 freundt@@muck:~> ls -sh ~/temp/pdftex-1.30.3.tar.bz2
488 3.2M /home/freundt/temp/pdftex-1.30.3.tar.bz2
489 @end group
490
491 @group
492 (let ((st (current-btime))
493       (b (with-temp-buffer
494            (insert-file-contents-literally
495             "~/temp/pdftex-1.30.3.tar.bz2")
496            (buffer-string))))
497   (dotimes (i 100)
498     (md5 b))
499   (- (current-btime) st))
500   @result{} 22729718
501   ;; @r{which is about 22 seconds}
502 @end group
503 @end example
504
505 Compared to the file stream function @code{ossl-digest-file}:
506
507 @example
508 @group
509 (let ((st (current-btime)))
510   (dotimes (i 100)
511     (ossl-digest-file 'md5 "~/temp/pdftex-1.30.3.tar.bz2"))
512   (- (current-btime) st))
513   @result{} 4189695
514   ;; @r{which is about 4 seconds}
515 @end group
516 @end example
517
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
520
521 @example
522 @group
523 (let ((st (current-btime)))
524   (dotimes (i 500)
525     (sha1-binary "a short test string"))
526   (- (current-btime) st))
527   @result{} 2574326
528   ;; @r{which is about 2.5 seconds}
529 @end group
530
531 @group
532   ;; @r{the same with the OpenSSL API}
533 (let ((st (current-btime)))
534   (dotimes (i 500)
535     (ossl-digest 'sha1 "a short test string"))
536   (- (current-btime) st))
537   @result{} 31378
538   ;; @r{which is about 0.03 seconds}
539 @end group
540 @end example
541
542   These results suggest to always use the openssl interface in favour of
543 other implementations.
544
545
546 @node openssl HMAC, openssl CIPHER, openssl MD, SXEmacs OpenSSL API
547 @subsection Message Authentication Codes (aka keyed hashes)
548
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.
555
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}.
559
560 Note: You probably want to put a wrapping encoder function
561 (like @code{base16-encode-string}) around it, since this returns
562 binary string data.
563 @end defun
564
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
569 digest.
570
571 @example
572 @group
573 (base16-encode-string
574  (ossl-hmac 'SHA512 "string to hash" "secret"))
575   @result{} "62351dfae2030fb28058a2aeba6ce3597d803575c120109ed6cfee240d7
576       50e71ffff1d8dfc8d52e666549dcb6ba95fb4d550bdc9f31178c19fecb4
577       30ddb7b565"
578 @end group
579
580 @group
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
586       f389436ab0"
587 @end group
588 @end example
589
590
591 @node openssl CIPHER, openssl PKEY, openssl HMAC, SXEmacs OpenSSL API
592 @subsection Symmetric Cryptography
593
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
597 single unit.
598
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.
603
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}.
608
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}.
611
612 @var{digest} (a symbol) is the message digest to use.
613 Valid digests can be obtained by @code{ossl-available-digests}.
614
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.
617
618 @var{password} is an arbitrary string which is processed to derive a
619 unique key and IV.
620
621 @var{count} (a positive integer) is the iteration count to use. This
622 indicates how often the hash algorithm is called recursively.
623
624 Note: You probably want to put a wrapping encoder function
625 (like @code{base16-encode-string}) around it, since this returns
626 binary string data.
627 @end defun
628
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
632 crashes.
633
634 @example
635 @group
636 (base16-encode-string
637  (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "somesalt" "secret" 1))
638   @result{} "bd2b1aaf7ef4f09be9f52ce2d8d599674d81aa9d6a4421696dc4d93dd0619d68"
639 @end group
640
641 @group
642 (base16-encode-string
643  (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "diffsalt" "secret" 1))
644   @result{} "bd2b1aaf7ef4f09be9f52ce2d8d599674d81aa9d6a4421696dc4d93dd0619d68"
645 @end group
646
647 @group
648 (base16-encode-string
649  (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "diffsalt" "retsec" 1))
650   @result{} "38515c1868bcab470075ec32bc79b0ed1aa945de95d2261991ea840921e7747b"
651 @end group
652 @end example
653
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
657 vector inside:
658
659 @example
660 @group
661 (object-plist
662  (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "somesalt" "secret" 1))
663   @result{} (iv "????????????????")
664 @end group
665
666 @group
667 (base16-encode-string
668  (get
669   (ossl-bytes-to-key 'AES-256-OFB 'SHA512 "somesalt" "secret" 1)
670   'iv))
671   @result{} "2ce56b4d64a9ef097761ced99e0f6726"
672 @end group
673 @end example
674
675
676 @defun ossl-encrypt cipher string key &optional iv
677 Return the cipher of @var{string} computed by @var{cipher} under
678 @var{key}.
679
680 @var{cipher} (a symbol) may be one of the OpenSSL cipher algorithms
681 you have compiled. See @code{ossl-available-ciphers}.
682
683 @var{string} is the text to be encrypted.
684
685 @var{key} should be a key generated suitably for this cipher, for
686 example by @code{ossl-bytes-to-key}.
687
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.
692
693 Note: You probably want to put a wrapping encoder function
694 (like @code{base16-encode-string}) around it, since this returns
695 binary string data.
696 @end defun
697
698 @defun ossl-decrypt cipher string key &optional iv
699 Return the deciphered version of @var{string} computed by @var{cipher}
700 under @var{key}.
701
702 @var{cipher} (a symbol) may be one of the OpenSSL cipher algorithms
703 you have compiled. See @code{ossl-available-ciphers}.
704
705 @var{string} is the text to be decrypted.
706
707 @var{key} should be a key generated suitably for this cipher, for
708 example by @code{ossl-bytes-to-key}.
709
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.
714 @end defun
715
716 @example
717 @group
718 (base16-encode-string
719  (let ((key
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"
723 @end group
724
725 @group
726 (let ((key
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."
731 @end group
732
733 @group
734 (let ((key
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{} "?????????????????"
739 @end group
740 @end example
741
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.
744
745   As for message digests, there are two companion functions which
746 directly work on files.
747
748 @defun ossl-encrypt-file cipher file key &optional iv outfile
749 Return the encrypted contents of @var{file} computed by @var{cipher}
750 under @var{key}.
751
752 @var{cipher} (a symbol) may be one of the OpenSSL cipher algorithms
753 you have compiled. See @code{ossl-available-ciphers}.
754
755 @var{file} is the file to be encrypted.
756
757 @var{key} should be a key generated suitably for this
758 cipher, for example by @code{ossl-bytes-to-key}.
759
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.
764
765 Optional fifth argument @var{outfile} may specify a file to have the
766 encrypted data redirected.
767
768 Note: You probably want to put a wrapping encoder function
769 (like @code{base16-encode-string}) around it, since this returns
770 binary string data.
771 @end defun
772
773
774 @defun ossl-decrypt-file cipher file key &optional iv outfile
775 Return the deciphered version of @var{file} computed by @var{cipher}
776 under @var{key}.
777
778 @var{cipher} (a symbol) may be one of the OpenSSL cipher algorithms
779 you have compiled. See @code{ossl-available-ciphers}.
780
781 @var{file} is the file to be decrypted.
782
783 @var{key} should be a key generated suitably for this
784 cipher, for example by @code{ossl-bytes-to-key}.
785
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.
790
791 Optional fifth argument @var{outfile} may specify a file to have the
792 decrypted data redirected.
793 @end defun
794
795
796
797 @node openssl PKEY, openssl SSL/TLS, openssl CIPHER, SXEmacs OpenSSL API
798 @subsection public key crypto systems
799
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
806 keys.
807
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.
811
812 @defun ossl-pkey-p object
813 Return @code{t} if @var{object} is a pkey, @code{nil} otherwise.
814 @end defun
815
816 @defun ossl-pkey-size pkey
817 Return the size a public key @var{pkey} in bits.
818 @end defun
819
820 @defun ossl-pkey-private-p pkey
821 Return non-@code{nil} if @var{pkey} contains private data.
822
823 Note: This function is not native OpenSSL.
824 @end defun
825
826 @defun ossl-pkey-get-public pkey
827 Return a copy of @var{pkey} stripped by the private data.
828
829 Note: This function is not native OpenSSL.
830 @end defun
831
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
837 a subkey check.
838
839 @noindent
840 Note: At the moment we do not provide the creation of DH-keys.
841
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}.
846
847 @defun ossl-rsa-generate-key bits exp
848 Return an RSA public key with of length @var{bits} and exponent @var{exp}.
849 @end defun
850
851 @defun ossl-rsa-pkey-p pkey
852 Return @code{t} iff @var{pkey} is of RSA type.
853 @end defun
854
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.
859
860 Note: This function is not native OpenSSL.
861 @end defun
862
863 @example
864 @group
865 (setq rsaexmpl (ossl-rsa-generate-key 2048 3))
866   @result{} #<OpenSSL RSA private/public key, size 2048>
867 (ossl-rsa-pkey-p rsaexmpl)
868   @result{} t
869 (ossl-pkey-private-p rsaexmpl)
870   @result{} t
871 @end group
872
873 @group
874 (setq rsapub (ossl-pkey-get-public rsaexmpl))
875   @result{} #<OpenSSL RSA public key, size 2048>
876 (ossl-pkey-private-p rsapub)
877   @result{} nil
878 (ossl-rsa-subkey-p rsapub rsaexmpl)
879   @result{} t
880 @end group
881 @end example
882
883
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.
888
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}.
892 @end defun
893
894 @defun ossl-dsa-pkey-p pkey
895 Return @code{t} if @var{pkey} is of DSA type, @code{nil} otherwise.
896 @end defun
897
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.
902
903 Note: This function is not native OpenSSL.
904 @end defun
905
906 @example
907 @group
908 (setq dsaexmpl (ossl-dsa-generate-key 1024))
909   @result{} #<OpenSSL DSA private/public key, size 384>
910 (ossl-dsa-pkey-p dsaexmpl)
911   @result{} t
912 (ossl-pkey-private-p dsaexmpl)
913   @result{} t
914 @end group
915
916 @group
917 (setq dsapub (ossl-pkey-get-public dsaexmpl))
918   @result{} #<OpenSSL DSA public key, size 384>
919 (ossl-pkey-private-p dsapub)
920   @result{} nil
921 (ossl-dsa-subkey-p dsapub dsaexmpl)
922   @result{} t
923 @end group
924 @end example
925
926
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.
932
933 @defun ossl-ec-available-curves
934 Return a list of builtin elliptic curves.
935 @end defun
936
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)}.
940
941 Note: At the moment we do not support creating custom curves.
942 @end defun
943
944 @defun ossl-ec-pkey-p pkey
945 Return @code{t} if @var{pkey} is of EC type, @code{nil} otherwise.
946 @end defun
947
948 @example
949 @group
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
966       secp112r2 secp112r1)
967 @end group
968
969 @group
970 (setq ecexmpl (ossl-ec-generate-key 'secp224r1))
971   @result{} #<OpenSSL EC private/public key, size 512>
972 (ossl-ec-pkey-p ecexmpl)
973   => t
974 (ossl-pkey-private-p ecexmpl)
975   @result{} t
976 @end group
977
978 @group
979 (setq ecpub (ossl-pkey-get-public ecexmpl))
980   @result{} #<OpenSSL EC public key, size 512>
981 (ossl-pkey-private-p ecpub)
982   @result{} nil
983 @end group
984 @end example
985
986
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.
990
991 @defun ossl-dh-pkey-p pkey
992 Return @code{t} if @var{pkey} is of DH type, @code{nil} otherwise.
993 @end defun
994
995
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.
999
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.
1003
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
1006 public key.
1007
1008 The envelope returned is a list
1009 @code{(@var{encrypted_string} @var{encrypted_key} @var{encrypted_iv})}
1010 where
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
1014
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.
1018 @end defun
1019
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}.
1023
1024 @itemize
1025 @item
1026 @var{cipher} is the cipher to use (the same as in @code{ossl-seal})
1027 @item
1028 @var{string} is the encrypted message
1029 @item
1030 @var{pkey} is the private key
1031 @item
1032 @var{ekey} is the encrypted random key
1033 @item
1034 @var{eiv} is the encrypted iv
1035 @end itemize
1036 @end defun
1037
1038 @c  * - HYBRID
1039 @c  *  ossl-seal - gateway to public key hybrid (envelope) encryption
1040 @c  *  ossl-open - gateway to public key hybrid (envelope) decryption
1041 @noindent
1042 In the following example we reuse the keys generated above.
1043
1044 @example
1045 @group
1046 (let ((envl
1047        (ossl-seal 'AES-256-CBC "I do not want to tell" rsaexmpl)))
1048   (setq str (car envl)
1049         key (nth 1 envl)
1050         iv (nth 2 envl))
1051   (mapcar #'base16-encode-string envl))
1052   @result{} ("0e6a38b28efea3ca4901b268c141d7ac23ed5f8fa598d23d9846fe3ec1
1053        47278e"
1054       "167911a73b0a228b24e78bdd37197ec95b21bed3bbd62d1915d8fac791
1055        7915fd49fdd9774e7906ca53ed3bf4fb20de8339e628d469a496f7351c
1056        06fddda49b71c90e73e31c406cfb0f0fb7411d1c9d49842603c45415cc
1057        3a8f660c728e8f05c6479d004f5068a7969294b4cc81e13dd257df37dc
1058        886b11266a3ccba576396d200ebb1a3e8f7185fdbc6de40b63964562f9
1059        1cbe39118a07415c030fd4c3e25bbe2a64b2ab635b2ef9a71a5ddeeaf0
1060        4a73d7cd04ad334d1de04228db5a9fb9aebfa6a9dc9d76af5ec329b360
1061        d1cd8da45868450a3bc5c41bba95a0ad74439f7d5edffcdf7dff09c296
1062        35ae13215be1ae55f5d2b5e97d6a4d523470eef050b07193"
1063       "ab458ccb46cbc092c31614e997cd176b")
1064 @end group
1065
1066 @group
1067 (ossl-open 'AES-256-CBC str rsaexmpl key iv)
1068   @result{} "I do not want to tell"
1069 @end group
1070 @end example
1071
1072 @noindent
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.
1078
1079 @example
1080 @group
1081 (let ((envl
1082        (ossl-seal 'AES-256-CBC "I do not want to tell" rsapub)))
1083   (setq str (car envl)
1084         key (nth 1 envl)
1085         iv (nth 2 envl))
1086   (mapcar #'base16-encode-string envl))
1087   @result{} ("93a5b3f2eb5a2eaee44805150717bb325b4e90be947591cc46b7819d3f
1088        4ec284"
1089       "300b9ab5a79524fdcb40fbed6bae7e9c470baa0d230f9b97c9b35de442
1090        62f82b626ef7668329d34cffc3eeddf535a879e974825e984c7e045c0a
1091        526b3b58453ae55926af519400f32c4aee7115088068fcb6fc75ce78c5
1092        b6d61bbaf90f0c4aff1d83efd63c45c62989c29efda187bcbd94edf9f1
1093        427ec8dce22cd6333e8196120285dc5bb224b9d7e9ecfb23e016475706
1094        5da6f999560d010adaf0465b108b2a84989ff8bd17778b61875f633a35
1095        a02c2cc1fdf3a3e50ad4a5fb7ad9a05b1a3a1818a21f3d7c71a33949f6
1096        437ee64bee60e1ae92ebea43ca524b15344a7fc2712e9758b98f1b2c9d
1097        c8ad3d074486f0d35fece7bf7b6ce979fa760aa7bd5854b2"
1098       "6979d574e8bc10dfddefd4cb017186a2")
1099 @end group
1100
1101 @group
1102 (ossl-open 'AES-256-CBC str rsaexmpl key iv)
1103   @result{} "I do not want to tell"
1104 @end group
1105
1106 @group
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
1110 @end group
1111 @end example
1112
1113 @noindent
1114 Also note you cannot use DSA keys for sealing.  They are exclusively
1115 for signatures.
1116
1117
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
1122 of the key.
1123
1124 @defun ossl-sign digest string pkey
1125 Return a signature obtained by signing @var{string} under @var{digest}
1126 with @var{pkey}.
1127
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}.
1130
1131 Note: Due to some relationship between the public key system and the
1132 message digest you cannot use every digest algorithm with every
1133 private key type.
1134 The most certain results will be achieved using
1135 RSA keys with RSA-* digests, DSA keys with DSA-* digests.
1136
1137 See @code{ossl-available-digests}.
1138
1139 Note: You probably want to put a wrapping encoder function
1140 (like @code{base16-encode-string}) around it, since this returns
1141 binary string data.
1142 @end defun
1143
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}.
1147
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
1151 are equal.
1152
1153 @itemize
1154 @item
1155 @var{digest} is the digest to use (the same as in @code{ossl-sign})
1156 @item
1157 @var{string} is the message
1158 @item
1159 @var{sig} is the signature of message
1160 @item
1161 @var{pkey} is the public key
1162 @end itemize
1163 @end defun
1164
1165 @c  * - SIGN
1166 @c  *  ossl-sign - gateway to public key signature
1167 @c  *  ossl-verify - gateway to public key signature verification
1168 @noindent
1169 Again we reuse the keys defined above.
1170
1171 @example
1172 @group
1173 (progn
1174   (setq sig (ossl-sign 'SHA1 "I owe you a beer" dsaexmpl))
1175   (base16-encode-string sig))
1176   @result{} "302d021500c2e5197d266573216e4daa85e0a7e43424d0f031021451186
1177       24043517e0cd24f381d0e6c92f96198f297"
1178 @end group
1179
1180 @group
1181 (ossl-verify 'SHA1 "I owe you a beer" sig dsapub)
1182   @result{} t
1183 @end group
1184
1185 @group
1186 ;; @r{we try to fake the signed text}
1187 (ossl-verify 'SHA1 "I owe you 10 beer" sig dsapub)
1188   @result{} nil
1189 @end group
1190 @end example
1191
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.
1199
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.
1203
1204 @defun ossl-pem-read-public-key file
1205 Return a key (the public part) stored in a PEM structure from
1206 @var{file}.
1207 @end defun
1208
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}.
1213 @end defun
1214
1215 @defun ossl-pem-write-public-key file pkey
1216 Write @var{pkey} (the public part) in a PEM structure to @var{file}.
1217 @end defun
1218
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}.
1222
1223 @var{cipher} can be set to @code{nil} and the key will not be
1224 encrypted.  @var{password} is ignored in this case.
1225 @end defun
1226
1227 @defun ossl-pem-public-key pkey
1228 Return @var{pkey} as PEM encoded string.
1229 @end defun
1230
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}.
1234
1235 @var{cipher} can be set to @code{nil} and the key will not be
1236 encrypted.  @var{password} is ignored in this case.
1237 @end defun
1238
1239 @example
1240 @group
1241 (ossl-pem-write-key "/tmp/mykey.pem" dsaexmpl)
1242 @end group
1243
1244 @group
1245 (let ((stored (ossl-pem-read-key "/tmp/mykey.pem")))
1246   (ossl-verify 'SHA1 "I owe you a beer" sig stored))
1247   @result{} t
1248 @end group
1249
1250 @group
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
1259 ewIBAw==
1260 -----END PUBLIC KEY-----
1261 "
1262 @end group
1263
1264 @group
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
1273 ewIBAw==
1274 -----END PUBLIC KEY-----
1275 "
1276 @end group
1277
1278 @group
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-----
1310 "
1311 @end group
1312 @end example
1313
1314
1315 @node openssl SSL/TLS,  , openssl PKEY, SXEmacs OpenSSL API
1316 @subsection Secure Network Layers
1317
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.
1323
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
1331 the change.
1332
1333 @defun ossl-ssl-handshake process &optional method ca cert key serverp
1334 Perform a handshake on the network connection @var{process}.
1335
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
1339 handle ssl at all.
1340
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}.
1344
1345 Optional argument @var{ca} indicates a CA certificate.
1346 See @code{ossl-ssl-inject-ca}.
1347
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}.
1351
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.
1356 @end defun
1357
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
1361 be performed.
1362
1363 Also, be sure to store the returned SSL-CONN object for later
1364 reference.
1365
1366 @defun ossl-ssl-finish ssl-conn
1367 Finish an SSL connection @var{ssl-conn}.
1368
1369 Note: This may also finish the network connection.
1370 @end defun
1371
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.
1375
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.
1380
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
1383 evp-pkey object.
1384 @end defun
1385
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.
1391
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.
1396 @end defun
1397
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.
1404
1405 @example
1406 @group
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>
1410
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>>
1415
1416 ;; @r{Let's examine @samp{p}}
1417 p
1418   @result{} #<secure network connection "moz"
1419        (443 . "addons.mozilla.org") state:run>
1420
1421 (ossl-ssl-finish m)
1422   @result{} #<OpenSSL socket layer: dead>
1423
1424 ;; @r{Let's examine @samp{p} again}
1425 p
1426   @result{} #<network connection "moz"
1427        (443 . "addons.mozilla.org") state:exit>
1428 @end group
1429 @end example
1430
1431 @noindent
1432 Offering a secure listening socket works quite similar as the
1433 following example shows.
1434
1435 @example
1436 @group
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
1442
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>
1448 @end group
1449
1450 @group
1451 @r{We connect using the OpenSSL command line interface.}
1452
1453 freundt@@hlid:~$ openssl s_client -ssl3 -connect localhost:4432 \
1454   -CAfile /etc/ssl/CA/cacert.pem
1455 CONNECTED(00000003)
1456 depth=1 /C=DE/ST=Berlin/O=hlidskjalf.org/OU=local CA/CN=hlid.hli
1457 dskjalf.org/emailAddress=freundt@@hlidskjalf.org
1458 verify return:1
1459 depth=0 /C=DE/ST=Berlin/O=hlidskjalf.org/OU=ldap client freundt/
1460 CN=hlid.hlidskjalf.org/emailAddress=freundt@@hlidskjalf.org
1461 verify return:1
1462 ---
1463 Certificate chain
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
1468 ---
1469 Server certificate
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
1499 @c ---
1500 @c No client certificate CA names sent
1501 @c ---
1502 @c SSL handshake has read 1289 bytes and written 489 bytes
1503 @c ---
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
1508 @c SSL-Session:
1509 @c     Protocol  : SSLv3
1510 @c     Cipher    : AES256-SHA
1511 @c     Session-ID: 05818FC08CA2A2A27157B4E33A568FA2CE0453633099DB03
1512 @c 90C25CB0C71DBCF2
1513 @c     Session-ID-ctx:
1514 @c     Master-Key: 8D8FEE3EAF1A85BB664AE779A4A4A0F6944EAA355497E162
1515 @c BAF60A7CD3DEAE6633C24116CC4BAF1013F78D2BFC919199
1516 @c     Key-Arg   : None
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)
1523 @c ---
1524 @dots{}
1525 DONE
1526 @end group
1527 @end example
1528 @noindent
1529 which is exactly the expected output.
1530
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.
1540
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}.
1544
1545 @example
1546 @group
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"))
1553   @result{} nil
1554 @end group
1555
1556 @group
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
1563 250-PIPELINING
1564 250-SIZE 10240000
1565 250-VRFY
1566 250-ETRN
1567 250-ENHANCEDSTATUSCODES
1568 250-8BITMIME
1569 250 DSN
1570 221 2.0.0 Bye
1571
1572 Process smtps exited abnormally with code 256
1573 @point{}
1574 ---------- Buffer: smtps ----------
1575 @end group
1576 @end example
1577
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.
1582
1583 @defun ossl-ssl-proselytise-process ssl-conn
1584 Convert the underlying process of @var{ssl-conn} into a secure
1585 network connection object.
1586 @end defun
1587
1588 @defun ossl-ssl-unproselytise-process ssl-conn
1589 Convert the underlying process of @var{ssl-conn} into an ordinary
1590 network connection object.
1591 @end defun
1592
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.
1601
1602 @example
1603 @group
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")))
1610   @result{} nil
1611 @end group
1612
1613 @group
1614 ---------- Buffer: smtps ----------
1615 220 fluch.fresse.org ESMTP Postfix
1616 220 2.0.0 Ready to start TLS
1617 < < < < < < < < < <
1618 < raw binary data >
1619 > > > > > > > > > >
1620
1621 Process smtps exited abnormally with code 256
1622 @point{}
1623 ---------- Buffer: smtps ----------
1624 @end group
1625 @end example
1626
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
1630 this case.
1631
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}.
1635 @end defun
1636 @c does not work at the moment
1637
1638 @defun ossl-ssl-write ssl-conn string
1639 Send @var{string} to the tunnel @var{ssl-conn}.
1640 @end defun
1641
1642 After all, unlinking the two layers currently only works in one
1643 direction.  The ssl-conn object will always know its parent
1644 network-stream.
1645
1646 @defun ossl-ssl-parent ssl-conn
1647 Return the underlying parent layer of @var{ssl-conn}.
1648 @end defun
1649
1650 @noindent
1651 In the linked case the converse can be determined by
1652 @code{process-type-data}, @pxref{Processes}.
1653
1654
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
1659 set by the user.
1660
1661 @defun ossl-ssl-cipher-version ssl-conn
1662 Return the protocol version of the tunnel @var{ssl-conn}.
1663 @end defun
1664
1665 @defun ossl-ssl-cipher-name ssl-conn
1666 Return the name of the current cipher used in the tunnel @var{ssl-conn}.
1667 @end defun
1668
1669 @defun ossl-ssl-cipher-names ssl-conn
1670 Return the names of all supported ciphers in the tunnel @var{ssl-conn}.
1671 @end defun
1672
1673 @defun ossl-ssl-cipher-bits ssl-conn
1674 Return the number of effective bits of the current cipher
1675 in @var{ssl-conn}.
1676 @end defun
1677
1678 @defun ossl-ssl-cipher-description ssl-conn
1679 Return a description of the current cipher used in the tunnel
1680 @var{ssl-conn}.
1681 @end defun
1682
1683
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.
1690
1691 @defun ossl-ssl-cert ssl-conn
1692 Return the local peer's certificate of @var{ssl-conn} if present,
1693 @code{nil} otherwise.
1694 @end defun
1695
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.
1699 @end defun
1700
1701 @defun ossl-ssl-peer-cert-chain ssl-conn
1702 Return the certificate chain of @var{ssl-conn} as a list of
1703 evp-pkey objects.
1704 @end defun
1705
1706 @defun ossl-ssl-verify-certificate ssl-conn
1707 Return a verify code of @var{ssl-conn}.
1708
1709 The result is a cons cell with the numeric verify code in the car and
1710 a verbose string in the cdr.
1711 @end defun
1712
1713 @example
1714 @group
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>)
1726 @end group
1727 @end example
1728
1729
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.
1736
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.
1740
1741 @defun ossl-x509-subject cert
1742 Return the certificate subject of @var{cert} (an evp-pkey object).
1743
1744 This will return a string in LDAP syntax.
1745 @end defun
1746
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.
1750
1751 This will return a string in LDAP syntax.
1752 @end defun
1753
1754 @defun ossl-x509-serial cert
1755 Return the certificate serial of @var{cert} (an evp-pkey object).
1756 @end defun
1757
1758 @defun ossl-x509-not-before cert
1759 Return the certificate valid-not-before time of @var{cert}.
1760 @end defun
1761
1762 @defun ossl-x509-not-after cert
1763 Return the certificate valid-not-after time of @var{cert}.
1764 @end defun
1765
1766 @defun ossl-x509-signature-type cert
1767 Return the signature type of @var{cert}.
1768 @end defun
1769
1770 @example
1771 @group
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>
1782 @end group
1783
1784 @group
1785 (ossl-x509-subject c)
1786   @result{} "/ST=The Internet/O=The OpenSSL Project/CN=www.openssl.org/
1787       emailAddress=openssl-team@@openssl.org"
1788 @end group
1789
1790 @group
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"
1795 @end group
1796
1797 @group
1798 (ossl-x509-serial c)
1799   @result{} 1
1800 @end group
1801
1802 @group
1803 (ossl-x509-not-before c)
1804   @result{} "020802062727Z"
1805 @end group
1806
1807 @group
1808 (ossl-x509-not-after c)
1809   @result{} "030802062727Z"
1810 @end group
1811
1812 @group
1813 (ossl-x509-signature-type c)
1814   @result{} none
1815 @end group
1816 @end example