[原创/通译]openssl 源码悦读之0.09 FAQ

[原创/翻译]openssl 源码悦读之0.09 FAQ

  • 标 题:[原创/翻译]openssl 源码悦读之0.09 FAQ
  • 作 者:sancao2
  • 时 间:2013-01-18 11:45:23
  • 链 接:http://blog.****.net/linjiangxiandong/article/details/8511385


OpenSSL  -  Frequently Asked Questions

--------------------------------------

[MISC] Miscellaneous questions

* Which is the current version of OpenSSL?
* Where is the documentation?
* How can I contact the OpenSSL developers?
* Where can I get a compiled version of OpenSSL?
* Why aren't tools like 'autoconf' and 'libtool' used?
* What is an 'engine' version?
* How do I check the authenticity of the OpenSSL distribution?

[LEGAL] Legal questions

* Do I need patent licenses to use OpenSSL?
* Can I use OpenSSL with GPL software?

[USER] Questions on using the OpenSSL applications

* Why do I get a "PRNG not seeded" error message?
* Why do I get an "unable to write 'random state'" error message?
* How do I create certificates or certificate requests?
* Why can't I create certificate requests?
* Why does <SSL program> fail with a certificate verify error?
* Why can I only use weak ciphers when I connect to a server using OpenSSL?
* How can I create DSA certificates?
* Why can't I make an SSL connection using a DSA certificate?
* How can I remove the passphrase on a private key?
* Why can't I use OpenSSL certificates with SSL client authentication?
* Why does my browser give a warning about a mismatched hostname?
* How do I install a CA certificate into a browser?
* Why is OpenSSL x509 DN output not conformant to RFC2253?
* What is a "128 bit certificate"? Can I create one with OpenSSL?
* Why does OpenSSL set the authority key identifier extension incorrectly?
* How can I set up a bundle of commercial root CA certificates?

[BUILD] Questions about building and testing OpenSSL

* Why does the linker complain about undefined symbols?
* Why does the OpenSSL test fail with "bc: command not found"?
* Why does the OpenSSL test fail with "bc: 1 no implemented"?
* Why does the OpenSSL test fail with "bc: stack empty"?
* Why does the OpenSSL compilation fail on Alpha Tru64 Unix?
* Why does the OpenSSL compilation fail with "ar: command not found"?
* Why does the OpenSSL compilation fail on Win32 with VC++?
* What is special about OpenSSL on Redhat?
* Why does the OpenSSL compilation fail on MacOS X?
* Why does the OpenSSL test suite fail on MacOS X?
* Why does the OpenSSL test suite fail in BN_sqr test [on a 64-bit platform]?
* Why does OpenBSD-i386 build fail on des-586.s with "Unimplemented segment type"?
* Why does the OpenSSL test suite fail in sha512t on x86 CPU?
* Why does compiler fail to compile sha512.c?
* Test suite still fails, what to do?
* I think I've found a bug, what should I do?
* I'm SURE I've found a bug, how do I report it?
* I've found a security issue, how do I report it?

[PROG] Questions about programming with OpenSSL

* Is OpenSSL thread-safe?
* I've compiled a program under Windows and it crashes: why?
* How do I read or write a DER encoded buffer using the ASN1 functions?
* OpenSSL uses DER but I need BER format: does OpenSSL support BER?
* I've tried using <M_some_evil_pkcs12_macro> and I get errors why?
* I've called <some function> and it fails, why?
* I just get a load of numbers for the error output, what do they mean?
* Why do I get errors about unknown algorithms?
* Why can't the OpenSSH configure script detect OpenSSL?
* Can I use OpenSSL's SSL library with non-blocking I/O?
* Why doesn't my server application receive a client certificate?
* Why does compilation fail due to an undefined symbol NID_uniqueIdentifier?
* I think I've detected a memory leak, is this a bug?
* Why does Valgrind complain about the use of uninitialized data?
* Why doesn't a memory BIO work when a file does?
* Where are the declarations and implementations of d2i_X509() etc?
===============================================================================
FAQ:
[MISC]杂项
哪个 是OpenSSL的当前版本?
哪里 能找到文档?
怎么 才能联系上OpenSSL的开发者?
哪里 能得到一份编译后的版本?
为啥 有"autoconf"和"libtool"不用,(而自己用"perl"写构建脚本)?
什么 是"engine"的版本?
怎么做 我才能校验OpenSSL分发包(distribution)的真实性(authenticity)?

[LEGAL]法律/协议
是否 我需要专利许可才能使用OpenSSL?
是否 我能使用OpenSSL,结合"GPL"软件?

[USER]应用程序
为啥 我得到"PRNG not seeded"的错误提示?
为啥 我得到"unable to write 'random state'"的错误提示?
怎么做 我创建证书(certificates)或证书请求(certificate requests)?
为啥 我不能创建证书请求(create certificate requests)?
为啥 "SSL"程序崩溃于证书校验(certificate verify)错误?
为啥 我只能使用弱密码(weak ciphers),当我用OpenSSL连上服务器?
怎么做 我才能创建"DSA"证书?
为啥 我不能使用"DSA"证书创建SSL连接?
怎么做 我才能去除一个私钥的口令(passphrase)?
为啥 我不能使用OpenSSL证书做SSL客户端认证?
为啥 我的浏览器发出"不匹配的主机名"(mismatched hostname)的报警?
怎么做 我才能安装一个CA证书到一个浏览器?
为啥 OpenSSL"x509"的"DN"输出跟"RFC2253"不一致?
什么 是一个"128比特的证书"?我能使用OpenSSL创建一个吗?
为啥 OpenSSL设置认证密钥标识(authority key identifier/AKID)扩展失败?
怎么做 我才能设置一簇商业根CA证书?

[BUILD]构建
为啥 连接器抱怨未定义的符号?
为啥 OpenSSL测试失败,提示"bc: command not found"?
为啥 OpenSSL测试失败,提示"bc: 1 no implemented"?
为啥 OpenSSL测试失败,提示"bc: stack empty"?
为啥 OpenSSL编译失败,在"Alpha Tru64 Unix"平台?
为啥 OpenSSL编译失败,提示"ar: command not found"?
为啥 OpenSSL编译失败,在"Win32"平台下使用VC++?
什么 特殊的要求,关于OpenSSL在"Redhat"平台下要具备?
为啥 OpenSSL编译失败,在"MacOS X"平台下?
为啥 OpenSSL测试套装(test suite)失败,在"MacOS X"平台下?
为啥 OpenSSL测试套装(test suite)失败,在"64-bit"平台下测试"BN_sqr"?
为啥 "OpenBSD-i386"构建"des-586"失败,提示"未实现的段类型"?
为啥 OpenSSL测试套装,测试"sha512t"失败,在"x86"平台?
为啥 编译器编译"sha512.c"失败?
怎么办 测试套装失败?
怎么做 我想找到了一bug?
怎么 报告,我确定我找到了一bug?
怎么 报告,我找到了一个安全话题(issue)?

[PROG]编程
是否 OpenSSL是线程安全的?
为啥 我编译一个程序于windows平台,崩溃了,泪奔~~?
怎么做 我能读写"DER"编码的缓存(buffer),使用"ASN1"函数?
是否 OpenSSL支持"BER"编码,OpenSSL使用"DER",但我需要"BER"?
为啥 我尝试使用"M_some_evil_pkcs12_macro"却得到错误?
为啥 我调用"某些函数",却失败?
什么意思, 我刚刚加载一个数字,在错误输出时?
为啥 我得到错误,关于未知的算法?
为啥 我不能使用OpenSSH的配置脚本侦测(detect)OpenSSL?
是否 我能使用OpenSSL的"SSL"库,结合非阻塞I/O?
为啥 我不能使用我的服务器应用程序接收到客户端证书?
为啥 编译失败,提示"an undefined symbol NID_uniqueIdentifier"?
是否 是一bug,我侦测到内存溢出?
为啥 "Valgrind"抱怨,使用未初始化的数据?
为啥 内存BIO不能工作,但是文件工作正常?
哪里 找到"d2i_X509()"等函数的声明和实现?


[MISC] ========================================================================

* Which is the current version of OpenSSL?

The current version is available from <URL: http://www.openssl.org>.
OpenSSL 1.0.0e was released on Sep 6th, 2011.

In addition to the current stable release, you can also access daily
snapshots of the OpenSSL development version at <URL:
ftp://ftp.openssl.org/snapshot/>, or get it by anonymous CVS access.


* Where is the documentation?

OpenSSL is a library that provides cryptographic functionality to
applications such as secure web servers.  Be sure to read the
documentation of the application you want to use.  The INSTALL file
explains how to install this library.

OpenSSL includes a command line utility that can be used to perform a
variety of cryptographic functions.  It is described in the openssl(1)
manpage.  Documentation for developers is currently being written. Many
manual pages are available; overviews over libcrypto and
libssl are given in the crypto(3) and ssl(3) manpages.

The OpenSSL manpages are installed in /usr/local/ssl/man/ (or a
different directory if you specified one as described in INSTALL).
In addition, you can read the most current versions at
<URL: http://www.openssl.org/docs/>. Note that the online documents refer
to the very latest development versions of OpenSSL and may include features
not present in released versions. If in doubt refer to the documentation
that came with the version of OpenSSL you are using.

For information on parts of libcrypto that are not yet documented, you
might want to read Ariel Glenn's documentation on SSLeay 0.9, OpenSSL's
predecessor, at <URL: http://www.columbia.edu/~ariel/ssleay/>.  Much
of this still applies to OpenSSL.

There is some documentation about certificate extensions and PKCS#12
in doc/openssl.txt

The original SSLeay documentation is included in OpenSSL as
doc/ssleay.txt.  It may be useful when none of the other resources
help, but please note that it reflects the obsolete version SSLeay
0.6.6.


* How can I contact the OpenSSL developers?

The README file describes how to submit bug reports and patches to
OpenSSL.  Information on the OpenSSL mailing lists is available from
<URL: http://www.openssl.org>.


* Where can I get a compiled version of OpenSSL?

You can finder pointers to binary distributions in
<URL: http://www.openssl.org/related/binaries.html> .

Some applications that use OpenSSL are distributed in binary form.
When using such an application, you don't need to install OpenSSL
yourself; the application will include the required parts (e.g. DLLs).

If you want to build OpenSSL on a Windows system and you don't have
a C compiler, read the "Mingw32" section of INSTALL.W32 for information
on how to obtain and install the free GNU C compiler.

A number of Linux and *BSD distributions include OpenSSL.


* Why aren't tools like 'autoconf' and 'libtool' used?

autoconf will probably be used in future OpenSSL versions. If it was
less Unix-centric, it might have been used much earlier.

* What is an 'engine' version?

With version 0.9.6 OpenSSL was extended to interface to external crypto
hardware. This was realized in a special release '0.9.6-engine'. With
version 0.9.7 the changes were merged into the main development line,
so that the special release is no longer necessary.

* How do I check the authenticity of the OpenSSL distribution?

We provide MD5 digests and ASC signatures of each tarball.
Use MD5 to check that a tarball from a mirror site is identical:

   md5sum TARBALL | awk '{print $1;}' | cmp - TARBALL.md5

You can check authenticity using pgp or gpg. You need the OpenSSL team
member public key used to sign it (download it from a key server, see a
list of keys at <URL: http://www.openssl.org/about/>). Then
just do:

   pgp TARBALL.asc

[LEGAL] =======================================================================

* Do I need patent licenses to use OpenSSL?

The patents section of the README file lists patents that may apply to
you if you want to use OpenSSL.  For information on intellectual
property rights, please consult a lawyer.  The OpenSSL team does not
offer legal advice.

You can configure OpenSSL so as not to use IDEA, MDC2 and RC5 by using
 ./config no-idea no-mdc2 no-rc5


* Can I use OpenSSL with GPL software?

On many systems including the major Linux and BSD distributions, yes (the
GPL does not place restrictions on using libraries that are part of the
normal operating system distribution).

On other systems, the situation is less clear. Some GPL software copyright
holders claim that you infringe on their rights if you use OpenSSL with
their software on operating systems that don't normally include OpenSSL.

If you develop open source software that uses OpenSSL, you may find it
useful to choose an other license than the GPL, or state explicitly that
"This program is released under the GPL with the additional exemption that
compiling, linking, and/or using OpenSSL is allowed."  If you are using
GPL software developed by others, you may want to ask the copyright holder
for permission to use their software with OpenSSL.


[USER] ========================================================================

* Why do I get a "PRNG not seeded" error message?

Cryptographic software needs a source of unpredictable data to work
correctly.  Many open source operating systems provide a "randomness
device" (/dev/urandom or /dev/random) that serves this purpose.
All OpenSSL versions try to use /dev/urandom by default; starting with
version 0.9.7, OpenSSL also tries /dev/random if /dev/urandom is not
available.

On other systems, applications have to call the RAND_add() or
RAND_seed() function with appropriate data before generating keys or
performing public key encryption. (These functions initialize the
pseudo-random number generator, PRNG.)  Some broken applications do
not do this.  As of version 0.9.5, the OpenSSL functions that need
randomness report an error if the random number generator has not been
seeded with at least 128 bits of randomness.  If this error occurs and
is not discussed in the documentation of the application you are
using, please contact the author of that application; it is likely
that it never worked correctly.  OpenSSL 0.9.5 and later make the
error visible by refusing to perform potentially insecure encryption.

If you are using Solaris 8, you can add /dev/urandom and /dev/random
devices by installing patch 112438 (Sparc) or 112439 (x86), which are
available via the Patchfinder at <URL: http://sunsolve.sun.com>
(Solaris 9 includes these devices by default). For /dev/random support
for earlier Solaris versions, see Sun's statement at
<URL: http://sunsolve.sun.com/pub-cgi/retrieve.pl?doc=fsrdb/27606&zone_32=SUNWski>
(the SUNWski package is available in patch 105710).

On systems without /dev/urandom and /dev/random, it is a good idea to
use the Entropy Gathering Demon (EGD); see the RAND_egd() manpage for
details.  Starting with version 0.9.7, OpenSSL will automatically look
for an EGD socket at /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool and
/etc/entropy.

Most components of the openssl command line utility automatically try
to seed the random number generator from a file.  The name of the
default seeding file is determined as follows: If environment variable
RANDFILE is set, then it names the seeding file.  Otherwise if
environment variable HOME is set, then the seeding file is $HOME/.rnd.
If neither RANDFILE nor HOME is set, versions up to OpenSSL 0.9.6 will
use file .rnd in the current directory while OpenSSL 0.9.6a uses no
default seeding file at all.  OpenSSL 0.9.6b and later will behave
similarly to 0.9.6a, but will use a default of "C:\" for HOME on
Windows systems if the environment variable has not been set.

If the default seeding file does not exist or is too short, the "PRNG
not seeded" error message may occur.

The openssl command line utility will write back a new state to the
default seeding file (and create this file if necessary) unless
there was no sufficient seeding.

Pointing $RANDFILE to an Entropy Gathering Daemon socket does not work.
Use the "-rand" option of the OpenSSL command line tools instead.
The $RANDFILE environment variable and $HOME/.rnd are only used by the
OpenSSL command line tools. Applications using the OpenSSL library
provide their own configuration options to specify the entropy source,
please check out the documentation coming the with application.


* Why do I get an "unable to write 'random state'" error message?


Sometimes the openssl command line utility does not abort with
a "PRNG not seeded" error message, but complains that it is
"unable to write 'random state'".  This message refers to the
default seeding file (see previous answer).  A possible reason
is that no default filename is known because neither RANDFILE
nor HOME is set.  (Versions up to 0.9.6 used file ".rnd" in the
current directory in this case, but this has changed with 0.9.6a.)


* How do I create certificates or certificate requests?

Check out the CA.pl(1) manual page. This provides a simple wrapper round
the 'req', 'verify', 'ca' and 'pkcs12' utilities. For finer control check
out the manual pages for the individual utilities and the certificate
extensions documentation (currently in doc/openssl.txt).


* Why can't I create certificate requests?

You typically get the error:

    unable to find 'distinguished_name' in config
    problems making Certificate Request

This is because it can't find the configuration file. Check out the
DIAGNOSTICS section of req(1) for more information.


* Why does <SSL program> fail with a certificate verify error?

This problem is usually indicated by log messages saying something like
"unable to get local issuer certificate" or "self signed certificate".
When a certificate is verified its root CA must be "trusted" by OpenSSL
this typically means that the CA certificate must be placed in a directory
or file and the relevant program configured to read it. The OpenSSL program
'verify' behaves in a similar way and issues similar error messages: check
the verify(1) program manual page for more information.


* Why can I only use weak ciphers when I connect to a server using OpenSSL?

This is almost certainly because you are using an old "export grade" browser
which only supports weak encryption. Upgrade your browser to support 128 bit
ciphers.


* How can I create DSA certificates?

Check the CA.pl(1) manual page for a DSA certificate example.


* Why can't I make an SSL connection to a server using a DSA certificate?

Typically you'll see a message saying there are no shared ciphers when
the same setup works fine with an RSA certificate. There are two possible
causes. The client may not support connections to DSA servers most web
browsers (including Netscape and MSIE) only support connections to servers
supporting RSA cipher suites. The other cause is that a set of DH parameters
has not been supplied to the server. DH parameters can be created with the
dhparam(1) command and loaded using the SSL_CTX_set_tmp_dh() for example:
check the source to s_server in apps/s_server.c for an example.


* How can I remove the passphrase on a private key?

Firstly you should be really *really* sure you want to do this. Leaving
a private key unencrypted is a major security risk. If you decide that
you do have to do this check the EXAMPLES sections of the rsa(1) and
dsa(1) manual pages.


* Why can't I use OpenSSL certificates with SSL client authentication?

What will typically happen is that when a server requests authentication
it will either not include your certificate or tell you that you have
no client certificates (Netscape) or present you with an empty list box
(MSIE). The reason for this is that when a server requests a client
certificate it includes a list of CAs names which it will accept. Browsers
will only let you select certificates from the list on the grounds that
there is little point presenting a certificate which the server will
reject.

The solution is to add the relevant CA certificate to your servers "trusted
CA list". How you do this depends on the server software in uses. You can
print out the servers list of acceptable CAs using the OpenSSL s_client tool:

openssl s_client -connect www.some.host:443 -prexit

If your server only requests certificates on certain URLs then you may need
to manually issue an HTTP GET command to get the list when s_client connects:

GET /some/page/needing/a/certificate.html

If your CA does not appear in the list then this confirms the problem.


* Why does my browser give a warning about a mismatched hostname?

Browsers expect the server's hostname to match the value in the commonName
(CN) field of the certificate. If it does not then you get a warning.


* How do I install a CA certificate into a browser?

The usual way is to send the DER encoded certificate to the browser as
MIME type application/x-x509-ca-cert, for example by clicking on an appropriate
link. On MSIE certain extensions such as .der or .cacert may also work, or you
can import the certificate using the certificate import wizard.

You can convert a certificate to DER form using the command:

openssl x509 -in ca.pem -outform DER -out ca.der

Occasionally someone suggests using a command such as:

openssl pkcs12 -export -out cacert.p12 -in cacert.pem -inkey cakey.pem

DO NOT DO THIS! This command will give away your CAs private key and
reduces its security to zero: allowing anyone to forge certificates in
whatever name they choose.

* Why is OpenSSL x509 DN output not conformant to RFC2253?

The ways to print out the oneline format of the DN (Distinguished Name) have
been extended in version 0.9.7 of OpenSSL. Using the new X509_NAME_print_ex()
interface, the "-nameopt" option could be introduded. See the manual
page of the "openssl x509" commandline tool for details. The old behaviour
has however been left as default for the sake of compatibility.

* What is a "128 bit certificate"? Can I create one with OpenSSL?

The term "128 bit certificate" is a highly misleading marketing term. It does
*not* refer to the size of the public key in the certificate! A certificate
containing a 128 bit RSA key would have negligible security.

There were various other names such as "magic certificates", "SGC
certificates", "step up certificates" etc.

You can't generally create such a certificate using OpenSSL but there is no
need to any more. Nowadays web browsers using unrestricted strong encryption
are generally available.

When there were tight restrictions on the export of strong encryption
software from the US only weak encryption algorithms could be freely exported
(initially 40 bit and then 56 bit). It was widely recognised that this was
inadequate. A relaxation of the rules allowed the use of strong encryption but
only to an authorised server.

Two slighly different techniques were developed to support this, one used by
Netscape was called "step up", the other used by MSIE was called "Server Gated
Cryptography" (SGC). When a browser initially connected to a server it would
check to see if the certificate contained certain extensions and was issued by
an authorised authority. If these test succeeded it would reconnect using
strong encryption.

Only certain (initially one) certificate authorities could issue the
certificates and they generally cost more than ordinary certificates.

Although OpenSSL can create certificates containing the appropriate extensions
the certificate would not come from a permitted authority and so would not
be recognized.

The export laws were later changed to allow almost unrestricted use of strong
encryption so these certificates are now obsolete.


* Why does OpenSSL set the authority key identifier (AKID) extension incorrectly?

It doesn't: this extension is often the cause of confusion.

Consider a certificate chain A->B->C so that A signs B and B signs C. Suppose
certificate C contains AKID.

The purpose of this extension is to identify the authority certificate B. This
can be done either by including the subject key identifier of B or its issuer
name and serial number.

In this latter case because it is identifying certifcate B it must contain the
issuer name and serial number of B.

It is often wrongly assumed that it should contain the subject name of B. If it
did this would be redundant information because it would duplicate the issuer
name of C.


* How can I set up a bundle of commercial root CA certificates?

The OpenSSL software is shipped without any root CA certificate as the
OpenSSL project does not have any policy on including or excluding
any specific CA and does not intend to set up such a policy. Deciding
about which CAs to support is up to application developers or
administrators.

Other projects do have other policies so you can for example extract the CA
bundle used by Mozilla and/or modssl as described in this article:

  <URL: http://www.mail-archive.com/modssl-users@modssl.org/msg16980.html>


[BUILD] =======================================================================

* Why does the linker complain about undefined symbols?

Maybe the compilation was interrupted, and make doesn't notice that
something is missing.  Run "make clean; make".

If you used ./Configure instead of ./config, make sure that you
selected the right target.  File formats may differ slightly between
OS versions (for example sparcv8/sparcv9, or a.out/elf).

In case you get errors about the following symbols, use the config
option "no-asm", as described in INSTALL:

 BF_cbc_encrypt, BF_decrypt, BF_encrypt, CAST_cbc_encrypt,
 CAST_decrypt, CAST_encrypt, RC4, RC5_32_cbc_encrypt, RC5_32_decrypt,
 RC5_32_encrypt, bn_add_words, bn_div_words, bn_mul_add_words,
 bn_mul_comba4, bn_mul_comba8, bn_mul_words, bn_sqr_comba4,
 bn_sqr_comba8, bn_sqr_words, bn_sub_words, des_decrypt3,
 des_ede3_cbc_encrypt, des_encrypt, des_encrypt2, des_encrypt3,
 des_ncbc_encrypt, md5_block_asm_host_order, sha1_block_asm_data_order

If none of these helps, you may want to try using the current snapshot.
If the problem persists, please submit a bug report.


* Why does the OpenSSL test fail with "bc: command not found"?

You didn't install "bc", the Unix calculator.  If you want to run the
tests, get GNU bc from ftp://ftp.gnu.org or from your OS distributor.


* Why does the OpenSSL test fail with "bc: 1 no implemented"?

On some SCO installations or versions, bc has a bug that gets triggered
when you run the test suite (using "make test").  The message returned is
"bc: 1 not implemented".

The best way to deal with this is to find another implementation of bc
and compile/install it.  GNU bc (see <URL: http://www.gnu.org/software/software.html>
for download instructions) can be safely used, for example.


* Why does the OpenSSL test fail with "bc: stack empty"?

On some DG/ux versions, bc seems to have a too small stack for calculations
that the OpenSSL bntest throws at it.  This gets triggered when you run the
test suite (using "make test").  The message returned is "bc: stack empty".

The best way to deal with this is to find another implementation of bc
and compile/install it.  GNU bc (see <URL: http://www.gnu.org/software/software.html>
for download instructions) can be safely used, for example.


* Why does the OpenSSL compilation fail on Alpha Tru64 Unix?

On some Alpha installations running Tru64 Unix and Compaq C, the compilation
of crypto/sha/sha_dgst.c fails with the message 'Fatal:  Insufficient virtual
memory to continue compilation.'  As far as the tests have shown, this may be
a compiler bug.  What happens is that it eats up a lot of resident memory
to build something, probably a table.  The problem is clearly in the
optimization code, because if one eliminates optimization completely (-O0),
the compilation goes through (and the compiler consumes about 2MB of resident
memory instead of 240MB or whatever one's limit is currently).

There are three options to solve this problem:

1. set your current data segment size soft limit higher.  Experience shows
that about 241000 kbytes seems to be enough on an AlphaServer DS10.  You do
this with the command 'ulimit -Sd nnnnnn', where 'nnnnnn' is the number of
kbytes to set the limit to.

2. If you have a hard limit that is lower than what you need and you can't
get it changed, you can compile all of OpenSSL with -O0 as optimization
level.  This is however not a very nice thing to do for those who expect to
get the best result from OpenSSL.  A bit more complicated solution is the
following:

----- snip:start -----
  make DIRS=crypto SDIRS=sha "`grep '^CFLAG=' Makefile.ssl | \
       sed -e 's/ -O[0-9] / -O0 /'`"
  rm `ls crypto/*.o crypto/sha/*.o | grep -v 'sha_dgst\.o'`
  make
----- snip:end -----

This will only compile sha_dgst.c with -O0, the rest with the optimization
level chosen by the configuration process.  When the above is done, do the
test and installation and you're set.

3. Reconfigure the toolkit with no-sha0 option to leave out SHA0. It
should not be used and is not used in SSL/TLS nor any other recognized
protocol in either case.


* Why does the OpenSSL compilation fail with "ar: command not found"?

Getting this message is quite usual on Solaris 2, because Sun has hidden
away 'ar' and other development commands in directories that aren't in
$PATH by default.  One of those directories is '/usr/ccs/bin'.  The
quickest way to fix this is to do the following (it assumes you use sh
or any sh-compatible shell):

----- snip:start -----
  PATH=${PATH}:/usr/ccs/bin; export PATH
----- snip:end -----

and then redo the compilation.  What you should really do is make sure
'/usr/ccs/bin' is permanently in your $PATH, for example through your
'.profile' (again, assuming you use a sh-compatible shell).


* Why does the OpenSSL compilation fail on Win32 with VC++?

Sometimes, you may get reports from VC++ command line (cl) that it
can't find standard include files like stdio.h and other weirdnesses.
One possible cause is that the environment isn't correctly set up.
To solve that problem for VC++ versions up to 6, one should run
VCVARS32.BAT which is found in the 'bin' subdirectory of the VC++
installation directory (somewhere under 'Program Files').  For VC++
version 7 (and up?), which is also called VS.NET, the file is called
VSVARS32.BAT instead.
This needs to be done prior to running NMAKE, and the changes are only
valid for the current DOS session.


* What is special about OpenSSL on Redhat?

Red Hat Linux (release 7.0 and later) include a preinstalled limited
version of OpenSSL. For patent reasons, support for IDEA, RC5 and MDC2
is disabled in this version. The same may apply to other Linux distributions.
Users may therefore wish to install more or all of the features left out.

To do this you MUST ensure that you do not overwrite the openssl that is in
/usr/bin on your Red Hat machine. Several packages depend on this file,
including sendmail and ssh. /usr/local/bin is a good alternative choice. The
libraries that come with Red Hat 7.0 onwards have different names and so are
not affected. (eg For Red Hat 7.2 they are /lib/libssl.so.0.9.6b and
/lib/libcrypto.so.0.9.6b with symlinks /lib/libssl.so.2 and
/lib/libcrypto.so.2 respectively).

Please note that we have been advised by Red Hat attempting to recompile the
openssl rpm with all the cryptography enabled will not work. All other
packages depend on the original Red Hat supplied openssl package. It is also
worth noting that due to the way Red Hat supplies its packages, updates to
openssl on each distribution never change the package version, only the
build number. For example, on Red Hat 7.1, the latest openssl package has
version number 0.9.6 and build number 9 even though it contains all the
relevant updates in packages up to and including 0.9.6b.

A possible way around this is to persuade Red Hat to produce a non-US
version of Red Hat Linux.

FYI: Patent numbers and expiry dates of US patents:
MDC-2: 4,908,861 13/03/2007
IDEA:  5,214,703 25/05/2010
RC5:   5,724,428 03/03/2015


* Why does the OpenSSL compilation fail on MacOS X?

If the failure happens when trying to build the "openssl" binary, with
a large number of undefined symbols, it's very probable that you have
OpenSSL 0.9.6b delivered with the operating system (you can find out by
running '/usr/bin/openssl version') and that you were trying to build
OpenSSL 0.9.7 or newer.  The problem is that the loader ('ld') in
MacOS X has a misfeature that's quite difficult to go around.
Look in the file PROBLEMS for a more detailed explanation and for possible
solutions.


* Why does the OpenSSL test suite fail on MacOS X?

If the failure happens when running 'make test' and the RC4 test fails,
it's very probable that you have OpenSSL 0.9.6b delivered with the
operating system (you can find out by running '/usr/bin/openssl version')
and that you were trying to build OpenSSL 0.9.6d.  The problem is that
the loader ('ld') in MacOS X has a misfeature that's quite difficult to
go around and has linked the programs "openssl" and the test programs
with /usr/lib/libcrypto.dylib and /usr/lib/libssl.dylib instead of the
libraries you just built.
Look in the file PROBLEMS for a more detailed explanation and for possible
solutions.

* Why does the OpenSSL test suite fail in BN_sqr test [on a 64-bit platform]?

Failure in BN_sqr test is most likely caused by a failure to configure the
toolkit for current platform or lack of support for the platform in question.
Run './config -t' and './apps/openssl version -p'. Do these platform
identifiers match? If they don't, then you most likely failed to run
./config and you're hereby advised to do so before filing a bug report.
If ./config itself fails to run, then it's most likely problem with your
local environment and you should turn to your system administrator (or
similar). If identifiers match (and/or no alternative identifier is
suggested by ./config script), then the platform is unsupported. There might
or might not be a workaround. Most notably on SPARC64 platforms with GNU
C compiler you should be able to produce a working build by running
'./config -m32'. I understand that -m32 might not be what you want/need,
but the build should be operational. For further details turn to
<openssl-dev@openssl.org>.

* Why does OpenBSD-i386 build fail on des-586.s with "Unimplemented segment type"?

As of 0.9.7 assembler routines were overhauled for position independence
of the machine code, which is essential for shared library support. For
some reason OpenBSD is equipped with an out-of-date GNU assembler which
finds the new code offensive. To work around the problem, configure with
no-asm (and sacrifice a great deal of performance) or patch your assembler
according to <URL: http://www.openssl.org/~appro/gas-1.92.3.OpenBSD.patch>.
For your convenience a pre-compiled replacement binary is provided at
<URL: http://www.openssl.org/~appro/gas-1.92.3.static.aout.bin>.
Reportedly elder *BSD a.out platforms also suffer from this problem and
remedy should be same. Provided binary is statically linked and should be
working across wider range of *BSD branches, not just OpenBSD.

* Why does the OpenSSL test suite fail in sha512t on x86 CPU?

If the test program in question fails withs SIGILL, Illegal Instruction
exception, then you more than likely to run SSE2-capable CPU, such as
Intel P4, under control of kernel which does not support SSE2
instruction extentions. See accompanying INSTALL file and
OPENSSL_ia32cap(3) documentation page for further information.

* Why does compiler fail to compile sha512.c?

OpenSSL SHA-512 implementation depends on compiler support for 64-bit
integer type. Few elder compilers [ULTRIX cc, SCO compiler to mention a
couple] lack support for this and therefore are incapable of compiling
the module in question. The recommendation is to disable SHA-512 by
adding no-sha512 to ./config [or ./Configure] command line. Another
possible alternative might be to switch to GCC.

* Test suite still fails, what to do?

Another common reason for failure to complete some particular test is
simply bad code generated by a buggy component in toolchain or deficiency
in run-time environment. There are few cases documented in PROBLEMS file,
consult it for possible workaround before you beat the drum. Even if you
don't find solution or even mention there, do reserve for possibility of
a compiler bug. Compiler bugs might appear in rather bizarre ways, they
never make sense, and tend to emerge when you least expect them. In order
to identify one, drop optimization level, e.g. by editing CFLAG line in
top-level Makefile, recompile and re-run the test.

* I think I've found a bug, what should I do?

If you are a new user then it is quite likely you haven't found a bug and
something is happening you aren't familiar with. Check this FAQ, the associated
documentation and the mailing lists for similar queries. If you are still
unsure whether it is a bug or not submit a query to the openssl-users mailing
list.


* I'm SURE I've found a bug, how do I report it?

Bug reports with no security implications should be sent to the request
tracker. This can be done by mailing the report to <rt@openssl.org> (or its
alias <openssl-bugs@openssl.org>), please note that messages sent to the
request tracker also appear in the public openssl-dev mailing list.

The report should be in plain text. Any patches should be sent as
plain text attachments because some mailers corrupt patches sent inline.
If your issue affects multiple versions of OpenSSL check any patches apply
cleanly and, if possible include patches to each affected version.

The report should be given a meaningful subject line briefly summarising the
issue. Just "bug in OpenSSL" or "bug in OpenSSL 0.9.8n" is not very helpful.

By sending reports to the request tracker the bug can then be given a priority
and assigned to the appropriate maintainer. The history of discussions can be
accessed and if the issue has been addressed or a reason why not. If patches
are only sent to openssl-dev they can be mislaid if a team member has to
wade through months of old messages to review the discussion.

See also <URL: http://www.openssl.org/support/rt.html>


* I've found a security issue, how do I report it?

If you think your bug has security implications then please send it to
openssl-security@openssl.org if you don't get a prompt reply at least
acknowledging receipt then resend or mail it directly to one of the
more active team members (e.g. Steve).

[PROG] ========================================================================

* Is OpenSSL thread-safe?

Yes (with limitations: an SSL connection may not concurrently be used
by multiple threads).  On Windows and many Unix systems, OpenSSL
automatically uses the multi-threaded versions of the standard
libraries.  If your platform is not one of these, consult the INSTALL
file.

Multi-threaded applications must provide two callback functions to
OpenSSL by calling CRYPTO_set_locking_callback() and
CRYPTO_set_id_callback(), for all versions of OpenSSL up to and
including 0.9.8[abc...]. As of version 1.0.0, CRYPTO_set_id_callback()
and associated APIs are deprecated by CRYPTO_THREADID_set_callback()
and friends. This is described in the threads(3) manpage.

* I've compiled a program under Windows and it crashes: why?

This is usually because you've missed the comment in INSTALL.W32.
Your application must link against the same version of the Win32
C-Runtime against which your openssl libraries were linked.  The
default version for OpenSSL is /MD - "Multithreaded DLL".

If you are using Microsoft Visual C++'s IDE (Visual Studio), in
many cases, your new project most likely defaulted to "Debug
Singlethreaded" - /ML.  This is NOT interchangeable with /MD and your
program will crash, typically on the first BIO related read or write
operation.

For each of the six possible link stage configurations within Win32,
your application must link  against the same by which OpenSSL was
built.  If you are using MS Visual C++ (Studio) this can be changed
by:

 1. Select Settings... from the Project Menu.
 2. Select the C/C++ Tab.
 3. Select "Code Generation from the "Category" drop down list box
 4. Select the Appropriate library (see table below) from the "Use
    run-time library" drop down list box.  Perform this step for both
    your debug and release versions of your application (look at the
    top left of the settings panel to change between the two)

    Single Threaded           /ML        -  MS VC++ often defaults to
                                            this for the release
                                            version of a new project.
    Debug Single Threaded     /MLd       -  MS VC++ often defaults to
                                            this for the debug version
                                            of a new project.
    Multithreaded             /MT
    Debug Multithreaded       /MTd
    Multithreaded DLL         /MD        -  OpenSSL defaults to this.
    Debug Multithreaded DLL   /MDd

Note that debug and release libraries are NOT interchangeable.  If you
built OpenSSL with /MD your application must use /MD and cannot use /MDd.

As per 0.9.8 the above limitation is eliminated for .DLLs. OpenSSL
.DLLs compiled with some specific run-time option [we insist on the
default /MD] can be deployed with application compiled with different
option or even different compiler. But there is a catch! Instead of
re-compiling OpenSSL toolkit, as you would have to with prior versions,
you have to compile small C snippet with compiler and/or options of
your choice. The snippet gets installed as
<install-root>/include/openssl/applink.c and should be either added to
your application project or simply #include-d in one [and only one]
of your application source files. Failure to link this shim module
into your application manifests itself as fatal "no OPENSSL_Applink"
run-time error. An explicit reminder is due that in this situation
[mixing compiler options] it is as important to add CRYPTO_malloc_init
prior first call to OpenSSL.

* How do I read or write a DER encoded buffer using the ASN1 functions?

You have two options. You can either use a memory BIO in conjunction
with the i2d_*_bio() or d2i_*_bio() functions or you can use the
i2d_*(), d2i_*() functions directly. Since these are often the
cause of grief here are some code fragments using PKCS7 as an example:

 unsigned char *buf, *p;
 int len;

 len = i2d_PKCS7(p7, NULL);
 buf = OPENSSL_malloc(len); /* or Malloc, error checking omitted */
 p = buf;
 i2d_PKCS7(p7, &p);

At this point buf contains the len bytes of the DER encoding of
p7.

The opposite assumes we already have len bytes in buf:

 unsigned char *p;
 p = buf;
 p7 = d2i_PKCS7(NULL, &p, len);

At this point p7 contains a valid PKCS7 structure of NULL if an error
occurred. If an error occurred ERR_print_errors(bio) should give more
information.

The reason for the temporary variable 'p' is that the ASN1 functions
increment the passed pointer so it is ready to read or write the next
structure. This is often a cause of problems: without the temporary
variable the buffer pointer is changed to point just after the data
that has been read or written. This may well be uninitialized data
and attempts to free the buffer will have unpredictable results
because it no longer points to the same address.


* OpenSSL uses DER but I need BER format: does OpenSSL support BER?

The short answer is yes, because DER is a special case of BER and OpenSSL
ASN1 decoders can process BER.

The longer answer is that ASN1 structures can be encoded in a number of
different ways. One set of ways is the Basic Encoding Rules (BER) with various
permissible encodings. A restriction of BER is the Distinguished Encoding
Rules (DER): these uniquely specify how a given structure is encoded.

Therefore, because DER is a special case of BER, DER is an acceptable encoding
for BER.


* I've tried using <M_some_evil_pkcs12_macro> and I get errors why?

This usually happens when you try compiling something using the PKCS#12
macros with a C++ compiler. There is hardly ever any need to use the
PKCS#12 macros in a program, it is much easier to parse and create
PKCS#12 files using the PKCS12_parse() and PKCS12_create() functions
documented in doc/openssl.txt and with examples in demos/pkcs12. The
'pkcs12' application has to use the macros because it prints out
debugging information.


* I've called <some function> and it fails, why?

Before submitting a report or asking in one of the mailing lists, you
should try to determine the cause. In particular, you should call
ERR_print_errors() or ERR_print_errors_fp() after the failed call
and see if the message helps. Note that the problem may occur earlier
than you think -- you should check for errors after every call where
it is possible, otherwise the actual problem may be hidden because
some OpenSSL functions clear the error state.


* I just get a load of numbers for the error output, what do they mean?

The actual format is described in the ERR_print_errors() manual page.
You should call the function ERR_load_crypto_strings() before hand and
the message will be output in text form. If you can't do this (for example
it is a pre-compiled binary) you can use the errstr utility on the error
code itself (the hex digits after the second colon).


* Why do I get errors about unknown algorithms?

The cause is forgetting to load OpenSSL's table of algorithms with
OpenSSL_add_all_algorithms(). See the manual page for more information. This
can cause several problems such as being unable to read in an encrypted
PEM file, unable to decrypt a PKCS#12 file or signature failure when
verifying certificates.

* Why can't the OpenSSH configure script detect OpenSSL?

Several reasons for problems with the automatic detection exist.
OpenSSH requires at least version 0.9.5a of the OpenSSL libraries.
Sometimes the distribution has installed an older version in the system
locations that is detected instead of a new one installed. The OpenSSL
library might have been compiled for another CPU or another mode (32/64 bits).
Permissions might be wrong.

The general answer is to check the config.log file generated when running
the OpenSSH configure script. It should contain the detailed information
on why the OpenSSL library was not detected or considered incompatible.


* Can I use OpenSSL's SSL library with non-blocking I/O?

Yes; make sure to read the SSL_get_error(3) manual page!

A pitfall to avoid: Don't assume that SSL_read() will just read from
the underlying transport or that SSL_write() will just write to it --
it is also possible that SSL_write() cannot do any useful work until
there is data to read, or that SSL_read() cannot do anything until it
is possible to send data.  One reason for this is that the peer may
request a new TLS/SSL handshake at any time during the protocol,
requiring a bi-directional message exchange; both SSL_read() and
SSL_write() will try to continue any pending handshake.


* Why doesn't my server application receive a client certificate?

Due to the TLS protocol definition, a client will only send a certificate,
if explicitly asked by the server. Use the SSL_VERIFY_PEER flag of the
SSL_CTX_set_verify() function to enable the use of client certificates.


* Why does compilation fail due to an undefined symbol NID_uniqueIdentifier?

For OpenSSL 0.9.7 the OID table was extended and corrected. In earlier
versions, uniqueIdentifier was incorrectly used for X.509 certificates.
The correct name according to RFC2256 (LDAP) is x500UniqueIdentifier.
Change your code to use the new name when compiling against OpenSSL 0.9.7.


* I think I've detected a memory leak, is this a bug?

In most cases the cause of an apparent memory leak is an OpenSSL internal table
that is allocated when an application starts up. Since such tables do not grow
in size over time they are harmless.

These internal tables can be freed up when an application closes using various
functions.  Currently these include following:

Thread-local cleanup functions:

  ERR_remove_state()

Application-global cleanup functions that are aware of usage (and therefore
thread-safe):

  ENGINE_cleanup() and CONF_modules_unload()

"Brutal" (thread-unsafe) Application-global cleanup functions:

  ERR_free_strings(), EVP_cleanup() and CRYPTO_cleanup_all_ex_data().


* Why does Valgrind complain about the use of uninitialized data?

When OpenSSL's PRNG routines are called to generate random numbers the supplied
buffer contents are mixed into the entropy pool: so it technically does not
matter whether the buffer is initialized at this point or not.  Valgrind (and
other test tools) will complain about this. When using Valgrind, make sure the
OpenSSL library has been compiled with the PURIFY macro defined (-DPURIFY)
to get rid of these warnings.


* Why doesn't a memory BIO work when a file does?

This can occur in several cases for example reading an S/MIME email message.
The reason is that a memory BIO can do one of two things when all the data
has been read from it.

The default behaviour is to indicate that no more data is available and that
the call should be retried, this is to allow the application to fill up the BIO
again if necessary.

Alternatively it can indicate that no more data is available and that EOF has
been reached.

If a memory BIO is to behave in the same way as a file this second behaviour
is needed. This must be done by calling:

   BIO_set_mem_eof_return(bio, 0);

See the manual pages for more details.


* Where are the declarations and implementations of d2i_X509() etc?

These are defined and implemented by macros of the form:


 DECLARE_ASN1_FUNCTIONS(X509) and IMPLEMENT_ASN1_FUNCTIONS(X509)

The implementation passes an ASN1 "template" defining the structure into an
ASN1 interpreter using generalised functions such as ASN1_item_d2i().

===============================================================================

[MISC]杂项 =======================================================================
哪个 是OpenSSL的当前版本?
-> 当前有效版本请浏览<URL: http://www.openssl.org>,
    "OpenSSL 1.0.0e"发布于"Sep 6th, 2011".
        相对于稳定的发行部,您还能进入每天的快照(daily snapshots),
    开发版本在<URL:ftp://ftp.openssl.org/snapshot/>,
    通过匿名"CVS"服务器得到他.

哪里 能找到文档?
-> OpenSSL是一个给如"安全网络服务器"的应用程序,提供加密功能的库.
    在使用之前,请确保您读过该应用程序(OpenSSL)的文档.
    "INSTALL"文档解释了怎么安装该库.
        OpenSSL包括一个命令行工具,能使用他执行各种加密函数.
    "openssl(1)"操作手册解释了他的用法.面向开发者的文档已经码好.

    很多操作页面已经有效了,"libcrypto"和"libssl"的文档在"crypto(3)"和"ssl(3)"操作页面.

        OpenSSL的操作页面被安装于"/usr/local/ssl/man/",
    或其他目录,如您指定了一个目录于"INSTALL"配置,另外,
    您可以读当前版本的,浏览<URL: http://www.openssl.org/docs/>.
    须知:在线的文档对应于最新的OpenSSL的开发版本,
    可能包括一些发行版没有的特性.如您对文档存在疑问,
    请参考您自己正在使用的版本.
        对于"libcrypto"相关的信息,还未归档,
    您可能要阅读"Ariel Glenn"的原先0.9版本SSLeay的文档,
    <URL: http://www.columbia.edu/~ariel/ssleay/>,
    这里很多内容还使用于当下.
        证书扩展(certificate extensions)和"PKCS#12"的文档,
    可以从"doc/openssl.txt"查到.
        最初的"SSLeay"文档,位于"doc/ssleay.txt"目录,
    当没有其他的辅助资料,她是很有用的,但须知,
    她对应的版本是过时的"0.6.6"版本.
        
怎么 能联系上OpenSSL的开发者?
-> "README"上解释了怎么去提交一个bug报告和补丁到OpenSSL.
    邮件列表上的信息是可用的,网址在<URL: http://www.openssl.org>.

哪里 我能得到一份编译后的版本?
-> 您能找到二进制分发包,
    网址在<URL: http://www.openssl.org/related/binaries.html>.
        有些应用程序使用OpenSSL的二进制分发包,当使用这种应用程序的时候,
    您不必安装OpenSSL,该应用程序会包含需要的部分(比如DLL).
        如您想构建OpenSSL于Windows系统,您不必拥有一个C编译器.
    读下"INSTALL.W32"中的"Mingw32"部分,
    关于怎样得到和安装"福瑞"(free)"GNU C"编译器.
        很多"Linux"和"*BSD"的分发包包含OpenSSL.
    
为啥 有"autoconf"和"libtool"不用,(而自己用"perl"写构建脚本)?
-> "autoconf"很有可能在将来版本的OpenSSL使用,
    如她能更少的以"Unix"为中心,她或许能被使用得更早.

什么 是"engine"的版本?
-> 在0.9.6版本的OpenSSL中,扩展了对外部加密硬件设备的接口.
    这实现于一个特殊的发行版"0.9.6-engine".
    在"0.9.7"版本的中,合并到了一个开发主线中.
    所以该特殊的发行版不再是必需的了.

怎么做 我才能校验OpenSSL分发包(distribution)的真实性(authenticity)?
    我门提供对每个压缩包(tarball)"MD5"摘要和"ASC"的签名,
    使用"MD5"校验一个压缩包,等效于从一个镜像地址:
        "md5sum TARBALL | awk '{print $1;}' | cmp - TARBALL.md5"
        您可以使用"pgp"或"gpg"来校验真实性.
    如您需要OpenSSL团队成员的公钥,以用来做签名,
    地址在<URL: http://www.openssl.org/about/>.然后只要:
        "pgp TARBALL.asc"

[LEGAL]法律/协议 ==================================================================
是否 我需要专利许可才能使用OpenSSL?
-> "README"中的专利部分将使用于您,如您使用OpenSSL.
    要得到知识产权(intellectual property rights)方面的信息,请咨询律师.
    OpenSSL不提供法律方面的建议.
        您可以配置OpenSSL,不使用"IDEA","MDC2","RC5"等模块:
        "./config no-idea no-mdc2 no-rc5"
    
是否 我能使用OpenSSL,结合"GPL"软件?
-> 在许多系统包括大部分的"Linux"和"BSD"的分发包,是的.
    ("GPL"并不添加使用部分来自通常的操作系统分发包的限制.)
        在一些其他的系统上,情形就不是那么清晰(clear)了.
    "GPL"软件版权所有者明确声明您违反他们的权利,
    如您在那些通常不包含OpenSSL的操作系统上,结合他们的软件使用OpenSSL.
        如您欲使用OpenSSL开发开源软件,
    您可以发现选择其他的协议更有用,而不是"GPL".或显式声明:
    "本软件发布在"GPL"协议下,附加豁免,
    即针对于编译,连接,"与/或"使用OpenSSL是允许的."
    ("This program is released under the GPL with the additional exemption that
    compiling, linking, and/or using OpenSSL is allowed")
    
[USER]应用程序 ===================================================================
为啥 我得到"PRNG not seeded"的错误提示?
-> 加密软件需要不可预知数据的源(source),以准确的工作.
    许多开源操作系统提供随机混乱设备("randomness device"),
    位于"/dev/urandom"或"/dev/random",为上述目标服务.
    所有的OpenSSL的版本默认使用"/dev/urandom",开始于"0.9.7".
    OpenSSL开始尝试"/dev/random",如"/dev/urandom"不可用.
        在其他操作系统中,应用程序不得不调用"RAND_add()"或"RAND_seed()"函数,
    传以合适的数据,在生成密钥或运行公钥加密之前.这些函数初始化伪随机数生成器
    (Pseudo-Random Number Generator, PRNG).有些损坏的(broken)应用程序不使用这些.
    就像"0.9.5"版本的需要随机数的OpenSSL函数,如发现随机数生成器不能生发(seed)
    一个至少128比特的随机数,就会报告错误.如错误发生且没有在应用程序的文档中讨论过,
    请联系应用程序的作者.事实上,他可能从来没有工作正常过.
    "0.9.5"版本以及后续版本使该错误可见,通过拒绝运行潜在的不安全加密.
        如您使用"Solaris 8",您可以添加"/dev/urandom"和"/dev/random"设备,
    通过安装"112438 (Sparc)"和"112439 (x86)"的补丁.
    在下列补丁查找器中找到可用的: <URL: http://sunsolve.sun.com>.
    "Solaris 9"中默认包括了这些设备.
    欲知道更多的关于"/dev/random"相关的信息,请访问:
    <URL: http://sunsolve.sun.com/pub-cgi/retrieve.pl?doc=fsrdb/27606&zone_32=SUNWski>
    (the SUNWski package is available in patch 105710)
        在一些没有"/dev/urandom"和"/dev/random"的系统中,使用
    "Entropy Gathering Demon (EGD)"是个好主意.详情参见"RAND_egd()"操作手册.
    从"0.9.7"版本开始,OpenSSL自动在"/var/run/egd-pool","/dev/egd-pool",
    "/etc/egd-pool"和"/etc/entropy"查找"EGD"套接字.
        大部分命令行工具自动尝试从文件中生发(seed)随机数生成器.
    默认生发(seeding)文件由下列条件决定:如环境变量"RANDFILE"中设置了,
    会以该变量的值命名她.否则,如环境变量"HOME"设置了,
    会以"$HOME/.rnd"命名她.另一方面,直到"0.9.6"的OpenSSL,
    会使用当前目录下的".rnd"文档,但是"0.9.6a"不会使用默认的查找目录.
    "0.9.6b"行为类似于"0.9.6a",但会使用"C:\"作为默认的"HOME"在windows平台,
    如环境变量(RANDFILE或HOME)都没有设置的话.
        如默认生发(seeding)文件不存在或太短,将会报"PRNG not seeded"错.
        openssl的命令行工具将回写(write back)新的默认状态到生发(seeding)文件
    (如没有将创建之),除非不能充分的生发.
        "$RANDFILE"指向一个"信息熵收集伺服套接字"(Entropy Gathering Daemon socket)
    不能工作.请使用OpenSSL命令行工具的"-rand"选项代替."$RANDFILE"环境变量
    和"$HOME/.rnd"是只用于OpenSSL命令行工具的.应用程序,使用OpenSSL库的,
    提供了他们自己的配置选项"s"用于指定"信息熵".请查阅关于应用程序的文档.
        
为啥 我得到"unable to write 'random state'"的错误提示?
-> 有时候,命令行工具不是因随机数生成器不能生发("PRNG not seeded")
    报错罢工,而是抱怨不能写随机状态("unable to write 'random state").
    见上个问题的答案,该信息表明她偏爱默认的生发文件.
    一个可能的原因是没有默认的文件名,因为"RANDFILE"和"HOME"没有设置.
    直到"0.9.6",还是使用当前目录的".rnd"文件,但是"0.9.6a"已经改变了.
    
怎么做 我创建证书(certificates)或证书请求(certificate requests)?
-> 查阅(check out)"CA.pl(1)"操作页面.
    她提供了一个简单的对"req","verify","ca","pkcs12"工具的包装.
    更好的控制查阅针对独立工具的操作说明和证书扩展文档,当前在"doc/openssl.txt".
    
为啥 我不能创建证书请求(create certificate requests)?
-> 您可能得到如下的典型性的错误:
        "在创建证书请求时,不能找到著名的名字
        ("distinguished_name")于配置中."
    这是因为他不能找到配置文件.检查"req(1)"中的诊断("DIAGNOSTICS")部分.
    
为啥 "SSL"程序崩溃于证书校验(certificate verify)错误?
-> 该问题经常表示log消息会抱怨不能找到本地发行者的证书
    ("unable to get local issuer certificate")
    或自签名的证书("self signed certificate").
    当一枚证书被OpenSSL校验其根"CA"为可信任的("trusted").
    通常,这意味着其"CA"证书必须被置于一个目录或文件中,
    且相关的程序被配置得去读他.OpenSSL程序校验的行为都比较类似,
    还有议题("issues")类似的错误消息.详情请见"verify(1)"操作手册.
    
为啥 我只能使用弱密码(weak ciphers),当我用OpenSSL连上服务器?
-> 大体上,由于您使用旧的导出级别(export grade)浏览器,
    她只支持弱加密.升级您的浏览器到支持128比特的密码.
    
怎么做 我才能创建"DSA"证书?
-> 请看"CA.pl(1)"操作手册,以获得"DSA"证书的例子.
    
为啥 我不能使用"DSA"证书创建SSL连接?
-> 通常,您会看到一条消息称"不存在分享的密码"(shared ciphers),
    但是,同样的安装/设置(setup)对于"RSA"的证书却工作良好.
    这可能存在两方面的原因:客户端不支持"DSA"服务器的连接.
    大部分的网络浏览器,包括网景("Netscape")和微软IE("MSIE"),
    只支持连上"RSA"密码套装(cipher suite).
    另外,"DH"的参数集没有提供给服务器."DH"参数能被"dhparam"命令创建,
    被"SSL_CTX_set_tmp_dh()"函数加载.详细请查阅"apps/s_sever.c"的"s_server"部分.
    
怎么做 我才能去除一个私钥的口令(passphrase)?
-> 首先您必须确定是真的要这么做.
    放着私钥不加密,是一个很大的安全风险.
    如您觉得这么做,可以参考"rsa(1)"中的"EXAMPLES"部分和"dsa"的操作手册.
    
为啥 我不能使用OpenSSL证书做SSL客户端认证?
-> 通常,这种情况发生在:当服务端程序请求认证,
    他没有包含您的证书或
    提示您没有客户端证书("you have no client certificates")(Netscape),
    或展示给您一条空的列表框("an empty list box")(MSIE).
    原因在于,服务端请求客户端证书时,包括一个她信任的"CA"名字列表.
    浏览器会让您选择该列表中的证书,
    因为几乎不会发生服务端拒绝发送/展示(present)她的证书的情况.
        解决方法就是添加相关的"CA"证书到服务器"可信任CA链"中.
    怎么操作取决于您使用的服务器软件.您能通过以下命令打印出信任的CA们:
    "openssl s_client -connect www.some.host:443 -prexit"
    (www.some.host替换成自己的).
    如您的服务器只请求某个"URL"的证书,那么您只需要手动发出(issue)
    "HTTP"的"GET"命令去得到该列表,当"s_client"连接的时候:
    "GET /some/page/needing/a/certificate.html".(/../xx/yy.html替换成您的)
    如您的"CA"没有出现在该列表中,那么她证实了该问题.
    
为啥 我的浏览器发出"不匹配的主机名"(mismatched hostname)的报警?
-> 浏览器预期/假设(expect)服务器的主机名和证书的一般名字("commonName/CN")域匹配.
    如不匹配,您将获得该警告.

怎么做 我才能安装一个CA证书到一个浏览器?
-> 通常的方法是发送一个"DER"编码的证书到浏览器,作为"MIME"类型.
    比如点击一个适当的连接"application/x-x509-ca-cert".
    在"MSIE"的某个扩展名为".der"或".cacert"也可以个工作,
    或您可以用一个导入证书的向导(wizard)导入.
        您可以转化一个证书到"DER"格式,使用如下命令:
    "openssl x509 -in ca.pem -outform DER -out ca.der".
    偶尔某人会建议您使用如下命令:
    "openssl pkcs12 -export -out cacert.p12 -in cacert.pem -inkey cakey.pem".
    请千万不要这么做!!该命令去掉了您CA的私钥,将您的安全系数降到了零.
    允许任何人在任何他们选择名字上伪造(forge)证书.

为啥 OpenSSL"x509"的"DN"输出跟"RFC2253"不一致?
-> 打印"可区别的名字"(Distinguished Name/DN)的一行格式(oneline format),
    已经被"0.9.7"版本的OpenSSL扩展了.
    使用新的"X509_NAME_print_ex()"接口,
    "-nameopt"选项将会被输出(introduded).
    详情参见"openssl x509"的命令行工具.
    考虑到兼容性,旧的行为将被保留作为默认(输出).

什么 是一个"128比特的证书"?我能使用OpenSSL创建一个吗?
-> 术语"128比特的证书"(128 bit certificate),
    是一个高度误导性的市场化(广告宣传)术语,
    他不涉及证书中的公钥长度!
    一个证书包括一个128比特的"RSA"密钥将拥有可忽略的安全性.:-)
        还存在各种相关的名字,像"magic certificates",
    "SGC certificates", "step up certificates"等等.
        一般地,我们不能使用OpenSSL创建这种证书,
    而且也没必要去这么做.现在的浏览器一般对无限强的密钥(加密)有效.
        对于强加密(密钥)导出是存在很强的限制的.
    美国软件只有弱加密算法(刚开始40比特,后来56比特),才能自由导出.
    普遍认为,这样是不合适的.放宽规则允许用户使用强加密(的密钥),
    不过仅对于授权的服务器.
        2个稍有差别的基础发展用来支持这个:
    一个是网景所谓的"step up", 另外一个是微软所谓的"Server GatedCryptography/SGC"
    当一个浏览器初始连接一个服务器是,他会检查她的证书
    是否包含某款扩展,且被权威机构授权分发的.
    如测试成功,则采用强加密重连接.
        只有某(初始一个)证书权威可以分发证书,
    通常,他们的花费(cost)普通证书高很多.
        虽然OpenSSL可以创造证书,包含适当的扩展.
    该证书将不会来自允许的权威机构,从而不会被认知(信任).
        导出法则将来会被修改:允许大部分地非限制使用强加密算法(的密钥).
    所以这些证书将会废弃(过时).
    
为啥 OpenSSL设置认证密钥标识(authority key identifier/AKID)扩展失败?
-> 他(本来就)不能:该扩展经常导致混乱(confusion).
        考虑一个证书链 A->B->C, 从而A签名了B,B签名了C.假设C包含AKID.
    该扩展的目的是鉴别权威证书B,只要包含B的科目(subject)密钥标识,
    或他的发行者名(issuer name)和序列号.后一种情况因为鉴别证书B,
    必须包含发行者名(issuer name)和B的序列号.
    他常常错误地假定他必须包含B的科目(subject)密钥名.
    如他这么做,这将存在冗余信息.因为C将包含双份的发行者名.
    
怎么做 才能设置一簇商业根CA证书?
-> OpenSSL发布(ship)不带有任何根CA证书,
    因为OpenSSL项目没有任何政策(policy)去包含或者不包含任一指定的"CA",
    且没有打算去设置这样的政策.
    决定支持什么CA取决于应用开发者或管理员.
        其他项目有其他的政策,所以您可以提取
    用于"Mozilla"或"modssl"的CA簇,就像下篇文章描述的:
     <URL: http://www.mail-archive.com/modssl-users@modssl.org/msg16980.html>

[BUILD]构建 =======================================================================
为啥 连接器抱怨未定义的符号?
-> 可能是编译中断了,而不知道某样东西缺失,
    尝试敲"make clean; make".
        如您使用"./Configure"替代"./config",
    请确保正确的标的(target),文件格式可能在不同版本的OS中会不同,
    比如"sparcv8/sparcv9",对应"a.out/elf".
        如您得到下列对象的符号错误,请使用"./config"中的"no-asm"选项,
    详情参见"INSTALL":
            BF_cbc_encrypt, BF_decrypt, BF_encrypt, CAST_cbc_encrypt,
            CAST_decrypt, CAST_encrypt, RC4, RC5_32_cbc_encrypt, RC5_32_decrypt,
            RC5_32_encrypt, bn_add_words, bn_div_words, bn_mul_add_words,
            bn_mul_comba4, bn_mul_comba8, bn_mul_words, bn_sqr_comba4,
            bn_sqr_comba8, bn_sqr_words, bn_sub_words, des_decrypt3,
            des_ede3_cbc_encrypt, des_encrypt, des_encrypt2, des_encrypt3,
            des_ncbc_encrypt, md5_block_asm_host_order, sha1_block_asm_data_order
        如上述tips对您没有帮助,您可以尝试使用当前的快照(snapshot),
    如问题还存在,请提交一个bug报告.
    
为啥 OpenSSL测试失败,提示"bc: command not found"?
-> 您没有安装"bc",一个"Unix"的计算器.
    如您要跑该测试,请到"ftp://ftp.gnu.org"或您的OS发行官网,下载"GNU bc".
    
为啥 OpenSSL测试失败,提示"bc: 1 no implemented"?
-> 在某些"SCO"安装版本上,当您用"make test"命令跑一个测试套件(test suite)时,
    "bc"会抛出一个"bug".错误消息提示:bc:1没有实现("bc: 1 not implemented").
        最好的处理方法就是找一个"bc"另外的实现版本,编译/安装他.
    例如,"GNU bc"就能安全的使用.
    其下载说明参见<URL: http://www.gnu.org/software/software.html>.
    
为啥 OpenSSL测试失败,提示"bc: stack empty"?
-> 在某些"DG/ux"版本中,在OpenSSL的大数测试("bntest")的时候,
    "bc"开的堆栈太小了.当您敲"make test"的时候,
    会触发这个错误,返回的消息:bc栈为空("bc: stack empty").
        最好的处理方法就是找一个"bc"另外的实现版本,编译/安装他.
    例如,"GNU bc"就能安全的使用.
    其下载说明参见<URL: http://www.gnu.org/software/software.html>.
    
为啥 OpenSSL编译失败,在"Alpha Tru64 Unix"平台?
-> 在某些"Alpha"设备上,跑"Tru64 Unix"和"Compaq C",
    "crypto/sha/sha_dgst.c"将失败,返回消息:内存不足以继续编译
    ("Fatal:  Insufficient virtual memory to continue compilation.").
        就像该测试消息显示的,这可能是编译器的一个bug,
    他消耗光了大量的用户(resident)内存,用来建立表啊什么的东西.
    问题明显在其优化代码模块,因为一旦去掉"完全优化"选项("-O0"),
    编译过程就顺利通过了.
    且编译器只消耗了2M的用户内存,而不是240M或其当前的上限.
    有三种方法可以解决这个问题:
        1.调高当前数据段大小的上限.
        实验结果表明,241000K字节就足够了,在"AlphaServer DS10"平台.
        您可以敲"ulimit -Sd nnnnnn",
        这里的nnnnnn就是要设置的内存上限,单位KB.
        2.如您的内存小于您需要的大小,且不能改变.
        可以在编译OpenSSL的加上"-O0"级别.
        但这是那些完美主义者不乐见的结果.
        稍微复杂的方案如下:
        ----- snip:start -----
            make DIRS=crypto SDIRS=sha "`grep '^CFLAG=' Makefile.ssl | \
                sed -e 's/ -O[0-9] / -O0 /'`"
            rm `ls crypto/*.o crypto/sha/*.o | grep -v 'sha_dgst\.o'`
            make
        ----- snip:end -----
        这样就只用"-O0"选项编译"sha_dgst.c",
        其余的优化级别,配置过程会自己选择.
        上面的完成了之后,做下测试和安装就行了.
        3.用"no-sha0"选项重配置,去掉"SHA0"模块.
        这不应该也没在"SSL/TLS"或其他的验证协议中.
        
为啥 OpenSSL编译失败,提示"ar: command not found"?
-> 通常在"Solaris 2"平台上获得该消息提示,
    因为"Sun"公司隐藏了"ar"和其他的开发包命令,
    通过排除他们的目录于默认的"$PATH"目录.
    一个这种目录是"/usr/ccs/bin".
    快速测试以修复他,操作如下(假定您使用"sh"或兼容"sh"的壳(Shell)):
    ----- snip:start -----
     PATH=${PATH}:/usr/ccs/bin; export PATH
    ----- snip:end -----
    然后重新编译.
    您只要做的就是确保"/usr/ccs/bin"目录是永久的在"$PATH"中.
    比如通过您的"profile"文件(再次假定您使用"sh"或兼容"sh"的壳(Shell)).
    
为啥 OpenSSL编译失败,在"Win32"平台下使用VC++?
-> 有时候,您可能会得到VC++命令行"cl"报告
    不能找到标准包含文件像"stdio.h"或其他的奇葩.
    可能的原因是环境设置错误.
    直到VC6版本,在VC的安装目录下的bin目录下
    找到并运行"VCVARS32.BAT";
    对于VC7以上的版本,也叫VS.NET,
    该文件名变为"VSVARS32.BAT".
    运行该脚本要在运行"NMAKE"之前,
    改变的仅仅是当前合法的DOS会话.
    
什么 特殊的要求,关于OpenSSL在"Redhat"平台下要具备?
-> Red Hat Linux (release 7.0 and later) include a preinstalled limited
    version of OpenSSL. For patent reasons, support for IDEA, RC5 and MDC2
    is disabled in this version. The same may apply to other Linux distributions.
    Users may therefore wish to install more or all of the features left out.

    To do this you MUST ensure that you do not overwrite the openssl that is in
    /usr/bin on your Red Hat machine. Several packages depend on this file,
    including sendmail and ssh. /usr/local/bin is a good alternative choice. The
    libraries that come with Red Hat 7.0 onwards have different names and so are
    not affected. (eg For Red Hat 7.2 they are /lib/libssl.so.0.9.6b and
    /lib/libcrypto.so.0.9.6b with symlinks /lib/libssl.so.2 and
    /lib/libcrypto.so.2 respectively).

    Please note that we have been advised by Red Hat attempting to recompile the
    openssl rpm with all the cryptography enabled will not work. All other
    packages depend on the original Red Hat supplied openssl package. It is also
    worth noting that due to the way Red Hat supplies its packages, updates to
    openssl on each distribution never change the package version, only the
    build number. For example, on Red Hat 7.1, the latest openssl package has
    version number 0.9.6 and build number 9 even though it contains all the
    relevant updates in packages up to and including 0.9.6b.

    A possible way around this is to persuade Red Hat to produce a non-US
    version of Red Hat Linux.

    FYI: Patent numbers and expiry dates of US patents:
    MDC-2: 4,908,861 13/03/2007
    IDEA:  5,214,703 25/05/2010
    RC5:   5,724,428 03/03/2015


为啥 OpenSSL编译失败,在"MacOS X"平台下?
-> If the failure happens when trying to build the "openssl" binary, with
    a large number of undefined symbols, it's very probable that you have
    OpenSSL 0.9.6b delivered with the operating system (you can find out by
    running '/usr/bin/openssl version') and that you were trying to build
    OpenSSL 0.9.7 or newer.  The problem is that the loader ('ld') in
    MacOS X has a misfeature that's quite difficult to go around.
    Look in the file PROBLEMS for a more detailed explanation and for possible
    solutions.

为啥 OpenSSL测试套装(test suite)失败,在"MacOS X"平台下?
-> If the failure happens when running 'make test' and the RC4 test fails,
    it's very probable that you have OpenSSL 0.9.6b delivered with the
    operating system (you can find out by running '/usr/bin/openssl version')
    and that you were trying to build OpenSSL 0.9.6d.  The problem is that
    the loader ('ld') in MacOS X has a misfeature that's quite difficult to
    go around and has linked the programs "openssl" and the test programs
    with /usr/lib/libcrypto.dylib and /usr/lib/libssl.dylib instead of the
    libraries you just built.
    Look in the file PROBLEMS for a more detailed explanation and for possible
    solutions.
    
为啥 OpenSSL测试套装(test suite)失败,在"64-bit"平台下测试"BN_sqr"?
-> 测试"BN_sqr"失败,大部分原因是出在错误的配置当前平台,
    或缺少支持的平台.
    运行"./config -t"和"./apps/openssl version -p",
    平台的标识匹配吗?如不匹配,可能原因就出在这里.
    因此您最好报告下bug,(注:因为您的"./config"过了但是没正确配置.)
    如"./config"运行失败,可能原因是您本地环境变量有问题,
    请将问题反馈给系统管理员或类似人员.
    如平台标识都匹配或系统在"./config"中没有可变的标识,
    那么您的系统就是不支持的,他可能有可能没有跑过.
    特别需要注意的是"SPARC64"平台,"GNU C"编译器下,
    您应跑"./config -m32"命令,来生成一个可工作的构建(build).
    我知道"-m32"那个不是您需要的,但是该构建是可运行的.
    详情参见"<URL: openssl-dev@openssl.org>."
    
为啥 "OpenBSD-i386"构建"des-586"失败,提示"未实现的段类型"?
-> 为了机器代码的位置无关性考虑,
    "0.9.7"汇编器运行时进行了大手术(overhauled),
    这对于共享库的支持是必要的.
    出于某种原因,带着过时的"GNU"汇编器的OpenBSD
    找到了新代码的"坏味道"(offensive).
    为了解决这个问题,配置结合"no-asm",牺牲大量的性能.
    或给您的汇编器打补丁.
    参见<URL: http://www.openssl.org/~appro/gas-1.92.3.OpenBSD.patch>.
    出于方便您,预编译重定位二进制文件,
    参见<URL: http://www.openssl.org/~appro/gas-1.92.3.static.aout.bin>.
    据说更早的"*BSD a.out"平台也受这个问题的困扰,
    "药方"(remedy)应该是一样的.
    如二进制文件是静态连接的,应该能工作于更广泛版本的"BSD"分支,
    而不仅仅只是"OpenBSD".
    
为啥 OpenSSL测试套装,测试"sha512t"失败,在"x86"平台?
-> 如测试程序失败带有"SIGILL",非法的指令异常,
    那么您最好运行在"SSE"兼容的"CPU",比如"Intel P4",
    在不支持"SSE2"指令集的内核控制下.
    详情参见"INSTALL"对应的部分和"OPENSSL_ia32cap(3)"操作手册.
    
为啥 编译器编译"sha512.c"失败?
-> OpenSSL"SHA-512"的实现依赖于支持64位整型的编译器.
    对于更早的编译器,比如"ULTRIX cc, SCO compiler to mention a couple"等,
    不支持这种类型,导致不能编译.
    建议去掉"SHA-512"模块,添加"no-sha512"选项到"./config"或"./Configure"中.
    另外一种选择就是切换到"GCC".
    
怎么办 测试套装失败?
-> 另一常见错误原因是:完成某些特定测试的时候,
    仅仅错误代码产生于运行时工具链中有bug的组件或组件缺失.
    几乎很少的用例归档于"PROBLEMS"文件,
    对于可能情况请先查阅,在大吵大闹(beat the drum)之前.
    即使您没有找到解决方案/方法,请保留她是个编译器bug的可能性.
    编译器bug可能出现以相当奇异的方式,
    没有让人感觉到,然后在您觉得最预期不到的地方出现.
    为了去标识他,去掉优化级别等通过编辑根目录"Makefile"的"CFLAG"行,
    然后重新编译和重运行测试.
    
怎么做 我想找到了一bug?
-> 如果您是一个新手,那么很可能您找不到bug,
    某些东西发生于您不熟悉的领域.
    检查"FAQ",结合文档和邮件列表以查找类似的质疑.
    如您还是不确定她是否是一个bug,

    提交一个疑问到"openssl-users"这个邮件列表.


怎么 报告,我确定我找到了一bug?

-> Bug reports with no security implications should be sent to the request
    tracker. This can be done by mailing the report to <rt@openssl.org> (or its
    alias <openssl-bugs@openssl.org>), please note that messages sent to the
    request tracker also appear in the public openssl-dev mailing list.

    The report should be in plain text. Any patches should be sent as
    plain text attachments because some mailers corrupt patches sent inline.
    If your issue affects multiple versions of OpenSSL check any patches apply
    cleanly and, if possible include patches to each affected version.

    The report should be given a meaningful subject line briefly summarising the
    issue. Just "bug in OpenSSL" or "bug in OpenSSL 0.9.8n" is not very helpful.

    By sending reports to the request tracker the bug can then be given a priority
    and assigned to the appropriate maintainer. The history of discussions can be
    accessed and if the issue has been addressed or a reason why not. If patches
    are only sent to openssl-dev they can be mislaid if a team member has to
    wade through months of old messages to review the discussion.
    
    See also <URL: http://www.openssl.org/support/rt.html>
    

怎么 报告,我找到了一个安全话题(issue)?

-> If you think your bug has security implications then please send it to
    openssl-security@openssl.org if you don't get a prompt reply at least
    acknowledging receipt then resend or mail it directly to one of the
    more active team members (e.g. Steve).

[PROG]编程
是否 OpenSSL是线程安全的?
-> 是的(带有限制:"SSL"连接可能不是被当前多线程环境可用).
    在Windows和很多"Unix"系统中,
    "OpenSSL"自动使用多线程版本的标准库,
    如非上述平台,请查询"INSTALL"文件.
        多线程应用程序必须提供2个回调函数给"OpenSSL",
    通过调用"CRYPTO_set_locking_callback()"和"CRYPTO_set_id_callback()",
    对于"OpenSSL"的所有版本直到"0.9.8"[abc...].
    作为"1.0.0"版本,"CRYPTO_set_id_callback()"和相结合的API废弃了,
    取而代之的是"CRYPTO_THREADID_set_callback()"和她的朋友们.
    
为啥 我编译了一个程序于windows平台,崩溃了,泪奔~~?
-> 很可能是因为您缺失"INSTALL.W32"的命令.
    您的应用程序必须链接以相同版本的"Win32"运行时库,
    就是openssl库链接的那些.
    默认版本的"OpenSSL"链接采用"/MD",就是多线程DLL.
        如您使用"Microsoft Visual C++'s IDE"(Visual Studio),
    在很多例子中,您新的工程最好链接以"ML",就是调试单线程.
    他和"/MD"是不可交换的,否则您的程序将崩溃,
    特别是"BIO"相关的读写操作时候.
        对于用WIN32的六个可能链接阶段配置,
    您的应用程序必须链接和OpenSSL创建时候创建时相同的库.
    改变MS Visual C++ (Studio),操作步骤如下:
     1. Select Settings... from the Project Menu.
     2. Select the C/C++ Tab.
     3. Select "Code Generation from the "Category" drop down list box
     4. Select the Appropriate library (see table below) from the "Use
        run-time library" drop down list box.  Perform this step for both
        your debug and release versions of your application (look at the
        top left of the settings panel to change between the two)

        Single Threaded           /ML        -  MS VC++ often defaults to
                                                this for the release
                                                version of a new project.
        Debug Single Threaded     /MLd       -  MS VC++ often defaults to
                                                this for the debug version
                                                of a new project.
        Multithreaded             /MT
        Debug Multithreaded       /MTd
        Multithreaded DLL         /MD        -  OpenSSL defaults to this.
        Debug Multithreaded DLL   /MDd
    Note that debug and release libraries are NOT interchangeable.  If you
    built OpenSSL with /MD your application must use /MD and cannot use /MDd.
        每个"0.9.8"版本,上述对"DLLs"的限制去除了.
    OpenSSL以某特定的运行时编译选项(我们坚持以"/MD"为默认),
    可以被其他选项或其他编译器编译的应用程序发布.
    但是这里有个注意点(catch)!
    取代重编译的OpenSSL的工具集,
    当您不得不和以前版本的,
    您不得不用编译器编译您选择的"与/或"小的C片段(C snippet).
    该小片段安装在
    <install-root>/include/openssl/applink.c,
    应当添加到您的应用程序或简单地包含(只包一次)到您的应用程序.
    链接该小垫片(shim)模块进您应用程序的清单失败,
    将报严重的运行时错误"no OPENSSL_Applink".
    一个显式的提醒是在这种情况下,
    优先添加"CRYPTO_malloc_init"到OpenSSL很重要.
    
怎么做 我能读写"DER"编码的缓存(buffer),使用"ASN1"函数?
-> 您有2个选择:使用内存BIO,
    结合"i2d_*_bio()"或"d2i_*_bio()"函数,
    或直接使用"i2d_*(), d2i_*()"函数.
    因为他们是经常导致悲剧的原因.
    这里有一些代码片段使用"PKCS7"作为例子:
    ----- snip:start -----
    unsigned char *buf, *p;
    int len;

    len = i2d_PKCS7(p7, NULL);
    buf = OPENSSL_malloc(len); /* or Malloc, error checking omitted */
    p = buf;
    i2d_PKCS7(p7, &p);
    ----- snip:end -----
    buf包含"DER"编码的p7.
    这里,p7包含合法的"PKCS7"结构,填充以NULL,
    如一个错误发生,"ERR_print_errors(bio)"应该能得到更多的信息.
        需要临时变量p的原因是,"ASN1"函数改变(增长)了传入的指针,
    以准备好去读写下一个结构.这样经常导致一系列错误:
    没有临时变量,缓冲指针buf改变了去指向下个她读取/写入的数据.
    这可能导致未初始化的数据.当释放该缓冲,
    将导致不可预期的结果,因为他不再指向同一个地址.
    
是否 OpenSSL支持"BER"编码,OpenSSL使用"DER",但我需要"BER"?
-> 简明的回答是"是的",因为"DER"是"BER"的特例,
    OpenSSL"ASN1"解码器能处理"BER".
        详细的回答是,"ASN1"结构支持以很多不同的方式的编码.
    该方式的一个集合是:各种可允许的编码的"BER".
    "DER"(Distinguished Encoding Rules)是"BER"一个限制的集合:
    他们唯一地指定怎样一个给定的结构的编码方式.
    因此,"DER"是"BER"的特殊情况,
    DER是"BER"可接受/兼容(acceptable)编码.
    
为啥 我尝试使用"M_some_evil_pkcs12_macro"却得到错误?
-> 通常,当您尝试用C++编译器,
    编译"PKCS#12"宏有关的代码,发生上述情况.
    在一个程序中,几乎不存在需要使用"PKCS#12"宏,
    因为用"PKCS12_parse()"和"PKCS12_create()"函数,
    能更容易的解析和创建"PKCS#12".
    文档在"./doc/openssl.txt",例子在"demos/pkcs12",
    这个"pkcs12"应用程序不得不使用这些宏因为要打印调试信息.
    
为啥 我调用"某些函数",却失败?
-> 在提交报告或在邮件列表中问,您应该试着确定成因.
    特别是,您应该调用"ERR_print_errors()"或"ERR_print_errors_fp()",
    在失败的调用之后,见是否这条消息有帮助.
    须知:问题可能比您更早地发生.
    您该在可能的地方每次调用检查错误,
    否则,真正的原因可能隐藏因为OpenSSL函数清除了错误状态.

什么 她们的意思,我刚刚加载一个数字,在错误输出时?
-> 准确格式的描述见"ERR_print_errors()"操作手册.
    您该在她之前先调用"ERR_load_crypto_strings()",
    消息会以文本格式输出.
    如您不能这么做(比如,得到的是一个已经编译好的二进制包),
    您能使用"errstr"工具,传入错误代码(16进制文件第二个冒号后面的数字).
    
为啥 我得到错误,关于未知的算法?
-> 成因是忘记调用导入OpenSSL算法表的函数"OpenSSL_add_all_algorithms()".
    详情见操作手册.
    这能引起多种问题,比如不能读入一个加密的"PEM"文件,
    不能解密"PKCS#12"文件,当验签时签名失败.
    
为啥 我不能使用OpenSSH的配置脚本侦测(detect)OpenSSL?
-> 自动检测问题,有多种原因:
    OpenSSH需要至少"0.9.5a"的OpenSSL库.
    有时候,系统已经安装了旧版本的OpenSSL,
    旧版地址被检测到,替代了新版地址.
    OpenSSL库可能编译成另一种"CPU"或另一种"模式"(32/64位).
    许可证可能会错.
    一般地,检查"config.log"文件,产生于OpenSSH配置脚本.
    他应该会包含详细的信息:
    关于OpenSSL库没有检测到或可能的不兼容的原因.
    
是否 我能使用OpenSSL的"SSL"库,结合非阻塞I/O?
-> 是的,弄明白"the SSL_get_error(3)"操作手册!
    要避免的陷阱:
    不要假设"SSL_read()"仅仅从基本传输或"SSL_write()"刚写入的.
    可能"SSL_write()"不能做什么有用的工作,直到一个数据去读.
    或者,"SSL_read()"不能做任何事情直到可能发送一个数据.
    一个可能的原因是:对方可能在协议的任何时候,
    请求一个新的"TLS/SSL"握手,需要一个双向的消息交换.
    SSL_read()和SSL_write()会尝试继续任一挂起的握手.
    
为啥 我不能使用我的服务器应用程序接收到客户端证书?
-> 根据"TLS"协议的定义,一个客户端仅发送一个证书.
    如服务端欲显式地发起请求,请用在SSL_CTX_set_verify()函数中,
    加入"SSL_VERIFY_PEER"标志,使能客户端证书的使用.
    
为啥 编译失败,提示"an undefined symbol NID_uniqueIdentifier"?
-> 对于"0.9.7"的OpenSSL,OID表已经被扩展和修正.
    对更早的版本,唯一标识(uniqueIdentifier)是不正确的使用于"X.509"证书.
    正确名字,根据"RDC2256(LDAP)"是"x500UniqueIdentifier".
    改变您的代码去使用新的名字,当编译"0.9.7"版本时.
    
是否 是一bug,我侦测到内存溢出?
-> 大多数情况下,一个明显的内存溢出的成因是:
    当一个应用启动时,一个OpenSSL内部表已经分配内存了.
    因为这样的表不会增长他的体积,所以他们是无害的.
        这些内部表能被释放掉,当一个应用使用多种函数关闭.
    当前,他们包括:
    当地线程的清除函数:
    "ERR_remove_state()"
    全局应用程序的清除函数,他能意识到使用情况(因此是线程安全的):
    ENGINE_cleanup()和CONF_modules_unload()
    "暴力"的(非线程安全)全局应用程序清除函数:
    ERR_free_strings(),EVP_cleanup()和CRYPTO_cleanup_all_ex_data().
    
为啥 "Valgrind"抱怨,使用未初始化的数据?
-> 当OpenSSL"PRNG"例程被调用去产生随机数时,
    提供的缓存(buffer)内容混合进了"熵(平均数)"池:
    所以技术上,缓存是否初始化是不重要的.
    "Valgrind"或其他的测试工具,将会抱怨这个.
    当使用"Valgrind",确保OpenSSL库能被编译,
    结合"PURIFY"宏定义("-DPURIFY"),甩掉这些警告.
    
为啥 内存BIO不能工作,但是文件工作正常?
-> 这种情况经常发生于比如读取一个"S/MIME"email消息,
    原因是内存BIO能做两件事中的一件,当所有的数据已经读出来了:
    默认的行为:指示没有更多的数据是可用的,函数调用应该重试.
    这时候允许应用程序去再次填充BIO,如有需要.
    或者,如到达"EOF",则表明没有更多可用的数据.
        如内存BIO的行为和文件的行为一样,
    那么第二次的行为是必须的.
        这必须被完成,通过调用"BIO_set_mem_eof_return(bio, 0);".
    详情参看操作手册.
哪里 找到"d2i_X509()"等函数的声明和实现?
-> 他们被定义和实现如下:
    DECLARE_ASN1_FUNCTIONS(X509)和IMPLEMENT_ASN1_FUNCTIONS(X509).
    传递"ASN1"模板,定义结构信息到一个"ASN1"的解释器,
    使用生成的函数,比如"ASN1_item_d2i".