Network Security with OpenSSL by John Viega, Matt Messier, Pravir Chandra This errata page lists errors outstanding in the most recent printing. If you have technical questions or error reports, you can send them to booktech@oreilly.com. Please specify the printing date of your copy. This page was updated August 6, 2008. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification Confirmed errors: {10} On the second line of the fourth paragraph, "... she can sign it with her public key."; "public" should be "private". (29) 2nd paragraph; The second word in the second sentence should be "supports". (40-41) In the paragraph spanning the two pages; "... trust can be established if the certificate that issued a certificate...", The first instance of "certificate" should read "Certification Authority". (54) 1st paragraph; "just that is hasn't been revoked" should be "just that it hasn't been revoked" (75) In the first sentence in the section "Static Locking Callbacks", the word provide is misspelled. (92)2nd paragraph, 2nd sentence; "cis" should be "is". {97} In the Random Number Generation section, documentation of RAND_bytes and RAND_pseudo_bytes was omitted. These are API functions for programmers to use when they need random numbers from OpenSSL. The following are the declarations for these functions. int RAND_bytes(unsigned char *buf, int num); int RAND_pseudo_bytes(unsigned char *buf, int num); The first of these functions writes num bytes of cryptographically strong random bytes into the memory at buf. The second function does precisely the same thing except that the random bytes provided are not necessarily unpredictable. The latter function is not suitable for cryptographic needs (it is no more secure than functions like rand). For more information on these functions, see the man page for RAND_bytes here. (113) 4th paragraph; The second sentence in the fourth paragraph on page 113 start with "There a total of four files:". I assume there is the word "are" missing which would yield the correct sentence "There are a total of four files:". {115} In the function init_OpenSSL, SSL_init_library() should be SSL_library_init() (136) Function post_connection_check, line 61; In the Win32 environment, the function strcasecmp does not exist. I inserted the following lines above this function to fix this problem. #ifdef WIN32 int strcasecmp(const char *left, const char *right) { int iter; char leftc, rightc; leftc = rightc = 0; for ( iter = 0; left[iter] && right[iter] && leftc == rightc ; iter++ ) { if ( left[iter] > 96 && left[iter] < 123 ) leftc = left[iter] & 95; else leftc = left[iter]; if ( right[iter] > 96 && right[iter] < 123 ) rightc = right[iter] & 95; else rightc = right[iter]; } if ( leftc > rightc ) return 1; if ( leftc < rightc ) return -1; return 0; } #endif AUTHOR: Apparently it's true, at least for some windows versions. The function name is simply changed, though. Here's a much simpler fix (which would go at the top of the source listing): #ifdef _WIN32 #define strcasecmp(x,y) stricmp(x,y) #endif {138} In Example 5-9, line 3 should read: #define CAFILE "rootcert.pem" {140} In Example 5-10, line 3 should read: #define CAFILE "rootcert.pem" {141} In Example 5-10, the 66th line should be: ERR_remove_state(0); rather than: ERR_remove_state(0) {141} In Example 5-10, the 101th line should be: THREAD_CREATE(tid, server_thread, ssl); rather than: THREAD_create(tid, server_thread, ssl); {147} In Example 5-11, line 4 should read: #define CAFILE "rootcert.pem" {148} In Example 5-12, line 48 should read: #define CAFILE "rootcert.pem" {175} All AES modes use 128-bit blocks. Remove all references to variable block sizes. Rijndael, which became AES, supports variable block lengths, but the AES specification fixes the block size. (198) 6th line from bottom; unsigned char *process_file(FILE *f, insigned int *olen) should read unsigned char *process_file(FILE *f, unsigned int *olen) {288} In Example 10-6 on line 77 (third line of code from bottom of the page), the parentheses do not match up. The line should rather be: if (X509_REQ_verify(req, pkey) != 1) {289} In Example 10-6 on line 129 (third line of code from bottom of the page), the parentheses do not match up. The line should rather be: if (X509_set_pubkey(cert, pkey) != 1)