aboutsummaryrefslogtreecommitdiff
path: root/openssl
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-09-12 11:27:51 +0200
committermarha <marha@users.sourceforge.net>2011-09-12 11:27:51 +0200
commitdafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0 (patch)
treebdf833cc6a4fc9035411779e10dd9e8478201885 /openssl
parent0b40f5f4b54453a77f4b09c431f8efc6875da61f (diff)
downloadvcxsrv-dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0.tar.gz
vcxsrv-dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0.tar.bz2
vcxsrv-dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0.zip
Synchronised line endinge with release branch
Diffstat (limited to 'openssl')
-rw-r--r--openssl/CHANGES18904
-rw-r--r--openssl/FAQ2050
-rw-r--r--openssl/LICENSE254
-rw-r--r--openssl/NEWS1176
-rw-r--r--openssl/README436
-rw-r--r--openssl/VMS/mkshared.com780
-rw-r--r--openssl/apps/makeapps.com2112
-rw-r--r--openssl/crypto/asn1/a_strex.c1148
-rw-r--r--openssl/crypto/asn1/a_strnid.c580
-rw-r--r--openssl/crypto/asn1/ameth_lib.c900
-rw-r--r--openssl/crypto/asn1/asn1.h2804
-rw-r--r--openssl/crypto/bio/bss_dgram.c1660
-rw-r--r--openssl/crypto/bio/bss_file.c954
-rw-r--r--openssl/crypto/comp/c_rle.c122
-rw-r--r--openssl/crypto/crypto-lib.com2790
-rw-r--r--openssl/crypto/dsa/dsa_ossl.c796
-rw-r--r--openssl/crypto/ec/ec2_smpl.c2084
-rw-r--r--openssl/crypto/ec/ec_key.c926
-rw-r--r--openssl/crypto/ec/ecp_smpl.c3438
-rw-r--r--openssl/crypto/engine/engine.h1666
-rw-r--r--openssl/crypto/install.com300
-rw-r--r--openssl/crypto/opensslv.h178
-rw-r--r--openssl/crypto/stack/safestack.h5150
-rw-r--r--openssl/crypto/ts/ts_verify_ctx.c318
-rw-r--r--openssl/crypto/x509v3/v3_addr.c2586
-rw-r--r--openssl/crypto/x509v3/v3_asid.c1686
-rw-r--r--openssl/engines/e_capi.c3648
-rw-r--r--openssl/engines/e_gmp.c960
-rw-r--r--openssl/engines/e_padlock.c2466
-rw-r--r--openssl/engines/makeengines.com2042
-rw-r--r--openssl/makevms.com2822
-rw-r--r--openssl/openssl.spec426
-rw-r--r--openssl/ssl/d1_enc.c578
-rw-r--r--openssl/ssl/d1_pkt.c3538
-rw-r--r--openssl/ssl/install.com180
-rw-r--r--openssl/ssl/s2_srvr.c2284
-rw-r--r--openssl/ssl/ssl-lib.com2232
-rw-r--r--openssl/ssl/t1_lib.c3494
-rw-r--r--openssl/test/maketests.com1972
-rw-r--r--openssl/util/mk1mf.pl2448
-rw-r--r--openssl/util/mkerr.pl1620
-rw-r--r--openssl/util/mkstack.pl384
42 files changed, 43446 insertions, 43446 deletions
diff --git a/openssl/CHANGES b/openssl/CHANGES
index 862321280..5cae85c9c 100644
--- a/openssl/CHANGES
+++ b/openssl/CHANGES
@@ -1,9452 +1,9452 @@
-
- OpenSSL CHANGES
- _______________
-
- Changes between 1.0.0c and 1.0.0d [8 Feb 2011]
-
- *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014
- [Neel Mehta, Adam Langley, Bodo Moeller (Google)]
-
- *) Fix bug in string printing code: if *any* escaping is enabled we must
- escape the escape character (backslash) or the resulting string is
- ambiguous.
- [Steve Henson]
-
- Changes between 1.0.0b and 1.0.0c [2 Dec 2010]
-
- *) Disable code workaround for ancient and obsolete Netscape browsers
- and servers: an attacker can use it in a ciphersuite downgrade attack.
- Thanks to Martin Rex for discovering this bug. CVE-2010-4180
- [Steve Henson]
-
- *) Fixed J-PAKE implementation error, originally discovered by
- Sebastien Martini, further info and confirmation from Stefan
- Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252
- [Ben Laurie]
-
- Changes between 1.0.0a and 1.0.0b [16 Nov 2010]
-
- *) Fix extension code to avoid race conditions which can result in a buffer
- overrun vulnerability: resumed sessions must not be modified as they can
- be shared by multiple threads. CVE-2010-3864
- [Steve Henson]
-
- *) Fix WIN32 build system to correctly link an ENGINE directory into
- a DLL.
- [Steve Henson]
-
- Changes between 1.0.0 and 1.0.0a [01 Jun 2010]
-
- *) Check return value of int_rsa_verify in pkey_rsa_verifyrecover
- (CVE-2010-1633)
- [Steve Henson, Peter-Michael Hager <hager@dortmund.net>]
-
- Changes between 0.9.8n and 1.0.0 [29 Mar 2010]
-
- *) Add "missing" function EVP_CIPHER_CTX_copy(). This copies a cipher
- context. The operation can be customised via the ctrl mechanism in
- case ENGINEs want to include additional functionality.
- [Steve Henson]
-
- *) Tolerate yet another broken PKCS#8 key format: private key value negative.
- [Steve Henson]
-
- *) Add new -subject_hash_old and -issuer_hash_old options to x509 utility to
- output hashes compatible with older versions of OpenSSL.
- [Willy Weisz <weisz@vcpc.univie.ac.at>]
-
- *) Fix compression algorithm handling: if resuming a session use the
- compression algorithm of the resumed session instead of determining
- it from client hello again. Don't allow server to change algorithm.
- [Steve Henson]
-
- *) Add load_crls() function to apps tidying load_certs() too. Add option
- to verify utility to allow additional CRLs to be included.
- [Steve Henson]
-
- *) Update OCSP request code to permit adding custom headers to the request:
- some responders need this.
- [Steve Henson]
-
- *) The function EVP_PKEY_sign() returns <=0 on error: check return code
- correctly.
- [Julia Lawall <julia@diku.dk>]
-
- *) Update verify callback code in apps/s_cb.c and apps/verify.c, it
- needlessly dereferenced structures, used obsolete functions and
- didn't handle all updated verify codes correctly.
- [Steve Henson]
-
- *) Disable MD2 in the default configuration.
- [Steve Henson]
-
- *) In BIO_pop() and BIO_push() use the ctrl argument (which was NULL) to
- indicate the initial BIO being pushed or popped. This makes it possible
- to determine whether the BIO is the one explicitly called or as a result
- of the ctrl being passed down the chain. Fix BIO_pop() and SSL BIOs so
- it handles reference counts correctly and doesn't zero out the I/O bio
- when it is not being explicitly popped. WARNING: applications which
- included workarounds for the old buggy behaviour will need to be modified
- or they could free up already freed BIOs.
- [Steve Henson]
-
- *) Extend the uni2asc/asc2uni => OPENSSL_uni2asc/OPENSSL_asc2uni
- renaming to all platforms (within the 0.9.8 branch, this was
- done conditionally on Netware platforms to avoid a name clash).
- [Guenter <lists@gknw.net>]
-
- *) Add ECDHE and PSK support to DTLS.
- [Michael Tuexen <tuexen@fh-muenster.de>]
-
- *) Add CHECKED_STACK_OF macro to safestack.h, otherwise safestack can't
- be used on C++.
- [Steve Henson]
-
- *) Add "missing" function EVP_MD_flags() (without this the only way to
- retrieve a digest flags is by accessing the structure directly. Update
- EVP_MD_do_all*() and EVP_CIPHER_do_all*() to include the name a digest
- or cipher is registered as in the "from" argument. Print out all
- registered digests in the dgst usage message instead of manually
- attempting to work them out.
- [Steve Henson]
-
- *) If no SSLv2 ciphers are used don't use an SSLv2 compatible client hello:
- this allows the use of compression and extensions. Change default cipher
- string to remove SSLv2 ciphersuites. This effectively avoids ancient SSLv2
- by default unless an application cipher string requests it.
- [Steve Henson]
-
- *) Alter match criteria in PKCS12_parse(). It used to try to use local
- key ids to find matching certificates and keys but some PKCS#12 files
- don't follow the (somewhat unwritten) rules and this strategy fails.
- Now just gather all certificates together and the first private key
- then look for the first certificate that matches the key.
- [Steve Henson]
-
- *) Support use of registered digest and cipher names for dgst and cipher
- commands instead of having to add each one as a special case. So now
- you can do:
-
- openssl sha256 foo
-
- as well as:
-
- openssl dgst -sha256 foo
-
- and this works for ENGINE based algorithms too.
-
- [Steve Henson]
-
- *) Update Gost ENGINE to support parameter files.
- [Victor B. Wagner <vitus@cryptocom.ru>]
-
- *) Support GeneralizedTime in ca utility.
- [Oliver Martin <oliver@volatilevoid.net>, Steve Henson]
-
- *) Enhance the hash format used for certificate directory links. The new
- form uses the canonical encoding (meaning equivalent names will work
- even if they aren't identical) and uses SHA1 instead of MD5. This form
- is incompatible with the older format and as a result c_rehash should
- be used to rebuild symbolic links.
- [Steve Henson]
-
- *) Make PKCS#8 the default write format for private keys, replacing the
- traditional format. This form is standardised, more secure and doesn't
- include an implicit MD5 dependency.
- [Steve Henson]
-
- *) Add a $gcc_devteam_warn option to Configure. The idea is that any code
- committed to OpenSSL should pass this lot as a minimum.
- [Steve Henson]
-
- *) Add session ticket override functionality for use by EAP-FAST.
- [Jouni Malinen <j@w1.fi>]
-
- *) Modify HMAC functions to return a value. Since these can be implemented
- in an ENGINE errors can occur.
- [Steve Henson]
-
- *) Type-checked OBJ_bsearch_ex.
- [Ben Laurie]
-
- *) Type-checked OBJ_bsearch. Also some constification necessitated
- by type-checking. Still to come: TXT_DB, bsearch(?),
- OBJ_bsearch_ex, qsort, CRYPTO_EX_DATA, ASN1_VALUE, ASN1_STRING,
- CONF_VALUE.
- [Ben Laurie]
-
- *) New function OPENSSL_gmtime_adj() to add a specific number of days and
- seconds to a tm structure directly, instead of going through OS
- specific date routines. This avoids any issues with OS routines such
- as the year 2038 bug. New *_adj() functions for ASN1 time structures
- and X509_time_adj_ex() to cover the extended range. The existing
- X509_time_adj() is still usable and will no longer have any date issues.
- [Steve Henson]
-
- *) Delta CRL support. New use deltas option which will attempt to locate
- and search any appropriate delta CRLs available.
-
- This work was sponsored by Google.
- [Steve Henson]
-
- *) Support for CRLs partitioned by reason code. Reorganise CRL processing
- code and add additional score elements. Validate alternate CRL paths
- as part of the CRL checking and indicate a new error "CRL path validation
- error" in this case. Applications wanting additional details can use
- the verify callback and check the new "parent" field. If this is not
- NULL CRL path validation is taking place. Existing applications wont
- see this because it requires extended CRL support which is off by
- default.
-
- This work was sponsored by Google.
- [Steve Henson]
-
- *) Support for freshest CRL extension.
-
- This work was sponsored by Google.
- [Steve Henson]
-
- *) Initial indirect CRL support. Currently only supported in the CRLs
- passed directly and not via lookup. Process certificate issuer
- CRL entry extension and lookup CRL entries by bother issuer name
- and serial number. Check and process CRL issuer entry in IDP extension.
-
- This work was sponsored by Google.
- [Steve Henson]
-
- *) Add support for distinct certificate and CRL paths. The CRL issuer
- certificate is validated separately in this case. Only enabled if
- an extended CRL support flag is set: this flag will enable additional
- CRL functionality in future.
-
- This work was sponsored by Google.
- [Steve Henson]
-
- *) Add support for policy mappings extension.
-
- This work was sponsored by Google.
- [Steve Henson]
-
- *) Fixes to pathlength constraint, self issued certificate handling,
- policy processing to align with RFC3280 and PKITS tests.
-
- This work was sponsored by Google.
- [Steve Henson]
-
- *) Support for name constraints certificate extension. DN, email, DNS
- and URI types are currently supported.
-
- This work was sponsored by Google.
- [Steve Henson]
-
- *) To cater for systems that provide a pointer-based thread ID rather
- than numeric, deprecate the current numeric thread ID mechanism and
- replace it with a structure and associated callback type. This
- mechanism allows a numeric "hash" to be extracted from a thread ID in
- either case, and on platforms where pointers are larger than 'long',
- mixing is done to help ensure the numeric 'hash' is usable even if it
- can't be guaranteed unique. The default mechanism is to use "&errno"
- as a pointer-based thread ID to distinguish between threads.
-
- Applications that want to provide their own thread IDs should now use
- CRYPTO_THREADID_set_callback() to register a callback that will call
- either CRYPTO_THREADID_set_numeric() or CRYPTO_THREADID_set_pointer().
-
- Note that ERR_remove_state() is now deprecated, because it is tied
- to the assumption that thread IDs are numeric. ERR_remove_state(0)
- to free the current thread's error state should be replaced by
- ERR_remove_thread_state(NULL).
-
- (This new approach replaces the functions CRYPTO_set_idptr_callback(),
- CRYPTO_get_idptr_callback(), and CRYPTO_thread_idptr() that existed in
- OpenSSL 0.9.9-dev between June 2006 and August 2008. Also, if an
- application was previously providing a numeric thread callback that
- was inappropriate for distinguishing threads, then uniqueness might
- have been obtained with &errno that happened immediately in the
- intermediate development versions of OpenSSL; this is no longer the
- case, the numeric thread callback will now override the automatic use
- of &errno.)
- [Geoff Thorpe, with help from Bodo Moeller]
-
- *) Initial support for different CRL issuing certificates. This covers a
- simple case where the self issued certificates in the chain exist and
- the real CRL issuer is higher in the existing chain.
-
- This work was sponsored by Google.
- [Steve Henson]
-
- *) Removed effectively defunct crypto/store from the build.
- [Ben Laurie]
-
- *) Revamp of STACK to provide stronger type-checking. Still to come:
- TXT_DB, bsearch(?), OBJ_bsearch, qsort, CRYPTO_EX_DATA, ASN1_VALUE,
- ASN1_STRING, CONF_VALUE.
- [Ben Laurie]
-
- *) Add a new SSL_MODE_RELEASE_BUFFERS mode flag to release unused buffer
- RAM on SSL connections. This option can save about 34k per idle SSL.
- [Nick Mathewson]
-
- *) Revamp of LHASH to provide stronger type-checking. Still to come:
- STACK, TXT_DB, bsearch, qsort.
- [Ben Laurie]
-
- *) Initial support for Cryptographic Message Syntax (aka CMS) based
- on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility,
- support for data, signedData, compressedData, digestedData and
- encryptedData, envelopedData types included. Scripts to check against
- RFC4134 examples draft and interop and consistency checks of many
- content types and variants.
- [Steve Henson]
-
- *) Add options to enc utility to support use of zlib compression BIO.
- [Steve Henson]
-
- *) Extend mk1mf to support importing of options and assembly language
- files from Configure script, currently only included in VC-WIN32.
- The assembly language rules can now optionally generate the source
- files from the associated perl scripts.
- [Steve Henson]
-
- *) Implement remaining functionality needed to support GOST ciphersuites.
- Interop testing has been performed using CryptoPro implementations.
- [Victor B. Wagner <vitus@cryptocom.ru>]
-
- *) s390x assembler pack.
- [Andy Polyakov]
-
- *) ARMv4 assembler pack. ARMv4 refers to v4 and later ISA, not CPU
- "family."
- [Andy Polyakov]
-
- *) Implement Opaque PRF Input TLS extension as specified in
- draft-rescorla-tls-opaque-prf-input-00.txt. Since this is not an
- official specification yet and no extension type assignment by
- IANA exists, this extension (for now) will have to be explicitly
- enabled when building OpenSSL by providing the extension number
- to use. For example, specify an option
-
- -DTLSEXT_TYPE_opaque_prf_input=0x9527
-
- to the "config" or "Configure" script to enable the extension,
- assuming extension number 0x9527 (which is a completely arbitrary
- and unofficial assignment based on the MD5 hash of the Internet
- Draft). Note that by doing so, you potentially lose
- interoperability with other TLS implementations since these might
- be using the same extension number for other purposes.
-
- SSL_set_tlsext_opaque_prf_input(ssl, src, len) is used to set the
- opaque PRF input value to use in the handshake. This will create
- an interal copy of the length-'len' string at 'src', and will
- return non-zero for success.
-
- To get more control and flexibility, provide a callback function
- by using
-
- SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb)
- SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg)
-
- where
-
- int (*cb)(SSL *, void *peerinput, size_t len, void *arg);
- void *arg;
-
- Callback function 'cb' will be called in handshakes, and is
- expected to use SSL_set_tlsext_opaque_prf_input() as appropriate.
- Argument 'arg' is for application purposes (the value as given to
- SSL_CTX_set_tlsext_opaque_prf_input_callback_arg() will directly
- be provided to the callback function). The callback function
- has to return non-zero to report success: usually 1 to use opaque
- PRF input just if possible, or 2 to enforce use of the opaque PRF
- input. In the latter case, the library will abort the handshake
- if opaque PRF input is not successfully negotiated.
-
- Arguments 'peerinput' and 'len' given to the callback function
- will always be NULL and 0 in the case of a client. A server will
- see the client's opaque PRF input through these variables if
- available (NULL and 0 otherwise). Note that if the server
- provides an opaque PRF input, the length must be the same as the
- length of the client's opaque PRF input.
-
- Note that the callback function will only be called when creating
- a new session (session resumption can resume whatever was
- previously negotiated), and will not be called in SSL 2.0
- handshakes; thus, SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) or
- SSL_set_options(ssl, SSL_OP_NO_SSLv2) is especially recommended
- for applications that need to enforce opaque PRF input.
-
- [Bodo Moeller]
-
- *) Update ssl code to support digests other than SHA1+MD5 for handshake
- MAC.
-
- [Victor B. Wagner <vitus@cryptocom.ru>]
-
- *) Add RFC4507 support to OpenSSL. This includes the corrections in
- RFC4507bis. The encrypted ticket format is an encrypted encoded
- SSL_SESSION structure, that way new session features are automatically
- supported.
-
- If a client application caches session in an SSL_SESSION structure
- support is transparent because tickets are now stored in the encoded
- SSL_SESSION.
-
- The SSL_CTX structure automatically generates keys for ticket
- protection in servers so again support should be possible
- with no application modification.
-
- If a client or server wishes to disable RFC4507 support then the option
- SSL_OP_NO_TICKET can be set.
-
- Add a TLS extension debugging callback to allow the contents of any client
- or server extensions to be examined.
-
- This work was sponsored by Google.
- [Steve Henson]
-
- *) Final changes to avoid use of pointer pointer casts in OpenSSL.
- OpenSSL should now compile cleanly on gcc 4.2
- [Peter Hartley <pdh@utter.chaos.org.uk>, Steve Henson]
-
- *) Update SSL library to use new EVP_PKEY MAC API. Include generic MAC
- support including streaming MAC support: this is required for GOST
- ciphersuite support.
- [Victor B. Wagner <vitus@cryptocom.ru>, Steve Henson]
-
- *) Add option -stream to use PKCS#7 streaming in smime utility. New
- function i2d_PKCS7_bio_stream() and PEM_write_PKCS7_bio_stream()
- to output in BER and PEM format.
- [Steve Henson]
-
- *) Experimental support for use of HMAC via EVP_PKEY interface. This
- allows HMAC to be handled via the EVP_DigestSign*() interface. The
- EVP_PKEY "key" in this case is the HMAC key, potentially allowing
- ENGINE support for HMAC keys which are unextractable. New -mac and
- -macopt options to dgst utility.
- [Steve Henson]
-
- *) New option -sigopt to dgst utility. Update dgst to use
- EVP_Digest{Sign,Verify}*. These two changes make it possible to use
- alternative signing paramaters such as X9.31 or PSS in the dgst
- utility.
- [Steve Henson]
-
- *) Change ssl_cipher_apply_rule(), the internal function that does
- the work each time a ciphersuite string requests enabling
- ("foo+bar"), moving ("+foo+bar"), disabling ("-foo+bar", or
- removing ("!foo+bar") a class of ciphersuites: Now it maintains
- the order of disabled ciphersuites such that those ciphersuites
- that most recently went from enabled to disabled not only stay
- in order with respect to each other, but also have higher priority
- than other disabled ciphersuites the next time ciphersuites are
- enabled again.
-
- This means that you can now say, e.g., "PSK:-PSK:HIGH" to enable
- the same ciphersuites as with "HIGH" alone, but in a specific
- order where the PSK ciphersuites come first (since they are the
- most recently disabled ciphersuites when "HIGH" is parsed).
-
- Also, change ssl_create_cipher_list() (using this new
- funcionality) such that between otherwise identical
- cihpersuites, ephemeral ECDH is preferred over ephemeral DH in
- the default order.
- [Bodo Moeller]
-
- *) Change ssl_create_cipher_list() so that it automatically
- arranges the ciphersuites in reasonable order before starting
- to process the rule string. Thus, the definition for "DEFAULT"
- (SSL_DEFAULT_CIPHER_LIST) now is just "ALL:!aNULL:!eNULL", but
- remains equivalent to "AES:ALL:!aNULL:!eNULL:+aECDH:+kRSA:+RC4:@STRENGTH".
- This makes it much easier to arrive at a reasonable default order
- in applications for which anonymous ciphers are OK (meaning
- that you can't actually use DEFAULT).
- [Bodo Moeller; suggested by Victor Duchovni]
-
- *) Split the SSL/TLS algorithm mask (as used for ciphersuite string
- processing) into multiple integers instead of setting
- "SSL_MKEY_MASK" bits, "SSL_AUTH_MASK" bits, "SSL_ENC_MASK",
- "SSL_MAC_MASK", and "SSL_SSL_MASK" bits all in a single integer.
- (These masks as well as the individual bit definitions are hidden
- away into the non-exported interface ssl/ssl_locl.h, so this
- change to the definition of the SSL_CIPHER structure shouldn't
- affect applications.) This give us more bits for each of these
- categories, so there is no longer a need to coagulate AES128 and
- AES256 into a single algorithm bit, and to coagulate Camellia128
- and Camellia256 into a single algorithm bit, which has led to all
- kinds of kludges.
-
- Thus, among other things, the kludge introduced in 0.9.7m and
- 0.9.8e for masking out AES256 independently of AES128 or masking
- out Camellia256 independently of AES256 is not needed here in 0.9.9.
-
- With the change, we also introduce new ciphersuite aliases that
- so far were missing: "AES128", "AES256", "CAMELLIA128", and
- "CAMELLIA256".
- [Bodo Moeller]
-
- *) Add support for dsa-with-SHA224 and dsa-with-SHA256.
- Use the leftmost N bytes of the signature input if the input is
- larger than the prime q (with N being the size in bytes of q).
- [Nils Larsch]
-
- *) Very *very* experimental PKCS#7 streaming encoder support. Nothing uses
- it yet and it is largely untested.
- [Steve Henson]
-
- *) Add support for the ecdsa-with-SHA224/256/384/512 signature types.
- [Nils Larsch]
-
- *) Initial incomplete changes to avoid need for function casts in OpenSSL
- some compilers (gcc 4.2 and later) reject their use. Safestack is
- reimplemented. Update ASN1 to avoid use of legacy functions.
- [Steve Henson]
-
- *) Win32/64 targets are linked with Winsock2.
- [Andy Polyakov]
-
- *) Add an X509_CRL_METHOD structure to allow CRL processing to be redirected
- to external functions. This can be used to increase CRL handling
- efficiency especially when CRLs are very large by (for example) storing
- the CRL revoked certificates in a database.
- [Steve Henson]
-
- *) Overhaul of by_dir code. Add support for dynamic loading of CRLs so
- new CRLs added to a directory can be used. New command line option
- -verify_return_error to s_client and s_server. This causes real errors
- to be returned by the verify callback instead of carrying on no matter
- what. This reflects the way a "real world" verify callback would behave.
- [Steve Henson]
-
- *) GOST engine, supporting several GOST algorithms and public key formats.
- Kindly donated by Cryptocom.
- [Cryptocom]
-
- *) Partial support for Issuing Distribution Point CRL extension. CRLs
- partitioned by DP are handled but no indirect CRL or reason partitioning
- (yet). Complete overhaul of CRL handling: now the most suitable CRL is
- selected via a scoring technique which handles IDP and AKID in CRLs.
- [Steve Henson]
-
- *) New X509_STORE_CTX callbacks lookup_crls() and lookup_certs() which
- will ultimately be used for all verify operations: this will remove the
- X509_STORE dependency on certificate verification and allow alternative
- lookup methods. X509_STORE based implementations of these two callbacks.
- [Steve Henson]
-
- *) Allow multiple CRLs to exist in an X509_STORE with matching issuer names.
- Modify get_crl() to find a valid (unexpired) CRL if possible.
- [Steve Henson]
-
- *) New function X509_CRL_match() to check if two CRLs are identical. Normally
- this would be called X509_CRL_cmp() but that name is already used by
- a function that just compares CRL issuer names. Cache several CRL
- extensions in X509_CRL structure and cache CRLDP in X509.
- [Steve Henson]
-
- *) Store a "canonical" representation of X509_NAME structure (ASN1 Name)
- this maps equivalent X509_NAME structures into a consistent structure.
- Name comparison can then be performed rapidly using memcmp().
- [Steve Henson]
-
- *) Non-blocking OCSP request processing. Add -timeout option to ocsp
- utility.
- [Steve Henson]
-
- *) Allow digests to supply their own micalg string for S/MIME type using
- the ctrl EVP_MD_CTRL_MICALG.
- [Steve Henson]
-
- *) During PKCS7 signing pass the PKCS7 SignerInfo structure to the
- EVP_PKEY_METHOD before and after signing via the EVP_PKEY_CTRL_PKCS7_SIGN
- ctrl. It can then customise the structure before and/or after signing
- if necessary.
- [Steve Henson]
-
- *) New function OBJ_add_sigid() to allow application defined signature OIDs
- to be added to OpenSSLs internal tables. New function OBJ_sigid_free()
- to free up any added signature OIDs.
- [Steve Henson]
-
- *) New functions EVP_CIPHER_do_all(), EVP_CIPHER_do_all_sorted(),
- EVP_MD_do_all() and EVP_MD_do_all_sorted() to enumerate internal
- digest and cipher tables. New options added to openssl utility:
- list-message-digest-algorithms and list-cipher-algorithms.
- [Steve Henson]
-
- *) Change the array representation of binary polynomials: the list
- of degrees of non-zero coefficients is now terminated with -1.
- Previously it was terminated with 0, which was also part of the
- value; thus, the array representation was not applicable to
- polynomials where t^0 has coefficient zero. This change makes
- the array representation useful in a more general context.
- [Douglas Stebila]
-
- *) Various modifications and fixes to SSL/TLS cipher string
- handling. For ECC, the code now distinguishes between fixed ECDH
- with RSA certificates on the one hand and with ECDSA certificates
- on the other hand, since these are separate ciphersuites. The
- unused code for Fortezza ciphersuites has been removed.
-
- For consistency with EDH, ephemeral ECDH is now called "EECDH"
- (not "ECDHE"). For consistency with the code for DH
- certificates, use of ECDH certificates is now considered ECDH
- authentication, not RSA or ECDSA authentication (the latter is
- merely the CA's signing algorithm and not actively used in the
- protocol).
-
- The temporary ciphersuite alias "ECCdraft" is no longer
- available, and ECC ciphersuites are no longer excluded from "ALL"
- and "DEFAULT". The following aliases now exist for RFC 4492
- ciphersuites, most of these by analogy with the DH case:
-
- kECDHr - ECDH cert, signed with RSA
- kECDHe - ECDH cert, signed with ECDSA
- kECDH - ECDH cert (signed with either RSA or ECDSA)
- kEECDH - ephemeral ECDH
- ECDH - ECDH cert or ephemeral ECDH
-
- aECDH - ECDH cert
- aECDSA - ECDSA cert
- ECDSA - ECDSA cert
-
- AECDH - anonymous ECDH
- EECDH - non-anonymous ephemeral ECDH (equivalent to "kEECDH:-AECDH")
-
- [Bodo Moeller]
-
- *) Add additional S/MIME capabilities for AES and GOST ciphers if supported.
- Use correct micalg parameters depending on digest(s) in signed message.
- [Steve Henson]
-
- *) Add engine support for EVP_PKEY_ASN1_METHOD. Add functions to process
- an ENGINE asn1 method. Support ENGINE lookups in the ASN1 code.
- [Steve Henson]
-
- *) Initial engine support for EVP_PKEY_METHOD. New functions to permit
- an engine to register a method. Add ENGINE lookups for methods and
- functional reference processing.
- [Steve Henson]
-
- *) New functions EVP_Digest{Sign,Verify)*. These are enchance versions of
- EVP_{Sign,Verify}* which allow an application to customise the signature
- process.
- [Steve Henson]
-
- *) New -resign option to smime utility. This adds one or more signers
- to an existing PKCS#7 signedData structure. Also -md option to use an
- alternative message digest algorithm for signing.
- [Steve Henson]
-
- *) Tidy up PKCS#7 routines and add new functions to make it easier to
- create PKCS7 structures containing multiple signers. Update smime
- application to support multiple signers.
- [Steve Henson]
-
- *) New -macalg option to pkcs12 utility to allow setting of an alternative
- digest MAC.
- [Steve Henson]
-
- *) Initial support for PKCS#5 v2.0 PRFs other than default SHA1 HMAC.
- Reorganize PBE internals to lookup from a static table using NIDs,
- add support for HMAC PBE OID translation. Add a EVP_CIPHER ctrl:
- EVP_CTRL_PBE_PRF_NID this allows a cipher to specify an alternative
- PRF which will be automatically used with PBES2.
- [Steve Henson]
-
- *) Replace the algorithm specific calls to generate keys in "req" with the
- new API.
- [Steve Henson]
-
- *) Update PKCS#7 enveloped data routines to use new API. This is now
- supported by any public key method supporting the encrypt operation. A
- ctrl is added to allow the public key algorithm to examine or modify
- the PKCS#7 RecipientInfo structure if it needs to: for RSA this is
- a no op.
- [Steve Henson]
-
- *) Add a ctrl to asn1 method to allow a public key algorithm to express
- a default digest type to use. In most cases this will be SHA1 but some
- algorithms (such as GOST) need to specify an alternative digest. The
- return value indicates how strong the prefernce is 1 means optional and
- 2 is mandatory (that is it is the only supported type). Modify
- ASN1_item_sign() to accept a NULL digest argument to indicate it should
- use the default md. Update openssl utilities to use the default digest
- type for signing if it is not explicitly indicated.
- [Steve Henson]
-
- *) Use OID cross reference table in ASN1_sign() and ASN1_verify(). New
- EVP_MD flag EVP_MD_FLAG_PKEY_METHOD_SIGNATURE. This uses the relevant
- signing method from the key type. This effectively removes the link
- between digests and public key types.
- [Steve Henson]
-
- *) Add an OID cross reference table and utility functions. Its purpose is to
- translate between signature OIDs such as SHA1WithrsaEncryption and SHA1,
- rsaEncryption. This will allow some of the algorithm specific hackery
- needed to use the correct OID to be removed.
- [Steve Henson]
-
- *) Remove algorithm specific dependencies when setting PKCS7_SIGNER_INFO
- structures for PKCS7_sign(). They are now set up by the relevant public
- key ASN1 method.
- [Steve Henson]
-
- *) Add provisional EC pkey method with support for ECDSA and ECDH.
- [Steve Henson]
-
- *) Add support for key derivation (agreement) in the API, DH method and
- pkeyutl.
- [Steve Henson]
-
- *) Add DSA pkey method and DH pkey methods, extend DH ASN1 method to support
- public and private key formats. As a side effect these add additional
- command line functionality not previously available: DSA signatures can be
- generated and verified using pkeyutl and DH key support and generation in
- pkey, genpkey.
- [Steve Henson]
-
- *) BeOS support.
- [Oliver Tappe <zooey@hirschkaefer.de>]
-
- *) New make target "install_html_docs" installs HTML renditions of the
- manual pages.
- [Oliver Tappe <zooey@hirschkaefer.de>]
-
- *) New utility "genpkey" this is analagous to "genrsa" etc except it can
- generate keys for any algorithm. Extend and update EVP_PKEY_METHOD to
- support key and parameter generation and add initial key generation
- functionality for RSA.
- [Steve Henson]
-
- *) Add functions for main EVP_PKEY_method operations. The undocumented
- functions EVP_PKEY_{encrypt,decrypt} have been renamed to
- EVP_PKEY_{encrypt,decrypt}_old.
- [Steve Henson]
-
- *) Initial definitions for EVP_PKEY_METHOD. This will be a high level public
- key API, doesn't do much yet.
- [Steve Henson]
-
- *) New function EVP_PKEY_asn1_get0_info() to retrieve information about
- public key algorithms. New option to openssl utility:
- "list-public-key-algorithms" to print out info.
- [Steve Henson]
-
- *) Implement the Supported Elliptic Curves Extension for
- ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
- [Douglas Stebila]
-
- *) Don't free up OIDs in OBJ_cleanup() if they are in use by EVP_MD or
- EVP_CIPHER structures to avoid later problems in EVP_cleanup().
- [Steve Henson]
-
- *) New utilities pkey and pkeyparam. These are similar to algorithm specific
- utilities such as rsa, dsa, dsaparam etc except they process any key
- type.
- [Steve Henson]
-
- *) Transfer public key printing routines to EVP_PKEY_ASN1_METHOD. New
- functions EVP_PKEY_print_public(), EVP_PKEY_print_private(),
- EVP_PKEY_print_param() to print public key data from an EVP_PKEY
- structure.
- [Steve Henson]
-
- *) Initial support for pluggable public key ASN1.
- De-spaghettify the public key ASN1 handling. Move public and private
- key ASN1 handling to a new EVP_PKEY_ASN1_METHOD structure. Relocate
- algorithm specific handling to a single module within the relevant
- algorithm directory. Add functions to allow (near) opaque processing
- of public and private key structures.
- [Steve Henson]
-
- *) Implement the Supported Point Formats Extension for
- ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
- [Douglas Stebila]
-
- *) Add initial support for RFC 4279 PSK TLS ciphersuites. Add members
- for the psk identity [hint] and the psk callback functions to the
- SSL_SESSION, SSL and SSL_CTX structure.
-
- New ciphersuites:
- PSK-RC4-SHA, PSK-3DES-EDE-CBC-SHA, PSK-AES128-CBC-SHA,
- PSK-AES256-CBC-SHA
-
- New functions:
- SSL_CTX_use_psk_identity_hint
- SSL_get_psk_identity_hint
- SSL_get_psk_identity
- SSL_use_psk_identity_hint
-
- [Mika Kousa and Pasi Eronen of Nokia Corporation]
-
- *) Add RFC 3161 compliant time stamp request creation, response generation
- and response verification functionality.
- [Zoltán Glózik <zglozik@opentsa.org>, The OpenTSA Project]
-
- *) Add initial support for TLS extensions, specifically for the server_name
- extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now
- have new members for a host name. The SSL data structure has an
- additional member SSL_CTX *initial_ctx so that new sessions can be
- stored in that context to allow for session resumption, even after the
- SSL has been switched to a new SSL_CTX in reaction to a client's
- server_name extension.
-
- New functions (subject to change):
-
- SSL_get_servername()
- SSL_get_servername_type()
- SSL_set_SSL_CTX()
-
- New CTRL codes and macros (subject to change):
-
- SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
- - SSL_CTX_set_tlsext_servername_callback()
- SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
- - SSL_CTX_set_tlsext_servername_arg()
- SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name()
-
- openssl s_client has a new '-servername ...' option.
-
- openssl s_server has new options '-servername_host ...', '-cert2 ...',
- '-key2 ...', '-servername_fatal' (subject to change). This allows
- testing the HostName extension for a specific single host name ('-cert'
- and '-key' remain fallbacks for handshakes without HostName
- negotiation). If the unrecogninzed_name alert has to be sent, this by
- default is a warning; it becomes fatal with the '-servername_fatal'
- option.
-
- [Peter Sylvester, Remy Allais, Christophe Renou]
-
- *) Whirlpool hash implementation is added.
- [Andy Polyakov]
-
- *) BIGNUM code on 64-bit SPARCv9 targets is switched from bn(64,64) to
- bn(64,32). Because of instruction set limitations it doesn't have
- any negative impact on performance. This was done mostly in order
- to make it possible to share assembler modules, such as bn_mul_mont
- implementations, between 32- and 64-bit builds without hassle.
- [Andy Polyakov]
-
- *) Move code previously exiled into file crypto/ec/ec2_smpt.c
- to ec2_smpl.c, and no longer require the OPENSSL_EC_BIN_PT_COMP
- macro.
- [Bodo Moeller]
-
- *) New candidate for BIGNUM assembler implementation, bn_mul_mont,
- dedicated Montgomery multiplication procedure, is introduced.
- BN_MONT_CTX is modified to allow bn_mul_mont to reach for higher
- "64-bit" performance on certain 32-bit targets.
- [Andy Polyakov]
-
- *) New option SSL_OP_NO_COMP to disable use of compression selectively
- in SSL structures. New SSL ctrl to set maximum send fragment size.
- Save memory by seeting the I/O buffer sizes dynamically instead of
- using the maximum available value.
- [Steve Henson]
-
- *) New option -V for 'openssl ciphers'. This prints the ciphersuite code
- in addition to the text details.
- [Bodo Moeller]
-
- *) Very, very preliminary EXPERIMENTAL support for printing of general
- ASN1 structures. This currently produces rather ugly output and doesn't
- handle several customised structures at all.
- [Steve Henson]
-
- *) Integrated support for PVK file format and some related formats such
- as MS PUBLICKEYBLOB and PRIVATEKEYBLOB. Command line switches to support
- these in the 'rsa' and 'dsa' utilities.
- [Steve Henson]
-
- *) Support for PKCS#1 RSAPublicKey format on rsa utility command line.
- [Steve Henson]
-
- *) Remove the ancient ASN1_METHOD code. This was only ever used in one
- place for the (very old) "NETSCAPE" format certificates which are now
- handled using new ASN1 code equivalents.
- [Steve Henson]
-
- *) Let the TLSv1_method() etc. functions return a 'const' SSL_METHOD
- pointer and make the SSL_METHOD parameter in SSL_CTX_new,
- SSL_CTX_set_ssl_version and SSL_set_ssl_method 'const'.
- [Nils Larsch]
-
- *) Modify CRL distribution points extension code to print out previously
- unsupported fields. Enhance extension setting code to allow setting of
- all fields.
- [Steve Henson]
-
- *) Add print and set support for Issuing Distribution Point CRL extension.
- [Steve Henson]
-
- *) Change 'Configure' script to enable Camellia by default.
- [NTT]
-
- Changes between 0.9.8q and 0.9.8r [8 Feb 2011]
-
- *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014
- [Neel Mehta, Adam Langley, Bodo Moeller (Google)]
-
- *) Fix bug in string printing code: if *any* escaping is enabled we must
- escape the escape character (backslash) or the resulting string is
- ambiguous.
- [Steve Henson]
-
- Changes between 0.9.8p and 0.9.8q [2 Dec 2010]
-
- *) Disable code workaround for ancient and obsolete Netscape browsers
- and servers: an attacker can use it in a ciphersuite downgrade attack.
- Thanks to Martin Rex for discovering this bug. CVE-2010-4180
- [Steve Henson]
-
- *) Fixed J-PAKE implementation error, originally discovered by
- Sebastien Martini, further info and confirmation from Stefan
- Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252
- [Ben Laurie]
-
- Changes between 0.9.8o and 0.9.8p [16 Nov 2010]
-
- *) Fix extension code to avoid race conditions which can result in a buffer
- overrun vulnerability: resumed sessions must not be modified as they can
- be shared by multiple threads. CVE-2010-3864
- [Steve Henson]
-
- *) Fix for double free bug in ssl/s3_clnt.c CVE-2010-2939
- [Steve Henson]
-
- *) Don't reencode certificate when calculating signature: cache and use
- the original encoding instead. This makes signature verification of
- some broken encodings work correctly.
- [Steve Henson]
-
- *) ec2_GF2m_simple_mul bugfix: compute correct result if the output EC_POINT
- is also one of the inputs.
- [Emilia Käsper <emilia.kasper@esat.kuleuven.be> (Google)]
-
- *) Don't repeatedly append PBE algorithms to table if they already exist.
- Sort table on each new add. This effectively makes the table read only
- after all algorithms are added and subsequent calls to PKCS12_pbe_add
- etc are non-op.
- [Steve Henson]
-
- Changes between 0.9.8n and 0.9.8o [01 Jun 2010]
-
- [NB: OpenSSL 0.9.8o and later 0.9.8 patch levels were released after
- OpenSSL 1.0.0.]
-
- *) Correct a typo in the CMS ASN1 module which can result in invalid memory
- access or freeing data twice (CVE-2010-0742)
- [Steve Henson, Ronald Moesbergen <intercommit@gmail.com>]
-
- *) Add SHA2 algorithms to SSL_library_init(). SHA2 is becoming far more
- common in certificates and some applications which only call
- SSL_library_init and not OpenSSL_add_all_algorithms() will fail.
- [Steve Henson]
-
- *) VMS fixes:
- Reduce copying into .apps and .test in makevms.com
- Don't try to use blank CA certificate in CA.com
- Allow use of C files from original directories in maketests.com
- [Steven M. Schweda" <sms@antinode.info>]
-
- Changes between 0.9.8m and 0.9.8n [24 Mar 2010]
-
- *) When rejecting SSL/TLS records due to an incorrect version number, never
- update s->server with a new major version number. As of
- - OpenSSL 0.9.8m if 'short' is a 16-bit type,
- - OpenSSL 0.9.8f if 'short' is longer than 16 bits,
- the previous behavior could result in a read attempt at NULL when
- receiving specific incorrect SSL/TLS records once record payload
- protection is active. (CVE-2010-0740)
- [Bodo Moeller, Adam Langley <agl@chromium.org>]
-
- *) Fix for CVE-2010-0433 where some kerberos enabled versions of OpenSSL
- could be crashed if the relevant tables were not present (e.g. chrooted).
- [Tomas Hoger <thoger@redhat.com>]
-
- Changes between 0.9.8l and 0.9.8m [25 Feb 2010]
-
- *) Always check bn_wexpend() return values for failure. (CVE-2009-3245)
- [Martin Olsson, Neel Mehta]
-
- *) Fix X509_STORE locking: Every 'objs' access requires a lock (to
- accommodate for stack sorting, always a write lock!).
- [Bodo Moeller]
-
- *) On some versions of WIN32 Heap32Next is very slow. This can cause
- excessive delays in the RAND_poll(): over a minute. As a workaround
- include a time check in the inner Heap32Next loop too.
- [Steve Henson]
-
- *) The code that handled flushing of data in SSL/TLS originally used the
- BIO_CTRL_INFO ctrl to see if any data was pending first. This caused
- the problem outlined in PR#1949. The fix suggested there however can
- trigger problems with buggy BIO_CTRL_WPENDING (e.g. some versions
- of Apache). So instead simplify the code to flush unconditionally.
- This should be fine since flushing with no data to flush is a no op.
- [Steve Henson]
-
- *) Handle TLS versions 2.0 and later properly and correctly use the
- highest version of TLS/SSL supported. Although TLS >= 2.0 is some way
- off ancient servers have a habit of sticking around for a while...
- [Steve Henson]
-
- *) Modify compression code so it frees up structures without using the
- ex_data callbacks. This works around a problem where some applications
- call CRYPTO_cleanup_all_ex_data() before application exit (e.g. when
- restarting) then use compression (e.g. SSL with compression) later.
- This results in significant per-connection memory leaks and
- has caused some security issues including CVE-2008-1678 and
- CVE-2009-4355.
- [Steve Henson]
-
- *) Constify crypto/cast (i.e., <openssl/cast.h>): a CAST_KEY doesn't
- change when encrypting or decrypting.
- [Bodo Moeller]
-
- *) Add option SSL_OP_LEGACY_SERVER_CONNECT which will allow clients to
- connect and renegotiate with servers which do not support RI.
- Until RI is more widely deployed this option is enabled by default.
- [Steve Henson]
-
- *) Add "missing" ssl ctrls to clear options and mode.
- [Steve Henson]
-
- *) If client attempts to renegotiate and doesn't support RI respond with
- a no_renegotiation alert as required by RFC5746. Some renegotiating
- TLS clients will continue a connection gracefully when they receive
- the alert. Unfortunately OpenSSL mishandled this alert and would hang
- waiting for a server hello which it will never receive. Now we treat a
- received no_renegotiation alert as a fatal error. This is because
- applications requesting a renegotiation might well expect it to succeed
- and would have no code in place to handle the server denying it so the
- only safe thing to do is to terminate the connection.
- [Steve Henson]
-
- *) Add ctrl macro SSL_get_secure_renegotiation_support() which returns 1 if
- peer supports secure renegotiation and 0 otherwise. Print out peer
- renegotiation support in s_client/s_server.
- [Steve Henson]
-
- *) Replace the highly broken and deprecated SPKAC certification method with
- the updated NID creation version. This should correctly handle UTF8.
- [Steve Henson]
-
- *) Implement RFC5746. Re-enable renegotiation but require the extension
- as needed. Unfortunately, SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
- turns out to be a bad idea. It has been replaced by
- SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with
- SSL_CTX_set_options(). This is really not recommended unless you
- know what you are doing.
- [Eric Rescorla <ekr@networkresonance.com>, Ben Laurie, Steve Henson]
-
- *) Fixes to stateless session resumption handling. Use initial_ctx when
- issuing and attempting to decrypt tickets in case it has changed during
- servername handling. Use a non-zero length session ID when attempting
- stateless session resumption: this makes it possible to determine if
- a resumption has occurred immediately after receiving server hello
- (several places in OpenSSL subtly assume this) instead of later in
- the handshake.
- [Steve Henson]
-
- *) The functions ENGINE_ctrl(), OPENSSL_isservice(),
- CMS_get1_RecipientRequest() and RAND_bytes() can return <=0 on error
- fixes for a few places where the return code is not checked
- correctly.
- [Julia Lawall <julia@diku.dk>]
-
- *) Add --strict-warnings option to Configure script to include devteam
- warnings in other configurations.
- [Steve Henson]
-
- *) Add support for --libdir option and LIBDIR variable in makefiles. This
- makes it possible to install openssl libraries in locations which
- have names other than "lib", for example "/usr/lib64" which some
- systems need.
- [Steve Henson, based on patch from Jeremy Utley]
-
- *) Don't allow the use of leading 0x80 in OIDs. This is a violation of
- X690 8.9.12 and can produce some misleading textual output of OIDs.
- [Steve Henson, reported by Dan Kaminsky]
-
- *) Delete MD2 from algorithm tables. This follows the recommendation in
- several standards that it is not used in new applications due to
- several cryptographic weaknesses. For binary compatibility reasons
- the MD2 API is still compiled in by default.
- [Steve Henson]
-
- *) Add compression id to {d2i,i2d}_SSL_SESSION so it is correctly saved
- and restored.
- [Steve Henson]
-
- *) Rename uni2asc and asc2uni functions to OPENSSL_uni2asc and
- OPENSSL_asc2uni conditionally on Netware platforms to avoid a name
- clash.
- [Guenter <lists@gknw.net>]
-
- *) Fix the server certificate chain building code to use X509_verify_cert(),
- it used to have an ad-hoc builder which was unable to cope with anything
- other than a simple chain.
- [David Woodhouse <dwmw2@infradead.org>, Steve Henson]
-
- *) Don't check self signed certificate signatures in X509_verify_cert()
- by default (a flag can override this): it just wastes time without
- adding any security. As a useful side effect self signed root CAs
- with non-FIPS digests are now usable in FIPS mode.
- [Steve Henson]
-
- *) In dtls1_process_out_of_seq_message() the check if the current message
- is already buffered was missing. For every new message was memory
- allocated, allowing an attacker to perform an denial of service attack
- with sending out of seq handshake messages until there is no memory
- left. Additionally every future messege was buffered, even if the
- sequence number made no sense and would be part of another handshake.
- So only messages with sequence numbers less than 10 in advance will be
- buffered. (CVE-2009-1378)
- [Robin Seggelmann, discovered by Daniel Mentz]
-
- *) Records are buffered if they arrive with a future epoch to be
- processed after finishing the corresponding handshake. There is
- currently no limitation to this buffer allowing an attacker to perform
- a DOS attack with sending records with future epochs until there is no
- memory left. This patch adds the pqueue_size() function to detemine
- the size of a buffer and limits the record buffer to 100 entries.
- (CVE-2009-1377)
- [Robin Seggelmann, discovered by Daniel Mentz]
-
- *) Keep a copy of frag->msg_header.frag_len so it can be used after the
- parent structure is freed. (CVE-2009-1379)
- [Daniel Mentz]
-
- *) Handle non-blocking I/O properly in SSL_shutdown() call.
- [Darryl Miles <darryl-mailinglists@netbauds.net>]
-
- *) Add 2.5.4.* OIDs
- [Ilya O. <vrghost@gmail.com>]
-
- Changes between 0.9.8k and 0.9.8l [5 Nov 2009]
-
- *) Disable renegotiation completely - this fixes a severe security
- problem (CVE-2009-3555) at the cost of breaking all
- renegotiation. Renegotiation can be re-enabled by setting
- SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION in s3->flags at
- run-time. This is really not recommended unless you know what
- you're doing.
- [Ben Laurie]
-
- Changes between 0.9.8j and 0.9.8k [25 Mar 2009]
-
- *) Don't set val to NULL when freeing up structures, it is freed up by
- underlying code. If sizeof(void *) > sizeof(long) this can result in
- zeroing past the valid field. (CVE-2009-0789)
- [Paolo Ganci <Paolo.Ganci@AdNovum.CH>]
-
- *) Fix bug where return value of CMS_SignerInfo_verify_content() was not
- checked correctly. This would allow some invalid signed attributes to
- appear to verify correctly. (CVE-2009-0591)
- [Ivan Nestlerode <inestlerode@us.ibm.com>]
-
- *) Reject UniversalString and BMPString types with invalid lengths. This
- prevents a crash in ASN1_STRING_print_ex() which assumes the strings have
- a legal length. (CVE-2009-0590)
- [Steve Henson]
-
- *) Set S/MIME signing as the default purpose rather than setting it
- unconditionally. This allows applications to override it at the store
- level.
- [Steve Henson]
-
- *) Permit restricted recursion of ASN1 strings. This is needed in practice
- to handle some structures.
- [Steve Henson]
-
- *) Improve efficiency of mem_gets: don't search whole buffer each time
- for a '\n'
- [Jeremy Shapiro <jnshapir@us.ibm.com>]
-
- *) New -hex option for openssl rand.
- [Matthieu Herrb]
-
- *) Print out UTF8String and NumericString when parsing ASN1.
- [Steve Henson]
-
- *) Support NumericString type for name components.
- [Steve Henson]
-
- *) Allow CC in the environment to override the automatically chosen
- compiler. Note that nothing is done to ensure flags work with the
- chosen compiler.
- [Ben Laurie]
-
- Changes between 0.9.8i and 0.9.8j [07 Jan 2009]
-
- *) Properly check EVP_VerifyFinal() and similar return values
- (CVE-2008-5077).
- [Ben Laurie, Bodo Moeller, Google Security Team]
-
- *) Enable TLS extensions by default.
- [Ben Laurie]
-
- *) Allow the CHIL engine to be loaded, whether the application is
- multithreaded or not. (This does not release the developer from the
- obligation to set up the dynamic locking callbacks.)
- [Sander Temme <sander@temme.net>]
-
- *) Use correct exit code if there is an error in dgst command.
- [Steve Henson; problem pointed out by Roland Dirlewanger]
-
- *) Tweak Configure so that you need to say "experimental-jpake" to enable
- JPAKE, and need to use -DOPENSSL_EXPERIMENTAL_JPAKE in applications.
- [Bodo Moeller]
-
- *) Add experimental JPAKE support, including demo authentication in
- s_client and s_server.
- [Ben Laurie]
-
- *) Set the comparison function in v3_addr_canonize().
- [Rob Austein <sra@hactrn.net>]
-
- *) Add support for XMPP STARTTLS in s_client.
- [Philip Paeps <philip@freebsd.org>]
-
- *) Change the server-side SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG behavior
- to ensure that even with this option, only ciphersuites in the
- server's preference list will be accepted. (Note that the option
- applies only when resuming a session, so the earlier behavior was
- just about the algorithm choice for symmetric cryptography.)
- [Bodo Moeller]
-
- Changes between 0.9.8h and 0.9.8i [15 Sep 2008]
-
- *) Fix NULL pointer dereference if a DTLS server received
- ChangeCipherSpec as first record (CVE-2009-1386).
- [PR #1679]
-
- *) Fix a state transitition in s3_srvr.c and d1_srvr.c
- (was using SSL3_ST_CW_CLNT_HELLO_B, should be ..._ST_SW_SRVR_...).
- [Nagendra Modadugu]
-
- *) The fix in 0.9.8c that supposedly got rid of unsafe
- double-checked locking was incomplete for RSA blinding,
- addressing just one layer of what turns out to have been
- doubly unsafe triple-checked locking.
-
- So now fix this for real by retiring the MONT_HELPER macro
- in crypto/rsa/rsa_eay.c.
-
- [Bodo Moeller; problem pointed out by Marius Schilder]
-
- *) Various precautionary measures:
-
- - Avoid size_t integer overflow in HASH_UPDATE (md32_common.h).
-
- - Avoid a buffer overflow in d2i_SSL_SESSION() (ssl_asn1.c).
- (NB: This would require knowledge of the secret session ticket key
- to exploit, in which case you'd be SOL either way.)
-
- - Change bn_nist.c so that it will properly handle input BIGNUMs
- outside the expected range.
-
- - Enforce the 'num' check in BN_div() (bn_div.c) for non-BN_DEBUG
- builds.
-
- [Neel Mehta, Bodo Moeller]
-
- *) Allow engines to be "soft loaded" - i.e. optionally don't die if
- the load fails. Useful for distros.
- [Ben Laurie and the FreeBSD team]
-
- *) Add support for Local Machine Keyset attribute in PKCS#12 files.
- [Steve Henson]
-
- *) Fix BN_GF2m_mod_arr() top-bit cleanup code.
- [Huang Ying]
-
- *) Expand ENGINE to support engine supplied SSL client certificate functions.
-
- This work was sponsored by Logica.
- [Steve Henson]
-
- *) Add CryptoAPI ENGINE to support use of RSA and DSA keys held in Windows
- keystores. Support for SSL/TLS client authentication too.
- Not compiled unless enable-capieng specified to Configure.
-
- This work was sponsored by Logica.
- [Steve Henson]
-
- *) Fix bug in X509_ATTRIBUTE creation: dont set attribute using
- ASN1_TYPE_set1 if MBSTRING flag set. This bug would crash certain
- attribute creation routines such as certifcate requests and PKCS#12
- files.
- [Steve Henson]
-
- Changes between 0.9.8g and 0.9.8h [28 May 2008]
-
- *) Fix flaw if 'Server Key exchange message' is omitted from a TLS
- handshake which could lead to a cilent crash as found using the
- Codenomicon TLS test suite (CVE-2008-1672)
- [Steve Henson, Mark Cox]
-
- *) Fix double free in TLS server name extensions which could lead to
- a remote crash found by Codenomicon TLS test suite (CVE-2008-0891)
- [Joe Orton]
-
- *) Clear error queue in SSL_CTX_use_certificate_chain_file()
-
- Clear the error queue to ensure that error entries left from
- older function calls do not interfere with the correct operation.
- [Lutz Jaenicke, Erik de Castro Lopo]
-
- *) Remove root CA certificates of commercial CAs:
-
- The OpenSSL project does not recommend any specific CA and does not
- have any policy with respect to including or excluding any CA.
- Therefore it does not make any sense to ship an arbitrary selection
- of root CA certificates with the OpenSSL software.
- [Lutz Jaenicke]
-
- *) RSA OAEP patches to fix two separate invalid memory reads.
- The first one involves inputs when 'lzero' is greater than
- 'SHA_DIGEST_LENGTH' (it would read about SHA_DIGEST_LENGTH bytes
- before the beginning of from). The second one involves inputs where
- the 'db' section contains nothing but zeroes (there is a one-byte
- invalid read after the end of 'db').
- [Ivan Nestlerode <inestlerode@us.ibm.com>]
-
- *) Partial backport from 0.9.9-dev:
-
- Introduce bn_mul_mont (dedicated Montgomery multiplication
- procedure) as a candidate for BIGNUM assembler implementation.
- While 0.9.9-dev uses assembler for various architectures, only
- x86_64 is available by default here in the 0.9.8 branch, and
- 32-bit x86 is available through a compile-time setting.
-
- To try the 32-bit x86 assembler implementation, use Configure
- option "enable-montasm" (which exists only for this backport).
-
- As "enable-montasm" for 32-bit x86 disclaims code stability
- anyway, in this constellation we activate additional code
- backported from 0.9.9-dev for further performance improvements,
- namely BN_from_montgomery_word. (To enable this otherwise,
- e.g. x86_64, try "-DMONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD".)
-
- [Andy Polyakov (backport partially by Bodo Moeller)]
-
- *) Add TLS session ticket callback. This allows an application to set
- TLS ticket cipher and HMAC keys rather than relying on hardcoded fixed
- values. This is useful for key rollover for example where several key
- sets may exist with different names.
- [Steve Henson]
-
- *) Reverse ENGINE-internal logic for caching default ENGINE handles.
- This was broken until now in 0.9.8 releases, such that the only way
- a registered ENGINE could be used (assuming it initialises
- successfully on the host) was to explicitly set it as the default
- for the relevant algorithms. This is in contradiction with 0.9.7
- behaviour and the documentation. With this fix, when an ENGINE is
- registered into a given algorithm's table of implementations, the
- 'uptodate' flag is reset so that auto-discovery will be used next
- time a new context for that algorithm attempts to select an
- implementation.
- [Ian Lister (tweaked by Geoff Thorpe)]
-
- *) Backport of CMS code to OpenSSL 0.9.8. This differs from the 0.9.9
- implemention in the following ways:
-
- Lack of EVP_PKEY_ASN1_METHOD means algorithm parameters have to be
- hard coded.
-
- Lack of BER streaming support means one pass streaming processing is
- only supported if data is detached: setting the streaming flag is
- ignored for embedded content.
-
- CMS support is disabled by default and must be explicitly enabled
- with the enable-cms configuration option.
- [Steve Henson]
-
- *) Update the GMP engine glue to do direct copies between BIGNUM and
- mpz_t when openssl and GMP use the same limb size. Otherwise the
- existing "conversion via a text string export" trick is still used.
- [Paul Sheer <paulsheer@gmail.com>]
-
- *) Zlib compression BIO. This is a filter BIO which compressed and
- uncompresses any data passed through it.
- [Steve Henson]
-
- *) Add AES_wrap_key() and AES_unwrap_key() functions to implement
- RFC3394 compatible AES key wrapping.
- [Steve Henson]
-
- *) Add utility functions to handle ASN1 structures. ASN1_STRING_set0():
- sets string data without copying. X509_ALGOR_set0() and
- X509_ALGOR_get0(): set and retrieve X509_ALGOR (AlgorithmIdentifier)
- data. Attribute function X509at_get0_data_by_OBJ(): retrieves data
- from an X509_ATTRIBUTE structure optionally checking it occurs only
- once. ASN1_TYPE_set1(): set and ASN1_TYPE structure copying supplied
- data.
- [Steve Henson]
-
- *) Fix BN flag handling in RSA_eay_mod_exp() and BN_MONT_CTX_set()
- to get the expected BN_FLG_CONSTTIME behavior.
- [Bodo Moeller (Google)]
-
- *) Netware support:
-
- - fixed wrong usage of ioctlsocket() when build for LIBC BSD sockets
- - fixed do_tests.pl to run the test suite with CLIB builds too (CLIB_OPT)
- - added some more tests to do_tests.pl
- - fixed RunningProcess usage so that it works with newer LIBC NDKs too
- - removed usage of BN_LLONG for CLIB builds to avoid runtime dependency
- - added new Configure targets netware-clib-bsdsock, netware-clib-gcc,
- netware-clib-bsdsock-gcc, netware-libc-bsdsock-gcc
- - various changes to netware.pl to enable gcc-cross builds on Win32
- platform
- - changed crypto/bio/b_sock.c to work with macro functions (CLIB BSD)
- - various changes to fix missing prototype warnings
- - fixed x86nasm.pl to create correct asm files for NASM COFF output
- - added AES, WHIRLPOOL and CPUID assembler code to build files
- - added missing AES assembler make rules to mk1mf.pl
- - fixed order of includes in apps/ocsp.c so that e_os.h settings apply
- [Guenter Knauf <eflash@gmx.net>]
-
- *) Implement certificate status request TLS extension defined in RFC3546.
- A client can set the appropriate parameters and receive the encoded
- OCSP response via a callback. A server can query the supplied parameters
- and set the encoded OCSP response in the callback. Add simplified examples
- to s_client and s_server.
- [Steve Henson]
-
- Changes between 0.9.8f and 0.9.8g [19 Oct 2007]
-
- *) Fix various bugs:
- + Binary incompatibility of ssl_ctx_st structure
- + DTLS interoperation with non-compliant servers
- + Don't call get_session_cb() without proposed session
- + Fix ia64 assembler code
- [Andy Polyakov, Steve Henson]
-
- Changes between 0.9.8e and 0.9.8f [11 Oct 2007]
-
- *) DTLS Handshake overhaul. There were longstanding issues with
- OpenSSL DTLS implementation, which were making it impossible for
- RFC 4347 compliant client to communicate with OpenSSL server.
- Unfortunately just fixing these incompatibilities would "cut off"
- pre-0.9.8f clients. To allow for hassle free upgrade post-0.9.8e
- server keeps tolerating non RFC compliant syntax. The opposite is
- not true, 0.9.8f client can not communicate with earlier server.
- This update even addresses CVE-2007-4995.
- [Andy Polyakov]
-
- *) Changes to avoid need for function casts in OpenSSL: some compilers
- (gcc 4.2 and later) reject their use.
- [Kurt Roeckx <kurt@roeckx.be>, Peter Hartley <pdh@utter.chaos.org.uk>,
- Steve Henson]
-
- *) Add RFC4507 support to OpenSSL. This includes the corrections in
- RFC4507bis. The encrypted ticket format is an encrypted encoded
- SSL_SESSION structure, that way new session features are automatically
- supported.
-
- If a client application caches session in an SSL_SESSION structure
- support is transparent because tickets are now stored in the encoded
- SSL_SESSION.
-
- The SSL_CTX structure automatically generates keys for ticket
- protection in servers so again support should be possible
- with no application modification.
-
- If a client or server wishes to disable RFC4507 support then the option
- SSL_OP_NO_TICKET can be set.
-
- Add a TLS extension debugging callback to allow the contents of any client
- or server extensions to be examined.
-
- This work was sponsored by Google.
- [Steve Henson]
-
- *) Add initial support for TLS extensions, specifically for the server_name
- extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now
- have new members for a host name. The SSL data structure has an
- additional member SSL_CTX *initial_ctx so that new sessions can be
- stored in that context to allow for session resumption, even after the
- SSL has been switched to a new SSL_CTX in reaction to a client's
- server_name extension.
-
- New functions (subject to change):
-
- SSL_get_servername()
- SSL_get_servername_type()
- SSL_set_SSL_CTX()
-
- New CTRL codes and macros (subject to change):
-
- SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
- - SSL_CTX_set_tlsext_servername_callback()
- SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
- - SSL_CTX_set_tlsext_servername_arg()
- SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name()
-
- openssl s_client has a new '-servername ...' option.
-
- openssl s_server has new options '-servername_host ...', '-cert2 ...',
- '-key2 ...', '-servername_fatal' (subject to change). This allows
- testing the HostName extension for a specific single host name ('-cert'
- and '-key' remain fallbacks for handshakes without HostName
- negotiation). If the unrecogninzed_name alert has to be sent, this by
- default is a warning; it becomes fatal with the '-servername_fatal'
- option.
-
- [Peter Sylvester, Remy Allais, Christophe Renou, Steve Henson]
-
- *) Add AES and SSE2 assembly language support to VC++ build.
- [Steve Henson]
-
- *) Mitigate attack on final subtraction in Montgomery reduction.
- [Andy Polyakov]
-
- *) Fix crypto/ec/ec_mult.c to work properly with scalars of value 0
- (which previously caused an internal error).
- [Bodo Moeller]
-
- *) Squeeze another 10% out of IGE mode when in != out.
- [Ben Laurie]
-
- *) AES IGE mode speedup.
- [Dean Gaudet (Google)]
-
- *) Add the Korean symmetric 128-bit cipher SEED (see
- http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp) and
- add SEED ciphersuites from RFC 4162:
-
- TLS_RSA_WITH_SEED_CBC_SHA = "SEED-SHA"
- TLS_DHE_DSS_WITH_SEED_CBC_SHA = "DHE-DSS-SEED-SHA"
- TLS_DHE_RSA_WITH_SEED_CBC_SHA = "DHE-RSA-SEED-SHA"
- TLS_DH_anon_WITH_SEED_CBC_SHA = "ADH-SEED-SHA"
-
- To minimize changes between patchlevels in the OpenSSL 0.9.8
- series, SEED remains excluded from compilation unless OpenSSL
- is configured with 'enable-seed'.
- [KISA, Bodo Moeller]
-
- *) Mitigate branch prediction attacks, which can be practical if a
- single processor is shared, allowing a spy process to extract
- information. For detailed background information, see
- http://eprint.iacr.org/2007/039 (O. Aciicmez, S. Gueron,
- J.-P. Seifert, "New Branch Prediction Vulnerabilities in OpenSSL
- and Necessary Software Countermeasures"). The core of the change
- are new versions BN_div_no_branch() and
- BN_mod_inverse_no_branch() of BN_div() and BN_mod_inverse(),
- respectively, which are slower, but avoid the security-relevant
- conditional branches. These are automatically called by BN_div()
- and BN_mod_inverse() if the flag BN_FLG_CONSTTIME is set for one
- of the input BIGNUMs. Also, BN_is_bit_set() has been changed to
- remove a conditional branch.
-
- BN_FLG_CONSTTIME is the new name for the previous
- BN_FLG_EXP_CONSTTIME flag, since it now affects more than just
- modular exponentiation. (Since OpenSSL 0.9.7h, setting this flag
- in the exponent causes BN_mod_exp_mont() to use the alternative
- implementation in BN_mod_exp_mont_consttime().) The old name
- remains as a deprecated alias.
-
- Similary, RSA_FLAG_NO_EXP_CONSTTIME is replaced by a more general
- RSA_FLAG_NO_CONSTTIME flag since the RSA implementation now uses
- constant-time implementations for more than just exponentiation.
- Here too the old name is kept as a deprecated alias.
-
- BN_BLINDING_new() will now use BN_dup() for the modulus so that
- the BN_BLINDING structure gets an independent copy of the
- modulus. This means that the previous "BIGNUM *m" argument to
- BN_BLINDING_new() and to BN_BLINDING_create_param() now
- essentially becomes "const BIGNUM *m", although we can't actually
- change this in the header file before 0.9.9. It allows
- RSA_setup_blinding() to use BN_with_flags() on the modulus to
- enable BN_FLG_CONSTTIME.
-
- [Matthew D Wood (Intel Corp)]
-
- *) In the SSL/TLS server implementation, be strict about session ID
- context matching (which matters if an application uses a single
- external cache for different purposes). Previously,
- out-of-context reuse was forbidden only if SSL_VERIFY_PEER was
- set. This did ensure strict client verification, but meant that,
- with applications using a single external cache for quite
- different requirements, clients could circumvent ciphersuite
- restrictions for a given session ID context by starting a session
- in a different context.
- [Bodo Moeller]
-
- *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
- a ciphersuite string such as "DEFAULT:RSA" cannot enable
- authentication-only ciphersuites.
- [Bodo Moeller]
-
- *) Update the SSL_get_shared_ciphers() fix CVE-2006-3738 which was
- not complete and could lead to a possible single byte overflow
- (CVE-2007-5135) [Ben Laurie]
-
- Changes between 0.9.8d and 0.9.8e [23 Feb 2007]
-
- *) Since AES128 and AES256 (and similarly Camellia128 and
- Camellia256) share a single mask bit in the logic of
- ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
- kludge to work properly if AES128 is available and AES256 isn't
- (or if Camellia128 is available and Camellia256 isn't).
- [Victor Duchovni]
-
- *) Fix the BIT STRING encoding generated by crypto/ec/ec_asn1.c
- (within i2d_ECPrivateKey, i2d_ECPKParameters, i2d_ECParameters):
- When a point or a seed is encoded in a BIT STRING, we need to
- prevent the removal of trailing zero bits to get the proper DER
- encoding. (By default, crypto/asn1/a_bitstr.c assumes the case
- of a NamedBitList, for which trailing 0 bits need to be removed.)
- [Bodo Moeller]
-
- *) Have SSL/TLS server implementation tolerate "mismatched" record
- protocol version while receiving ClientHello even if the
- ClientHello is fragmented. (The server can't insist on the
- particular protocol version it has chosen before the ServerHello
- message has informed the client about his choice.)
- [Bodo Moeller]
-
- *) Add RFC 3779 support.
- [Rob Austein for ARIN, Ben Laurie]
-
- *) Load error codes if they are not already present instead of using a
- static variable. This allows them to be cleanly unloaded and reloaded.
- Improve header file function name parsing.
- [Steve Henson]
-
- *) extend SMTP and IMAP protocol emulation in s_client to use EHLO
- or CAPABILITY handshake as required by RFCs.
- [Goetz Babin-Ebell]
-
- Changes between 0.9.8c and 0.9.8d [28 Sep 2006]
-
- *) Introduce limits to prevent malicious keys being able to
- cause a denial of service. (CVE-2006-2940)
- [Steve Henson, Bodo Moeller]
-
- *) Fix ASN.1 parsing of certain invalid structures that can result
- in a denial of service. (CVE-2006-2937) [Steve Henson]
-
- *) Fix buffer overflow in SSL_get_shared_ciphers() function.
- (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team]
-
- *) Fix SSL client code which could crash if connecting to a
- malicious SSLv2 server. (CVE-2006-4343)
- [Tavis Ormandy and Will Drewry, Google Security Team]
-
- *) Since 0.9.8b, ciphersuite strings naming explicit ciphersuites
- match only those. Before that, "AES256-SHA" would be interpreted
- as a pattern and match "AES128-SHA" too (since AES128-SHA got
- the same strength classification in 0.9.7h) as we currently only
- have a single AES bit in the ciphersuite description bitmap.
- That change, however, also applied to ciphersuite strings such as
- "RC4-MD5" that intentionally matched multiple ciphersuites --
- namely, SSL 2.0 ciphersuites in addition to the more common ones
- from SSL 3.0/TLS 1.0.
-
- So we change the selection algorithm again: Naming an explicit
- ciphersuite selects this one ciphersuite, and any other similar
- ciphersuite (same bitmap) from *other* protocol versions.
- Thus, "RC4-MD5" again will properly select both the SSL 2.0
- ciphersuite and the SSL 3.0/TLS 1.0 ciphersuite.
-
- Since SSL 2.0 does not have any ciphersuites for which the
- 128/256 bit distinction would be relevant, this works for now.
- The proper fix will be to use different bits for AES128 and
- AES256, which would have avoided the problems from the beginning;
- however, bits are scarce, so we can only do this in a new release
- (not just a patchlevel) when we can change the SSL_CIPHER
- definition to split the single 'unsigned long mask' bitmap into
- multiple values to extend the available space.
-
- [Bodo Moeller]
-
- Changes between 0.9.8b and 0.9.8c [05 Sep 2006]
-
- *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher
- (CVE-2006-4339) [Ben Laurie and Google Security Team]
-
- *) Add AES IGE and biIGE modes.
- [Ben Laurie]
-
- *) Change the Unix randomness entropy gathering to use poll() when
- possible instead of select(), since the latter has some
- undesirable limitations.
- [Darryl Miles via Richard Levitte and Bodo Moeller]
-
- *) Disable "ECCdraft" ciphersuites more thoroughly. Now special
- treatment in ssl/ssl_ciph.s makes sure that these ciphersuites
- cannot be implicitly activated as part of, e.g., the "AES" alias.
- However, please upgrade to OpenSSL 0.9.9[-dev] for
- non-experimental use of the ECC ciphersuites to get TLS extension
- support, which is required for curve and point format negotiation
- to avoid potential handshake problems.
- [Bodo Moeller]
-
- *) Disable rogue ciphersuites:
-
- - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5")
- - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5")
- - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5")
-
- The latter two were purportedly from
- draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really
- appear there.
-
- Also deactivate the remaining ciphersuites from
- draft-ietf-tls-56-bit-ciphersuites-01.txt. These are just as
- unofficial, and the ID has long expired.
- [Bodo Moeller]
-
- *) Fix RSA blinding Heisenbug (problems sometimes occured on
- dual-core machines) and other potential thread-safety issues.
- [Bodo Moeller]
-
- *) Add the symmetric cipher Camellia (128-bit, 192-bit, 256-bit key
- versions), which is now available for royalty-free use
- (see http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html).
- Also, add Camellia TLS ciphersuites from RFC 4132.
-
- To minimize changes between patchlevels in the OpenSSL 0.9.8
- series, Camellia remains excluded from compilation unless OpenSSL
- is configured with 'enable-camellia'.
- [NTT]
-
- *) Disable the padding bug check when compression is in use. The padding
- bug check assumes the first packet is of even length, this is not
- necessarily true if compresssion is enabled and can result in false
- positives causing handshake failure. The actual bug test is ancient
- code so it is hoped that implementations will either have fixed it by
- now or any which still have the bug do not support compression.
- [Steve Henson]
-
- Changes between 0.9.8a and 0.9.8b [04 May 2006]
-
- *) When applying a cipher rule check to see if string match is an explicit
- cipher suite and only match that one cipher suite if it is.
- [Steve Henson]
-
- *) Link in manifests for VC++ if needed.
- [Austin Ziegler <halostatue@gmail.com>]
-
- *) Update support for ECC-based TLS ciphersuites according to
- draft-ietf-tls-ecc-12.txt with proposed changes (but without
- TLS extensions, which are supported starting with the 0.9.9
- branch, not in the OpenSSL 0.9.8 branch).
- [Douglas Stebila]
-
- *) New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free() to support
- opaque EVP_CIPHER_CTX handling.
- [Steve Henson]
-
- *) Fixes and enhancements to zlib compression code. We now only use
- "zlib1.dll" and use the default __cdecl calling convention on Win32
- to conform with the standards mentioned here:
- http://www.zlib.net/DLL_FAQ.txt
- Static zlib linking now works on Windows and the new --with-zlib-include
- --with-zlib-lib options to Configure can be used to supply the location
- of the headers and library. Gracefully handle case where zlib library
- can't be loaded.
- [Steve Henson]
-
- *) Several fixes and enhancements to the OID generation code. The old code
- sometimes allowed invalid OIDs (1.X for X >= 40 for example), couldn't
- handle numbers larger than ULONG_MAX, truncated printing and had a
- non standard OBJ_obj2txt() behaviour.
- [Steve Henson]
-
- *) Add support for building of engines under engine/ as shared libraries
- under VC++ build system.
- [Steve Henson]
-
- *) Corrected the numerous bugs in the Win32 path splitter in DSO.
- Hopefully, we will not see any false combination of paths any more.
- [Richard Levitte]
-
- Changes between 0.9.8 and 0.9.8a [11 Oct 2005]
-
- *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING
- (part of SSL_OP_ALL). This option used to disable the
- countermeasure against man-in-the-middle protocol-version
- rollback in the SSL 2.0 server implementation, which is a bad
- idea. (CVE-2005-2969)
-
- [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center
- for Information Security, National Institute of Advanced Industrial
- Science and Technology [AIST], Japan)]
-
- *) Add two function to clear and return the verify parameter flags.
- [Steve Henson]
-
- *) Keep cipherlists sorted in the source instead of sorting them at
- runtime, thus removing the need for a lock.
- [Nils Larsch]
-
- *) Avoid some small subgroup attacks in Diffie-Hellman.
- [Nick Mathewson and Ben Laurie]
-
- *) Add functions for well-known primes.
- [Nick Mathewson]
-
- *) Extended Windows CE support.
- [Satoshi Nakamura and Andy Polyakov]
-
- *) Initialize SSL_METHOD structures at compile time instead of during
- runtime, thus removing the need for a lock.
- [Steve Henson]
-
- *) Make PKCS7_decrypt() work even if no certificate is supplied by
- attempting to decrypt each encrypted key in turn. Add support to
- smime utility.
- [Steve Henson]
-
- Changes between 0.9.7h and 0.9.8 [05 Jul 2005]
-
- [NB: OpenSSL 0.9.7i and later 0.9.7 patch levels were released after
- OpenSSL 0.9.8.]
-
- *) Add libcrypto.pc and libssl.pc for those who feel they need them.
- [Richard Levitte]
-
- *) Change CA.sh and CA.pl so they don't bundle the CSR and the private
- key into the same file any more.
- [Richard Levitte]
-
- *) Add initial support for Win64, both IA64 and AMD64/x64 flavors.
- [Andy Polyakov]
-
- *) Add -utf8 command line and config file option to 'ca'.
- [Stefan <stf@udoma.org]
-
- *) Removed the macro des_crypt(), as it seems to conflict with some
- libraries. Use DES_crypt().
- [Richard Levitte]
-
- *) Correct naming of the 'chil' and '4758cca' ENGINEs. This
- involves renaming the source and generated shared-libs for
- both. The engines will accept the corrected or legacy ids
- ('ncipher' and '4758_cca' respectively) when binding. NB,
- this only applies when building 'shared'.
- [Corinna Vinschen <vinschen@redhat.com> and Geoff Thorpe]
-
- *) Add attribute functions to EVP_PKEY structure. Modify
- PKCS12_create() to recognize a CSP name attribute and
- use it. Make -CSP option work again in pkcs12 utility.
- [Steve Henson]
-
- *) Add new functionality to the bn blinding code:
- - automatic re-creation of the BN_BLINDING parameters after
- a fixed number of uses (currently 32)
- - add new function for parameter creation
- - introduce flags to control the update behaviour of the
- BN_BLINDING parameters
- - hide BN_BLINDING structure
- Add a second BN_BLINDING slot to the RSA structure to improve
- performance when a single RSA object is shared among several
- threads.
- [Nils Larsch]
-
- *) Add support for DTLS.
- [Nagendra Modadugu <nagendra@cs.stanford.edu> and Ben Laurie]
-
- *) Add support for DER encoded private keys (SSL_FILETYPE_ASN1)
- to SSL_CTX_use_PrivateKey_file() and SSL_use_PrivateKey_file()
- [Walter Goulet]
-
- *) Remove buggy and incompletet DH cert support from
- ssl/ssl_rsa.c and ssl/s3_both.c
- [Nils Larsch]
-
- *) Use SHA-1 instead of MD5 as the default digest algorithm for
- the apps/openssl applications.
- [Nils Larsch]
-
- *) Compile clean with "-Wall -Wmissing-prototypes
- -Wstrict-prototypes -Wmissing-declarations -Werror". Currently
- DEBUG_SAFESTACK must also be set.
- [Ben Laurie]
-
- *) Change ./Configure so that certain algorithms can be disabled by default.
- The new counterpiece to "no-xxx" is "enable-xxx".
-
- The patented RC5 and MDC2 algorithms will now be disabled unless
- "enable-rc5" and "enable-mdc2", respectively, are specified.
-
- (IDEA remains enabled despite being patented. This is because IDEA
- is frequently required for interoperability, and there is no license
- fee for non-commercial use. As before, "no-idea" can be used to
- avoid this algorithm.)
-
- [Bodo Moeller]
-
- *) Add processing of proxy certificates (see RFC 3820). This work was
- sponsored by KTH (The Royal Institute of Technology in Stockholm) and
- EGEE (Enabling Grids for E-science in Europe).
- [Richard Levitte]
-
- *) RC4 performance overhaul on modern architectures/implementations, such
- as Intel P4, IA-64 and AMD64.
- [Andy Polyakov]
-
- *) New utility extract-section.pl. This can be used specify an alternative
- section number in a pod file instead of having to treat each file as
- a separate case in Makefile. This can be done by adding two lines to the
- pod file:
-
- =for comment openssl_section:XXX
-
- The blank line is mandatory.
-
- [Steve Henson]
-
- *) New arguments -certform, -keyform and -pass for s_client and s_server
- to allow alternative format key and certificate files and passphrase
- sources.
- [Steve Henson]
-
- *) New structure X509_VERIFY_PARAM which combines current verify parameters,
- update associated structures and add various utility functions.
-
- Add new policy related verify parameters, include policy checking in
- standard verify code. Enhance 'smime' application with extra parameters
- to support policy checking and print out.
- [Steve Henson]
-
- *) Add a new engine to support VIA PadLock ACE extensions in the VIA C3
- Nehemiah processors. These extensions support AES encryption in hardware
- as well as RNG (though RNG support is currently disabled).
- [Michal Ludvig <michal@logix.cz>, with help from Andy Polyakov]
-
- *) Deprecate BN_[get|set]_params() functions (they were ignored internally).
- [Geoff Thorpe]
-
- *) New FIPS 180-2 algorithms, SHA-224/-256/-384/-512 are implemented.
- [Andy Polyakov and a number of other people]
-
- *) Improved PowerPC platform support. Most notably BIGNUM assembler
- implementation contributed by IBM.
- [Suresh Chari, Peter Waltenberg, Andy Polyakov]
-
- *) The new 'RSA_generate_key_ex' function now takes a BIGNUM for the public
- exponent rather than 'unsigned long'. There is a corresponding change to
- the new 'rsa_keygen' element of the RSA_METHOD structure.
- [Jelte Jansen, Geoff Thorpe]
-
- *) Functionality for creating the initial serial number file is now
- moved from CA.pl to the 'ca' utility with a new option -create_serial.
-
- (Before OpenSSL 0.9.7e, CA.pl used to initialize the serial
- number file to 1, which is bound to cause problems. To avoid
- the problems while respecting compatibility between different 0.9.7
- patchlevels, 0.9.7e employed 'openssl x509 -next_serial' in
- CA.pl for serial number initialization. With the new release 0.9.8,
- we can fix the problem directly in the 'ca' utility.)
- [Steve Henson]
-
- *) Reduced header interdepencies by declaring more opaque objects in
- ossl_typ.h. As a consequence, including some headers (eg. engine.h) will
- give fewer recursive includes, which could break lazy source code - so
- this change is covered by the OPENSSL_NO_DEPRECATED symbol. As always,
- developers should define this symbol when building and using openssl to
- ensure they track the recommended behaviour, interfaces, [etc], but
- backwards-compatible behaviour prevails when this isn't defined.
- [Geoff Thorpe]
-
- *) New function X509_POLICY_NODE_print() which prints out policy nodes.
- [Steve Henson]
-
- *) Add new EVP function EVP_CIPHER_CTX_rand_key and associated functionality.
- This will generate a random key of the appropriate length based on the
- cipher context. The EVP_CIPHER can provide its own random key generation
- routine to support keys of a specific form. This is used in the des and
- 3des routines to generate a key of the correct parity. Update S/MIME
- code to use new functions and hence generate correct parity DES keys.
- Add EVP_CHECK_DES_KEY #define to return an error if the key is not
- valid (weak or incorrect parity).
- [Steve Henson]
-
- *) Add a local set of CRLs that can be used by X509_verify_cert() as well
- as looking them up. This is useful when the verified structure may contain
- CRLs, for example PKCS#7 signedData. Modify PKCS7_verify() to use any CRLs
- present unless the new PKCS7_NO_CRL flag is asserted.
- [Steve Henson]
-
- *) Extend ASN1 oid configuration module. It now additionally accepts the
- syntax:
-
- shortName = some long name, 1.2.3.4
- [Steve Henson]
-
- *) Reimplemented the BN_CTX implementation. There is now no more static
- limitation on the number of variables it can handle nor the depth of the
- "stack" handling for BN_CTX_start()/BN_CTX_end() pairs. The stack
- information can now expand as required, and rather than having a single
- static array of bignums, BN_CTX now uses a linked-list of such arrays
- allowing it to expand on demand whilst maintaining the usefulness of
- BN_CTX's "bundling".
- [Geoff Thorpe]
-
- *) Add a missing BN_CTX parameter to the 'rsa_mod_exp' callback in RSA_METHOD
- to allow all RSA operations to function using a single BN_CTX.
- [Geoff Thorpe]
-
- *) Preliminary support for certificate policy evaluation and checking. This
- is initially intended to pass the tests outlined in "Conformance Testing
- of Relying Party Client Certificate Path Processing Logic" v1.07.
- [Steve Henson]
-
- *) bn_dup_expand() has been deprecated, it was introduced in 0.9.7 and
- remained unused and not that useful. A variety of other little bignum
- tweaks and fixes have also been made continuing on from the audit (see
- below).
- [Geoff Thorpe]
-
- *) Constify all or almost all d2i, c2i, s2i and r2i functions, along with
- associated ASN1, EVP and SSL functions and old ASN1 macros.
- [Richard Levitte]
-
- *) BN_zero() only needs to set 'top' and 'neg' to zero for correct results,
- and this should never fail. So the return value from the use of
- BN_set_word() (which can fail due to needless expansion) is now deprecated;
- if OPENSSL_NO_DEPRECATED is defined, BN_zero() is a void macro.
- [Geoff Thorpe]
-
- *) BN_CTX_get() should return zero-valued bignums, providing the same
- initialised value as BN_new().
- [Geoff Thorpe, suggested by Ulf Möller]
-
- *) Support for inhibitAnyPolicy certificate extension.
- [Steve Henson]
-
- *) An audit of the BIGNUM code is underway, for which debugging code is
- enabled when BN_DEBUG is defined. This makes stricter enforcements on what
- is considered valid when processing BIGNUMs, and causes execution to
- assert() when a problem is discovered. If BN_DEBUG_RAND is defined,
- further steps are taken to deliberately pollute unused data in BIGNUM
- structures to try and expose faulty code further on. For now, openssl will
- (in its default mode of operation) continue to tolerate the inconsistent
- forms that it has tolerated in the past, but authors and packagers should
- consider trying openssl and their own applications when compiled with
- these debugging symbols defined. It will help highlight potential bugs in
- their own code, and will improve the test coverage for OpenSSL itself. At
- some point, these tighter rules will become openssl's default to improve
- maintainability, though the assert()s and other overheads will remain only
- in debugging configurations. See bn.h for more details.
- [Geoff Thorpe, Nils Larsch, Ulf Möller]
-
- *) BN_CTX_init() has been deprecated, as BN_CTX is an opaque structure
- that can only be obtained through BN_CTX_new() (which implicitly
- initialises it). The presence of this function only made it possible
- to overwrite an existing structure (and cause memory leaks).
- [Geoff Thorpe]
-
- *) Because of the callback-based approach for implementing LHASH as a
- template type, lh_insert() adds opaque objects to hash-tables and
- lh_doall() or lh_doall_arg() are typically used with a destructor callback
- to clean up those corresponding objects before destroying the hash table
- (and losing the object pointers). So some over-zealous constifications in
- LHASH have been relaxed so that lh_insert() does not take (nor store) the
- objects as "const" and the lh_doall[_arg] callback wrappers are not
- prototyped to have "const" restrictions on the object pointers they are
- given (and so aren't required to cast them away any more).
- [Geoff Thorpe]
-
- *) The tmdiff.h API was so ugly and minimal that our own timing utility
- (speed) prefers to use its own implementation. The two implementations
- haven't been consolidated as yet (volunteers?) but the tmdiff API has had
- its object type properly exposed (MS_TM) instead of casting to/from "char
- *". This may still change yet if someone realises MS_TM and "ms_time_***"
- aren't necessarily the greatest nomenclatures - but this is what was used
- internally to the implementation so I've used that for now.
- [Geoff Thorpe]
-
- *) Ensure that deprecated functions do not get compiled when
- OPENSSL_NO_DEPRECATED is defined. Some "openssl" subcommands and a few of
- the self-tests were still using deprecated key-generation functions so
- these have been updated also.
- [Geoff Thorpe]
-
- *) Reorganise PKCS#7 code to separate the digest location functionality
- into PKCS7_find_digest(), digest addtion into PKCS7_bio_add_digest().
- New function PKCS7_set_digest() to set the digest type for PKCS#7
- digestedData type. Add additional code to correctly generate the
- digestedData type and add support for this type in PKCS7 initialization
- functions.
- [Steve Henson]
-
- *) New function PKCS7_set0_type_other() this initializes a PKCS7
- structure of type "other".
- [Steve Henson]
-
- *) Fix prime generation loop in crypto/bn/bn_prime.pl by making
- sure the loop does correctly stop and breaking ("division by zero")
- modulus operations are not performed. The (pre-generated) prime
- table crypto/bn/bn_prime.h was already correct, but it could not be
- re-generated on some platforms because of the "division by zero"
- situation in the script.
- [Ralf S. Engelschall]
-
- *) Update support for ECC-based TLS ciphersuites according to
- draft-ietf-tls-ecc-03.txt: the KDF1 key derivation function with
- SHA-1 now is only used for "small" curves (where the
- representation of a field element takes up to 24 bytes); for
- larger curves, the field element resulting from ECDH is directly
- used as premaster secret.
- [Douglas Stebila (Sun Microsystems Laboratories)]
-
- *) Add code for kP+lQ timings to crypto/ec/ectest.c, and add SEC2
- curve secp160r1 to the tests.
- [Douglas Stebila (Sun Microsystems Laboratories)]
-
- *) Add the possibility to load symbols globally with DSO.
- [Götz Babin-Ebell <babin-ebell@trustcenter.de> via Richard Levitte]
-
- *) Add the functions ERR_set_mark() and ERR_pop_to_mark() for better
- control of the error stack.
- [Richard Levitte]
-
- *) Add support for STORE in ENGINE.
- [Richard Levitte]
-
- *) Add the STORE type. The intention is to provide a common interface
- to certificate and key stores, be they simple file-based stores, or
- HSM-type store, or LDAP stores, or...
- NOTE: The code is currently UNTESTED and isn't really used anywhere.
- [Richard Levitte]
-
- *) Add a generic structure called OPENSSL_ITEM. This can be used to
- pass a list of arguments to any function as well as provide a way
- for a function to pass data back to the caller.
- [Richard Levitte]
-
- *) Add the functions BUF_strndup() and BUF_memdup(). BUF_strndup()
- works like BUF_strdup() but can be used to duplicate a portion of
- a string. The copy gets NUL-terminated. BUF_memdup() duplicates
- a memory area.
- [Richard Levitte]
-
- *) Add the function sk_find_ex() which works like sk_find(), but will
- return an index to an element even if an exact match couldn't be
- found. The index is guaranteed to point at the element where the
- searched-for key would be inserted to preserve sorting order.
- [Richard Levitte]
-
- *) Add the function OBJ_bsearch_ex() which works like OBJ_bsearch() but
- takes an extra flags argument for optional functionality. Currently,
- the following flags are defined:
-
- OBJ_BSEARCH_VALUE_ON_NOMATCH
- This one gets OBJ_bsearch_ex() to return a pointer to the first
- element where the comparing function returns a negative or zero
- number.
-
- OBJ_BSEARCH_FIRST_VALUE_ON_MATCH
- This one gets OBJ_bsearch_ex() to return a pointer to the first
- element where the comparing function returns zero. This is useful
- if there are more than one element where the comparing function
- returns zero.
- [Richard Levitte]
-
- *) Make it possible to create self-signed certificates with 'openssl ca'
- in such a way that the self-signed certificate becomes part of the
- CA database and uses the same mechanisms for serial number generation
- as all other certificate signing. The new flag '-selfsign' enables
- this functionality. Adapt CA.sh and CA.pl.in.
- [Richard Levitte]
-
- *) Add functionality to check the public key of a certificate request
- against a given private. This is useful to check that a certificate
- request can be signed by that key (self-signing).
- [Richard Levitte]
-
- *) Make it possible to have multiple active certificates with the same
- subject in the CA index file. This is done only if the keyword
- 'unique_subject' is set to 'no' in the main CA section (default
- if 'CA_default') of the configuration file. The value is saved
- with the database itself in a separate index attribute file,
- named like the index file with '.attr' appended to the name.
- [Richard Levitte]
-
- *) Generate muti valued AVAs using '+' notation in config files for
- req and dirName.
- [Steve Henson]
-
- *) Support for nameConstraints certificate extension.
- [Steve Henson]
-
- *) Support for policyConstraints certificate extension.
- [Steve Henson]
-
- *) Support for policyMappings certificate extension.
- [Steve Henson]
-
- *) Make sure the default DSA_METHOD implementation only uses its
- dsa_mod_exp() and/or bn_mod_exp() handlers if they are non-NULL,
- and change its own handlers to be NULL so as to remove unnecessary
- indirection. This lets alternative implementations fallback to the
- default implementation more easily.
- [Geoff Thorpe]
-
- *) Support for directoryName in GeneralName related extensions
- in config files.
- [Steve Henson]
-
- *) Make it possible to link applications using Makefile.shared.
- Make that possible even when linking against static libraries!
- [Richard Levitte]
-
- *) Support for single pass processing for S/MIME signing. This now
- means that S/MIME signing can be done from a pipe, in addition
- cleartext signing (multipart/signed type) is effectively streaming
- and the signed data does not need to be all held in memory.
-
- This is done with a new flag PKCS7_STREAM. When this flag is set
- PKCS7_sign() only initializes the PKCS7 structure and the actual signing
- is done after the data is output (and digests calculated) in
- SMIME_write_PKCS7().
- [Steve Henson]
-
- *) Add full support for -rpath/-R, both in shared libraries and
- applications, at least on the platforms where it's known how
- to do it.
- [Richard Levitte]
-
- *) In crypto/ec/ec_mult.c, implement fast point multiplication with
- precomputation, based on wNAF splitting: EC_GROUP_precompute_mult()
- will now compute a table of multiples of the generator that
- makes subsequent invocations of EC_POINTs_mul() or EC_POINT_mul()
- faster (notably in the case of a single point multiplication,
- scalar * generator).
- [Nils Larsch, Bodo Moeller]
-
- *) IPv6 support for certificate extensions. The various extensions
- which use the IP:a.b.c.d can now take IPv6 addresses using the
- formats of RFC1884 2.2 . IPv6 addresses are now also displayed
- correctly.
- [Steve Henson]
-
- *) Added an ENGINE that implements RSA by performing private key
- exponentiations with the GMP library. The conversions to and from
- GMP's mpz_t format aren't optimised nor are any montgomery forms
- cached, and on x86 it appears OpenSSL's own performance has caught up.
- However there are likely to be other architectures where GMP could
- provide a boost. This ENGINE is not built in by default, but it can be
- specified at Configure time and should be accompanied by the necessary
- linker additions, eg;
- ./config -DOPENSSL_USE_GMP -lgmp
- [Geoff Thorpe]
-
- *) "openssl engine" will not display ENGINE/DSO load failure errors when
- testing availability of engines with "-t" - the old behaviour is
- produced by increasing the feature's verbosity with "-tt".
- [Geoff Thorpe]
-
- *) ECDSA routines: under certain error conditions uninitialized BN objects
- could be freed. Solution: make sure initialization is performed early
- enough. (Reported and fix supplied by Nils Larsch <nla@trustcenter.de>
- via PR#459)
- [Lutz Jaenicke]
-
- *) Key-generation can now be implemented in RSA_METHOD, DSA_METHOD
- and DH_METHOD (eg. by ENGINE implementations) to override the normal
- software implementations. For DSA and DH, parameter generation can
- also be overriden by providing the appropriate method callbacks.
- [Geoff Thorpe]
-
- *) Change the "progress" mechanism used in key-generation and
- primality testing to functions that take a new BN_GENCB pointer in
- place of callback/argument pairs. The new API functions have "_ex"
- postfixes and the older functions are reimplemented as wrappers for
- the new ones. The OPENSSL_NO_DEPRECATED symbol can be used to hide
- declarations of the old functions to help (graceful) attempts to
- migrate to the new functions. Also, the new key-generation API
- functions operate on a caller-supplied key-structure and return
- success/failure rather than returning a key or NULL - this is to
- help make "keygen" another member function of RSA_METHOD etc.
-
- Example for using the new callback interface:
-
- int (*my_callback)(int a, int b, BN_GENCB *cb) = ...;
- void *my_arg = ...;
- BN_GENCB my_cb;
-
- BN_GENCB_set(&my_cb, my_callback, my_arg);
-
- return BN_is_prime_ex(some_bignum, BN_prime_checks, NULL, &cb);
- /* For the meaning of a, b in calls to my_callback(), see the
- * documentation of the function that calls the callback.
- * cb will point to my_cb; my_arg can be retrieved as cb->arg.
- * my_callback should return 1 if it wants BN_is_prime_ex()
- * to continue, or 0 to stop.
- */
-
- [Geoff Thorpe]
-
- *) Change the ZLIB compression method to be stateful, and make it
- available to TLS with the number defined in
- draft-ietf-tls-compression-04.txt.
- [Richard Levitte]
-
- *) Add the ASN.1 structures and functions for CertificatePair, which
- is defined as follows (according to X.509_4thEditionDraftV6.pdf):
-
- CertificatePair ::= SEQUENCE {
- forward [0] Certificate OPTIONAL,
- reverse [1] Certificate OPTIONAL,
- -- at least one of the pair shall be present -- }
-
- Also implement the PEM functions to read and write certificate
- pairs, and defined the PEM tag as "CERTIFICATE PAIR".
-
- This needed to be defined, mostly for the sake of the LDAP
- attribute crossCertificatePair, but may prove useful elsewhere as
- well.
- [Richard Levitte]
-
- *) Make it possible to inhibit symlinking of shared libraries in
- Makefile.shared, for Cygwin's sake.
- [Richard Levitte]
-
- *) Extend the BIGNUM API by creating a function
- void BN_set_negative(BIGNUM *a, int neg);
- and a macro that behave like
- int BN_is_negative(const BIGNUM *a);
-
- to avoid the need to access 'a->neg' directly in applications.
- [Nils Larsch]
-
- *) Implement fast modular reduction for pseudo-Mersenne primes
- used in NIST curves (crypto/bn/bn_nist.c, crypto/ec/ecp_nist.c).
- EC_GROUP_new_curve_GFp() will now automatically use this
- if applicable.
- [Nils Larsch <nla@trustcenter.de>]
-
- *) Add new lock type (CRYPTO_LOCK_BN).
- [Bodo Moeller]
-
- *) Change the ENGINE framework to automatically load engines
- dynamically from specific directories unless they could be
- found to already be built in or loaded. Move all the
- current engines except for the cryptodev one to a new
- directory engines/.
- The engines in engines/ are built as shared libraries if
- the "shared" options was given to ./Configure or ./config.
- Otherwise, they are inserted in libcrypto.a.
- /usr/local/ssl/engines is the default directory for dynamic
- engines, but that can be overriden at configure time through
- the usual use of --prefix and/or --openssldir, and at run
- time with the environment variable OPENSSL_ENGINES.
- [Geoff Thorpe and Richard Levitte]
-
- *) Add Makefile.shared, a helper makefile to build shared
- libraries. Addapt Makefile.org.
- [Richard Levitte]
-
- *) Add version info to Win32 DLLs.
- [Peter 'Luna' Runestig" <peter@runestig.com>]
-
- *) Add new 'medium level' PKCS#12 API. Certificates and keys
- can be added using this API to created arbitrary PKCS#12
- files while avoiding the low level API.
-
- New options to PKCS12_create(), key or cert can be NULL and
- will then be omitted from the output file. The encryption
- algorithm NIDs can be set to -1 for no encryption, the mac
- iteration count can be set to 0 to omit the mac.
-
- Enhance pkcs12 utility by making the -nokeys and -nocerts
- options work when creating a PKCS#12 file. New option -nomac
- to omit the mac, NONE can be set for an encryption algorithm.
- New code is modified to use the enhanced PKCS12_create()
- instead of the low level API.
- [Steve Henson]
-
- *) Extend ASN1 encoder to support indefinite length constructed
- encoding. This can output sequences tags and octet strings in
- this form. Modify pk7_asn1.c to support indefinite length
- encoding. This is experimental and needs additional code to
- be useful, such as an ASN1 bio and some enhanced streaming
- PKCS#7 code.
-
- Extend template encode functionality so that tagging is passed
- down to the template encoder.
- [Steve Henson]
-
- *) Let 'openssl req' fail if an argument to '-newkey' is not
- recognized instead of using RSA as a default.
- [Bodo Moeller]
-
- *) Add support for ECC-based ciphersuites from draft-ietf-tls-ecc-01.txt.
- As these are not official, they are not included in "ALL";
- the "ECCdraft" ciphersuite group alias can be used to select them.
- [Vipul Gupta and Sumit Gupta (Sun Microsystems Laboratories)]
-
- *) Add ECDH engine support.
- [Nils Gura and Douglas Stebila (Sun Microsystems Laboratories)]
-
- *) Add ECDH in new directory crypto/ecdh/.
- [Douglas Stebila (Sun Microsystems Laboratories)]
-
- *) Let BN_rand_range() abort with an error after 100 iterations
- without success (which indicates a broken PRNG).
- [Bodo Moeller]
-
- *) Change BN_mod_sqrt() so that it verifies that the input value
- is really the square of the return value. (Previously,
- BN_mod_sqrt would show GIGO behaviour.)
- [Bodo Moeller]
-
- *) Add named elliptic curves over binary fields from X9.62, SECG,
- and WAP/WTLS; add OIDs that were still missing.
-
- [Sheueling Chang Shantz and Douglas Stebila
- (Sun Microsystems Laboratories)]
-
- *) Extend the EC library for elliptic curves over binary fields
- (new files ec2_smpl.c, ec2_smpt.c, ec2_mult.c in crypto/ec/).
- New EC_METHOD:
-
- EC_GF2m_simple_method
-
- New API functions:
-
- EC_GROUP_new_curve_GF2m
- EC_GROUP_set_curve_GF2m
- EC_GROUP_get_curve_GF2m
- EC_POINT_set_affine_coordinates_GF2m
- EC_POINT_get_affine_coordinates_GF2m
- EC_POINT_set_compressed_coordinates_GF2m
-
- Point compression for binary fields is disabled by default for
- patent reasons (compile with OPENSSL_EC_BIN_PT_COMP defined to
- enable it).
-
- As binary polynomials are represented as BIGNUMs, various members
- of the EC_GROUP and EC_POINT data structures can be shared
- between the implementations for prime fields and binary fields;
- the above ..._GF2m functions (except for EX_GROUP_new_curve_GF2m)
- are essentially identical to their ..._GFp counterparts.
- (For simplicity, the '..._GFp' prefix has been dropped from
- various internal method names.)
-
- An internal 'field_div' method (similar to 'field_mul' and
- 'field_sqr') has been added; this is used only for binary fields.
-
- [Sheueling Chang Shantz and Douglas Stebila
- (Sun Microsystems Laboratories)]
-
- *) Optionally dispatch EC_POINT_mul(), EC_POINT_precompute_mult()
- through methods ('mul', 'precompute_mult').
-
- The generic implementations (now internally called 'ec_wNAF_mul'
- and 'ec_wNAF_precomputed_mult') remain the default if these
- methods are undefined.
-
- [Sheueling Chang Shantz and Douglas Stebila
- (Sun Microsystems Laboratories)]
-
- *) New function EC_GROUP_get_degree, which is defined through
- EC_METHOD. For curves over prime fields, this returns the bit
- length of the modulus.
-
- [Sheueling Chang Shantz and Douglas Stebila
- (Sun Microsystems Laboratories)]
-
- *) New functions EC_GROUP_dup, EC_POINT_dup.
- (These simply call ..._new and ..._copy).
-
- [Sheueling Chang Shantz and Douglas Stebila
- (Sun Microsystems Laboratories)]
-
- *) Add binary polynomial arithmetic software in crypto/bn/bn_gf2m.c.
- Polynomials are represented as BIGNUMs (where the sign bit is not
- used) in the following functions [macros]:
-
- BN_GF2m_add
- BN_GF2m_sub [= BN_GF2m_add]
- BN_GF2m_mod [wrapper for BN_GF2m_mod_arr]
- BN_GF2m_mod_mul [wrapper for BN_GF2m_mod_mul_arr]
- BN_GF2m_mod_sqr [wrapper for BN_GF2m_mod_sqr_arr]
- BN_GF2m_mod_inv
- BN_GF2m_mod_exp [wrapper for BN_GF2m_mod_exp_arr]
- BN_GF2m_mod_sqrt [wrapper for BN_GF2m_mod_sqrt_arr]
- BN_GF2m_mod_solve_quad [wrapper for BN_GF2m_mod_solve_quad_arr]
- BN_GF2m_cmp [= BN_ucmp]
-
- (Note that only the 'mod' functions are actually for fields GF(2^m).
- BN_GF2m_add() is misnomer, but this is for the sake of consistency.)
-
- For some functions, an the irreducible polynomial defining a
- field can be given as an 'unsigned int[]' with strictly
- decreasing elements giving the indices of those bits that are set;
- i.e., p[] represents the polynomial
- f(t) = t^p[0] + t^p[1] + ... + t^p[k]
- where
- p[0] > p[1] > ... > p[k] = 0.
- This applies to the following functions:
-
- BN_GF2m_mod_arr
- BN_GF2m_mod_mul_arr
- BN_GF2m_mod_sqr_arr
- BN_GF2m_mod_inv_arr [wrapper for BN_GF2m_mod_inv]
- BN_GF2m_mod_div_arr [wrapper for BN_GF2m_mod_div]
- BN_GF2m_mod_exp_arr
- BN_GF2m_mod_sqrt_arr
- BN_GF2m_mod_solve_quad_arr
- BN_GF2m_poly2arr
- BN_GF2m_arr2poly
-
- Conversion can be performed by the following functions:
-
- BN_GF2m_poly2arr
- BN_GF2m_arr2poly
-
- bntest.c has additional tests for binary polynomial arithmetic.
-
- Two implementations for BN_GF2m_mod_div() are available.
- The default algorithm simply uses BN_GF2m_mod_inv() and
- BN_GF2m_mod_mul(). The alternative algorithm is compiled in only
- if OPENSSL_SUN_GF2M_DIV is defined (patent pending; read the
- copyright notice in crypto/bn/bn_gf2m.c before enabling it).
-
- [Sheueling Chang Shantz and Douglas Stebila
- (Sun Microsystems Laboratories)]
-
- *) Add new error code 'ERR_R_DISABLED' that can be used when some
- functionality is disabled at compile-time.
- [Douglas Stebila <douglas.stebila@sun.com>]
-
- *) Change default behaviour of 'openssl asn1parse' so that more
- information is visible when viewing, e.g., a certificate:
-
- Modify asn1_parse2 (crypto/asn1/asn1_par.c) so that in non-'dump'
- mode the content of non-printable OCTET STRINGs is output in a
- style similar to INTEGERs, but with '[HEX DUMP]' prepended to
- avoid the appearance of a printable string.
- [Nils Larsch <nla@trustcenter.de>]
-
- *) Add 'asn1_flag' and 'asn1_form' member to EC_GROUP with access
- functions
- EC_GROUP_set_asn1_flag()
- EC_GROUP_get_asn1_flag()
- EC_GROUP_set_point_conversion_form()
- EC_GROUP_get_point_conversion_form()
- These control ASN1 encoding details:
- - Curves (i.e., groups) are encoded explicitly unless asn1_flag
- has been set to OPENSSL_EC_NAMED_CURVE.
- - Points are encoded in uncompressed form by default; options for
- asn1_for are as for point2oct, namely
- POINT_CONVERSION_COMPRESSED
- POINT_CONVERSION_UNCOMPRESSED
- POINT_CONVERSION_HYBRID
-
- Also add 'seed' and 'seed_len' members to EC_GROUP with access
- functions
- EC_GROUP_set_seed()
- EC_GROUP_get0_seed()
- EC_GROUP_get_seed_len()
- This is used only for ASN1 purposes (so far).
- [Nils Larsch <nla@trustcenter.de>]
-
- *) Add 'field_type' member to EC_METHOD, which holds the NID
- of the appropriate field type OID. The new function
- EC_METHOD_get_field_type() returns this value.
- [Nils Larsch <nla@trustcenter.de>]
-
- *) Add functions
- EC_POINT_point2bn()
- EC_POINT_bn2point()
- EC_POINT_point2hex()
- EC_POINT_hex2point()
- providing useful interfaces to EC_POINT_point2oct() and
- EC_POINT_oct2point().
- [Nils Larsch <nla@trustcenter.de>]
-
- *) Change internals of the EC library so that the functions
- EC_GROUP_set_generator()
- EC_GROUP_get_generator()
- EC_GROUP_get_order()
- EC_GROUP_get_cofactor()
- are implemented directly in crypto/ec/ec_lib.c and not dispatched
- to methods, which would lead to unnecessary code duplication when
- adding different types of curves.
- [Nils Larsch <nla@trustcenter.de> with input by Bodo Moeller]
-
- *) Implement compute_wNAF (crypto/ec/ec_mult.c) without BIGNUM
- arithmetic, and such that modified wNAFs are generated
- (which avoid length expansion in many cases).
- [Bodo Moeller]
-
- *) Add a function EC_GROUP_check_discriminant() (defined via
- EC_METHOD) that verifies that the curve discriminant is non-zero.
-
- Add a function EC_GROUP_check() that makes some sanity tests
- on a EC_GROUP, its generator and order. This includes
- EC_GROUP_check_discriminant().
- [Nils Larsch <nla@trustcenter.de>]
-
- *) Add ECDSA in new directory crypto/ecdsa/.
-
- Add applications 'openssl ecparam' and 'openssl ecdsa'
- (these are based on 'openssl dsaparam' and 'openssl dsa').
-
- ECDSA support is also included in various other files across the
- library. Most notably,
- - 'openssl req' now has a '-newkey ecdsa:file' option;
- - EVP_PKCS82PKEY (crypto/evp/evp_pkey.c) now can handle ECDSA;
- - X509_PUBKEY_get (crypto/asn1/x_pubkey.c) and
- d2i_PublicKey (crypto/asn1/d2i_pu.c) have been modified to make
- them suitable for ECDSA where domain parameters must be
- extracted before the specific public key;
- - ECDSA engine support has been added.
- [Nils Larsch <nla@trustcenter.de>]
-
- *) Include some named elliptic curves, and add OIDs from X9.62,
- SECG, and WAP/WTLS. Each curve can be obtained from the new
- function
- EC_GROUP_new_by_curve_name(),
- and the list of available named curves can be obtained with
- EC_get_builtin_curves().
- Also add a 'curve_name' member to EC_GROUP objects, which can be
- accessed via
- EC_GROUP_set_curve_name()
- EC_GROUP_get_curve_name()
- [Nils Larsch <larsch@trustcenter.de, Bodo Moeller]
-
- *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there
- was actually never needed) and in BN_mul(). The removal in BN_mul()
- required a small change in bn_mul_part_recursive() and the addition
- of the functions bn_cmp_part_words(), bn_sub_part_words() and
- bn_add_part_words(), which do the same thing as bn_cmp_words(),
- bn_sub_words() and bn_add_words() except they take arrays with
- differing sizes.
- [Richard Levitte]
-
- Changes between 0.9.7l and 0.9.7m [23 Feb 2007]
-
- *) Cleanse PEM buffers before freeing them since they may contain
- sensitive data.
- [Benjamin Bennett <ben@psc.edu>]
-
- *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
- a ciphersuite string such as "DEFAULT:RSA" cannot enable
- authentication-only ciphersuites.
- [Bodo Moeller]
-
- *) Since AES128 and AES256 share a single mask bit in the logic of
- ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
- kludge to work properly if AES128 is available and AES256 isn't.
- [Victor Duchovni]
-
- *) Expand security boundary to match 1.1.1 module.
- [Steve Henson]
-
- *) Remove redundant features: hash file source, editing of test vectors
- modify fipsld to use external fips_premain.c signature.
- [Steve Henson]
-
- *) New perl script mkfipsscr.pl to create shell scripts or batch files to
- run algorithm test programs.
- [Steve Henson]
-
- *) Make algorithm test programs more tolerant of whitespace.
- [Steve Henson]
-
- *) Have SSL/TLS server implementation tolerate "mismatched" record
- protocol version while receiving ClientHello even if the
- ClientHello is fragmented. (The server can't insist on the
- particular protocol version it has chosen before the ServerHello
- message has informed the client about his choice.)
- [Bodo Moeller]
-
- *) Load error codes if they are not already present instead of using a
- static variable. This allows them to be cleanly unloaded and reloaded.
- [Steve Henson]
-
- Changes between 0.9.7k and 0.9.7l [28 Sep 2006]
-
- *) Introduce limits to prevent malicious keys being able to
- cause a denial of service. (CVE-2006-2940)
- [Steve Henson, Bodo Moeller]
-
- *) Fix ASN.1 parsing of certain invalid structures that can result
- in a denial of service. (CVE-2006-2937) [Steve Henson]
-
- *) Fix buffer overflow in SSL_get_shared_ciphers() function.
- (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team]
-
- *) Fix SSL client code which could crash if connecting to a
- malicious SSLv2 server. (CVE-2006-4343)
- [Tavis Ormandy and Will Drewry, Google Security Team]
-
- *) Change ciphersuite string processing so that an explicit
- ciphersuite selects this one ciphersuite (so that "AES256-SHA"
- will no longer include "AES128-SHA"), and any other similar
- ciphersuite (same bitmap) from *other* protocol versions (so that
- "RC4-MD5" will still include both the SSL 2.0 ciphersuite and the
- SSL 3.0/TLS 1.0 ciphersuite). This is a backport combining
- changes from 0.9.8b and 0.9.8d.
- [Bodo Moeller]
-
- Changes between 0.9.7j and 0.9.7k [05 Sep 2006]
-
- *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher
- (CVE-2006-4339) [Ben Laurie and Google Security Team]
-
- *) Change the Unix randomness entropy gathering to use poll() when
- possible instead of select(), since the latter has some
- undesirable limitations.
- [Darryl Miles via Richard Levitte and Bodo Moeller]
-
- *) Disable rogue ciphersuites:
-
- - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5")
- - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5")
- - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5")
-
- The latter two were purportedly from
- draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really
- appear there.
-
- Also deactive the remaining ciphersuites from
- draft-ietf-tls-56-bit-ciphersuites-01.txt. These are just as
- unofficial, and the ID has long expired.
- [Bodo Moeller]
-
- *) Fix RSA blinding Heisenbug (problems sometimes occured on
- dual-core machines) and other potential thread-safety issues.
- [Bodo Moeller]
-
- Changes between 0.9.7i and 0.9.7j [04 May 2006]
-
- *) Adapt fipsld and the build system to link against the validated FIPS
- module in FIPS mode.
- [Steve Henson]
-
- *) Fixes for VC++ 2005 build under Windows.
- [Steve Henson]
-
- *) Add new Windows build target VC-32-GMAKE for VC++. This uses GNU make
- from a Windows bash shell such as MSYS. It is autodetected from the
- "config" script when run from a VC++ environment. Modify standard VC++
- build to use fipscanister.o from the GNU make build.
- [Steve Henson]
-
- Changes between 0.9.7h and 0.9.7i [14 Oct 2005]
-
- *) Wrapped the definition of EVP_MAX_MD_SIZE in a #ifdef OPENSSL_FIPS.
- The value now differs depending on if you build for FIPS or not.
- BEWARE! A program linked with a shared FIPSed libcrypto can't be
- safely run with a non-FIPSed libcrypto, as it may crash because of
- the difference induced by this change.
- [Andy Polyakov]
-
- Changes between 0.9.7g and 0.9.7h [11 Oct 2005]
-
- *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING
- (part of SSL_OP_ALL). This option used to disable the
- countermeasure against man-in-the-middle protocol-version
- rollback in the SSL 2.0 server implementation, which is a bad
- idea. (CVE-2005-2969)
-
- [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center
- for Information Security, National Institute of Advanced Industrial
- Science and Technology [AIST], Japan)]
-
- *) Minimal support for X9.31 signatures and PSS padding modes. This is
- mainly for FIPS compliance and not fully integrated at this stage.
- [Steve Henson]
-
- *) For DSA signing, unless DSA_FLAG_NO_EXP_CONSTTIME is set, perform
- the exponentiation using a fixed-length exponent. (Otherwise,
- the information leaked through timing could expose the secret key
- after many signatures; cf. Bleichenbacher's attack on DSA with
- biased k.)
- [Bodo Moeller]
-
- *) Make a new fixed-window mod_exp implementation the default for
- RSA, DSA, and DH private-key operations so that the sequence of
- squares and multiplies and the memory access pattern are
- independent of the particular secret key. This will mitigate
- cache-timing and potential related attacks.
-
- BN_mod_exp_mont_consttime() is the new exponentiation implementation,
- and this is automatically used by BN_mod_exp_mont() if the new flag
- BN_FLG_EXP_CONSTTIME is set for the exponent. RSA, DSA, and DH
- will use this BN flag for private exponents unless the flag
- RSA_FLAG_NO_EXP_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME, or
- DH_FLAG_NO_EXP_CONSTTIME, respectively, is set.
-
- [Matthew D Wood (Intel Corp), with some changes by Bodo Moeller]
-
- *) Change the client implementation for SSLv23_method() and
- SSLv23_client_method() so that is uses the SSL 3.0/TLS 1.0
- Client Hello message format if the SSL_OP_NO_SSLv2 option is set.
- (Previously, the SSL 2.0 backwards compatible Client Hello
- message format would be used even with SSL_OP_NO_SSLv2.)
- [Bodo Moeller]
-
- *) Add support for smime-type MIME parameter in S/MIME messages which some
- clients need.
- [Steve Henson]
-
- *) New function BN_MONT_CTX_set_locked() to set montgomery parameters in
- a threadsafe manner. Modify rsa code to use new function and add calls
- to dsa and dh code (which had race conditions before).
- [Steve Henson]
-
- *) Include the fixed error library code in the C error file definitions
- instead of fixing them up at runtime. This keeps the error code
- structures constant.
- [Steve Henson]
-
- Changes between 0.9.7f and 0.9.7g [11 Apr 2005]
-
- [NB: OpenSSL 0.9.7h and later 0.9.7 patch levels were released after
- OpenSSL 0.9.8.]
-
- *) Fixes for newer kerberos headers. NB: the casts are needed because
- the 'length' field is signed on one version and unsigned on another
- with no (?) obvious way to tell the difference, without these VC++
- complains. Also the "definition" of FAR (blank) is no longer included
- nor is the error ENOMEM. KRB5_PRIVATE has to be set to 1 to pick up
- some needed definitions.
- [Steve Henson]
-
- *) Undo Cygwin change.
- [Ulf Möller]
-
- *) Added support for proxy certificates according to RFC 3820.
- Because they may be a security thread to unaware applications,
- they must be explicitely allowed in run-time. See
- docs/HOWTO/proxy_certificates.txt for further information.
- [Richard Levitte]
-
- Changes between 0.9.7e and 0.9.7f [22 Mar 2005]
-
- *) Use (SSL_RANDOM_VALUE - 4) bytes of pseudo random data when generating
- server and client random values. Previously
- (SSL_RANDOM_VALUE - sizeof(time_t)) would be used which would result in
- less random data when sizeof(time_t) > 4 (some 64 bit platforms).
-
- This change has negligible security impact because:
-
- 1. Server and client random values still have 24 bytes of pseudo random
- data.
-
- 2. Server and client random values are sent in the clear in the initial
- handshake.
-
- 3. The master secret is derived using the premaster secret (48 bytes in
- size for static RSA ciphersuites) as well as client server and random
- values.
-
- The OpenSSL team would like to thank the UK NISCC for bringing this issue
- to our attention.
-
- [Stephen Henson, reported by UK NISCC]
-
- *) Use Windows randomness collection on Cygwin.
- [Ulf Möller]
-
- *) Fix hang in EGD/PRNGD query when communication socket is closed
- prematurely by EGD/PRNGD.
- [Darren Tucker <dtucker@zip.com.au> via Lutz Jänicke, resolves #1014]
-
- *) Prompt for pass phrases when appropriate for PKCS12 input format.
- [Steve Henson]
-
- *) Back-port of selected performance improvements from development
- branch, as well as improved support for PowerPC platforms.
- [Andy Polyakov]
-
- *) Add lots of checks for memory allocation failure, error codes to indicate
- failure and freeing up memory if a failure occurs.
- [Nauticus Networks SSL Team <openssl@nauticusnet.com>, Steve Henson]
-
- *) Add new -passin argument to dgst.
- [Steve Henson]
-
- *) Perform some character comparisons of different types in X509_NAME_cmp:
- this is needed for some certificates that reencode DNs into UTF8Strings
- (in violation of RFC3280) and can't or wont issue name rollover
- certificates.
- [Steve Henson]
-
- *) Make an explicit check during certificate validation to see that
- the CA setting in each certificate on the chain is correct. As a
- side effect always do the following basic checks on extensions,
- not just when there's an associated purpose to the check:
-
- - if there is an unhandled critical extension (unless the user
- has chosen to ignore this fault)
- - if the path length has been exceeded (if one is set at all)
- - that certain extensions fit the associated purpose (if one has
- been given)
- [Richard Levitte]
-
- Changes between 0.9.7d and 0.9.7e [25 Oct 2004]
-
- *) Avoid a race condition when CRLs are checked in a multi threaded
- environment. This would happen due to the reordering of the revoked
- entries during signature checking and serial number lookup. Now the
- encoding is cached and the serial number sort performed under a lock.
- Add new STACK function sk_is_sorted().
- [Steve Henson]
-
- *) Add Delta CRL to the extension code.
- [Steve Henson]
-
- *) Various fixes to s3_pkt.c so alerts are sent properly.
- [David Holmes <d.holmes@f5.com>]
-
- *) Reduce the chances of duplicate issuer name and serial numbers (in
- violation of RFC3280) using the OpenSSL certificate creation utilities.
- This is done by creating a random 64 bit value for the initial serial
- number when a serial number file is created or when a self signed
- certificate is created using 'openssl req -x509'. The initial serial
- number file is created using 'openssl x509 -next_serial' in CA.pl
- rather than being initialized to 1.
- [Steve Henson]
-
- Changes between 0.9.7c and 0.9.7d [17 Mar 2004]
-
- *) Fix null-pointer assignment in do_change_cipher_spec() revealed
- by using the Codenomicon TLS Test Tool (CVE-2004-0079)
- [Joe Orton, Steve Henson]
-
- *) Fix flaw in SSL/TLS handshaking when using Kerberos ciphersuites
- (CVE-2004-0112)
- [Joe Orton, Steve Henson]
-
- *) Make it possible to have multiple active certificates with the same
- subject in the CA index file. This is done only if the keyword
- 'unique_subject' is set to 'no' in the main CA section (default
- if 'CA_default') of the configuration file. The value is saved
- with the database itself in a separate index attribute file,
- named like the index file with '.attr' appended to the name.
- [Richard Levitte]
-
- *) X509 verify fixes. Disable broken certificate workarounds when
- X509_V_FLAGS_X509_STRICT is set. Check CRL issuer has cRLSign set if
- keyUsage extension present. Don't accept CRLs with unhandled critical
- extensions: since verify currently doesn't process CRL extensions this
- rejects a CRL with *any* critical extensions. Add new verify error codes
- for these cases.
- [Steve Henson]
-
- *) When creating an OCSP nonce use an OCTET STRING inside the extnValue.
- A clarification of RFC2560 will require the use of OCTET STRINGs and
- some implementations cannot handle the current raw format. Since OpenSSL
- copies and compares OCSP nonces as opaque blobs without any attempt at
- parsing them this should not create any compatibility issues.
- [Steve Henson]
-
- *) New md flag EVP_MD_CTX_FLAG_REUSE this allows md_data to be reused when
- calling EVP_MD_CTX_copy_ex() to avoid calling OPENSSL_malloc(). Without
- this HMAC (and other) operations are several times slower than OpenSSL
- < 0.9.7.
- [Steve Henson]
-
- *) Print out GeneralizedTime and UTCTime in ASN1_STRING_print_ex().
- [Peter Sylvester <Peter.Sylvester@EdelWeb.fr>]
-
- *) Use the correct content when signing type "other".
- [Steve Henson]
-
- Changes between 0.9.7b and 0.9.7c [30 Sep 2003]
-
- *) Fix various bugs revealed by running the NISCC test suite:
-
- Stop out of bounds reads in the ASN1 code when presented with
- invalid tags (CVE-2003-0543 and CVE-2003-0544).
-
- Free up ASN1_TYPE correctly if ANY type is invalid (CVE-2003-0545).
-
- If verify callback ignores invalid public key errors don't try to check
- certificate signature with the NULL public key.
-
- [Steve Henson]
-
- *) New -ignore_err option in ocsp application to stop the server
- exiting on the first error in a request.
- [Steve Henson]
-
- *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate
- if the server requested one: as stated in TLS 1.0 and SSL 3.0
- specifications.
- [Steve Henson]
-
- *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional
- extra data after the compression methods not only for TLS 1.0
- but also for SSL 3.0 (as required by the specification).
- [Bodo Moeller; problem pointed out by Matthias Loepfe]
-
- *) Change X509_certificate_type() to mark the key as exported/exportable
- when it's 512 *bits* long, not 512 bytes.
- [Richard Levitte]
-
- *) Change AES_cbc_encrypt() so it outputs exact multiple of
- blocks during encryption.
- [Richard Levitte]
-
- *) Various fixes to base64 BIO and non blocking I/O. On write
- flushes were not handled properly if the BIO retried. On read
- data was not being buffered properly and had various logic bugs.
- This also affects blocking I/O when the data being decoded is a
- certain size.
- [Steve Henson]
-
- *) Various S/MIME bugfixes and compatibility changes:
- output correct application/pkcs7 MIME type if
- PKCS7_NOOLDMIMETYPE is set. Tolerate some broken signatures.
- Output CR+LF for EOL if PKCS7_CRLFEOL is set (this makes opening
- of files as .eml work). Correctly handle very long lines in MIME
- parser.
- [Steve Henson]
-
- Changes between 0.9.7a and 0.9.7b [10 Apr 2003]
-
- *) Countermeasure against the Klima-Pokorny-Rosa extension of
- Bleichbacher's attack on PKCS #1 v1.5 padding: treat
- a protocol version number mismatch like a decryption error
- in ssl3_get_client_key_exchange (ssl/s3_srvr.c).
- [Bodo Moeller]
-
- *) Turn on RSA blinding by default in the default implementation
- to avoid a timing attack. Applications that don't want it can call
- RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING.
- They would be ill-advised to do so in most cases.
- [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller]
-
- *) Change RSA blinding code so that it works when the PRNG is not
- seeded (in this case, the secret RSA exponent is abused as
- an unpredictable seed -- if it is not unpredictable, there
- is no point in blinding anyway). Make RSA blinding thread-safe
- by remembering the creator's thread ID in rsa->blinding and
- having all other threads use local one-time blinding factors
- (this requires more computation than sharing rsa->blinding, but
- avoids excessive locking; and if an RSA object is not shared
- between threads, blinding will still be very fast).
- [Bodo Moeller]
-
- *) Fixed a typo bug that would cause ENGINE_set_default() to set an
- ENGINE as defaults for all supported algorithms irrespective of
- the 'flags' parameter. 'flags' is now honoured, so applications
- should make sure they are passing it correctly.
- [Geoff Thorpe]
-
- *) Target "mingw" now allows native Windows code to be generated in
- the Cygwin environment as well as with the MinGW compiler.
- [Ulf Moeller]
-
- Changes between 0.9.7 and 0.9.7a [19 Feb 2003]
-
- *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked
- via timing by performing a MAC computation even if incorrrect
- block cipher padding has been found. This is a countermeasure
- against active attacks where the attacker has to distinguish
- between bad padding and a MAC verification error. (CVE-2003-0078)
-
- [Bodo Moeller; problem pointed out by Brice Canvel (EPFL),
- Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and
- Martin Vuagnoux (EPFL, Ilion)]
-
- *) Make the no-err option work as intended. The intention with no-err
- is not to have the whole error stack handling routines removed from
- libcrypto, it's only intended to remove all the function name and
- reason texts, thereby removing some of the footprint that may not
- be interesting if those errors aren't displayed anyway.
-
- NOTE: it's still possible for any application or module to have it's
- own set of error texts inserted. The routines are there, just not
- used by default when no-err is given.
- [Richard Levitte]
-
- *) Add support for FreeBSD on IA64.
- [dirk.meyer@dinoex.sub.org via Richard Levitte, resolves #454]
-
- *) Adjust DES_cbc_cksum() so it returns the same value as the MIT
- Kerberos function mit_des_cbc_cksum(). Before this change,
- the value returned by DES_cbc_cksum() was like the one from
- mit_des_cbc_cksum(), except the bytes were swapped.
- [Kevin Greaney <Kevin.Greaney@hp.com> and Richard Levitte]
-
- *) Allow an application to disable the automatic SSL chain building.
- Before this a rather primitive chain build was always performed in
- ssl3_output_cert_chain(): an application had no way to send the
- correct chain if the automatic operation produced an incorrect result.
-
- Now the chain builder is disabled if either:
-
- 1. Extra certificates are added via SSL_CTX_add_extra_chain_cert().
-
- 2. The mode flag SSL_MODE_NO_AUTO_CHAIN is set.
-
- The reasoning behind this is that an application would not want the
- auto chain building to take place if extra chain certificates are
- present and it might also want a means of sending no additional
- certificates (for example the chain has two certificates and the
- root is omitted).
- [Steve Henson]
-
- *) Add the possibility to build without the ENGINE framework.
- [Steven Reddie <smr@essemer.com.au> via Richard Levitte]
-
- *) Under Win32 gmtime() can return NULL: check return value in
- OPENSSL_gmtime(). Add error code for case where gmtime() fails.
- [Steve Henson]
-
- *) DSA routines: under certain error conditions uninitialized BN objects
- could be freed. Solution: make sure initialization is performed early
- enough. (Reported and fix supplied by Ivan D Nestlerode <nestler@MIT.EDU>,
- Nils Larsch <nla@trustcenter.de> via PR#459)
- [Lutz Jaenicke]
-
- *) Another fix for SSLv2 session ID handling: the session ID was incorrectly
- checked on reconnect on the client side, therefore session resumption
- could still fail with a "ssl session id is different" error. This
- behaviour is masked when SSL_OP_ALL is used due to
- SSL_OP_MICROSOFT_SESS_ID_BUG being set.
- Behaviour observed by Crispin Flowerday <crispin@flowerday.cx> as
- followup to PR #377.
- [Lutz Jaenicke]
-
- *) IA-32 assembler support enhancements: unified ELF targets, support
- for SCO/Caldera platforms, fix for Cygwin shared build.
- [Andy Polyakov]
-
- *) Add support for FreeBSD on sparc64. As a consequence, support for
- FreeBSD on non-x86 processors is separate from x86 processors on
- the config script, much like the NetBSD support.
- [Richard Levitte & Kris Kennaway <kris@obsecurity.org>]
-
- Changes between 0.9.6h and 0.9.7 [31 Dec 2002]
-
- [NB: OpenSSL 0.9.6i and later 0.9.6 patch levels were released after
- OpenSSL 0.9.7.]
-
- *) Fix session ID handling in SSLv2 client code: the SERVER FINISHED
- code (06) was taken as the first octet of the session ID and the last
- octet was ignored consequently. As a result SSLv2 client side session
- caching could not have worked due to the session ID mismatch between
- client and server.
- Behaviour observed by Crispin Flowerday <crispin@flowerday.cx> as
- PR #377.
- [Lutz Jaenicke]
-
- *) Change the declaration of needed Kerberos libraries to use EX_LIBS
- instead of the special (and badly supported) LIBKRB5. LIBKRB5 is
- removed entirely.
- [Richard Levitte]
-
- *) The hw_ncipher.c engine requires dynamic locks. Unfortunately, it
- seems that in spite of existing for more than a year, many application
- author have done nothing to provide the necessary callbacks, which
- means that this particular engine will not work properly anywhere.
- This is a very unfortunate situation which forces us, in the name
- of usability, to give the hw_ncipher.c a static lock, which is part
- of libcrypto.
- NOTE: This is for the 0.9.7 series ONLY. This hack will never
- appear in 0.9.8 or later. We EXPECT application authors to have
- dealt properly with this when 0.9.8 is released (unless we actually
- make such changes in the libcrypto locking code that changes will
- have to be made anyway).
- [Richard Levitte]
-
- *) In asn1_d2i_read_bio() repeatedly call BIO_read() until all content
- octets have been read, EOF or an error occurs. Without this change
- some truncated ASN1 structures will not produce an error.
- [Steve Henson]
-
- *) Disable Heimdal support, since it hasn't been fully implemented.
- Still give the possibility to force the use of Heimdal, but with
- warnings and a request that patches get sent to openssl-dev.
- [Richard Levitte]
-
- *) Add the VC-CE target, introduce the WINCE sysname, and add
- INSTALL.WCE and appropriate conditionals to make it build.
- [Steven Reddie <smr@essemer.com.au> via Richard Levitte]
-
- *) Change the DLL names for Cygwin to cygcrypto-x.y.z.dll and
- cygssl-x.y.z.dll, where x, y and z are the major, minor and
- edit numbers of the version.
- [Corinna Vinschen <vinschen@redhat.com> and Richard Levitte]
-
- *) Introduce safe string copy and catenation functions
- (BUF_strlcpy() and BUF_strlcat()).
- [Ben Laurie (CHATS) and Richard Levitte]
-
- *) Avoid using fixed-size buffers for one-line DNs.
- [Ben Laurie (CHATS)]
-
- *) Add BUF_MEM_grow_clean() to avoid information leakage when
- resizing buffers containing secrets, and use where appropriate.
- [Ben Laurie (CHATS)]
-
- *) Avoid using fixed size buffers for configuration file location.
- [Ben Laurie (CHATS)]
-
- *) Avoid filename truncation for various CA files.
- [Ben Laurie (CHATS)]
-
- *) Use sizeof in preference to magic numbers.
- [Ben Laurie (CHATS)]
-
- *) Avoid filename truncation in cert requests.
- [Ben Laurie (CHATS)]
-
- *) Add assertions to check for (supposedly impossible) buffer
- overflows.
- [Ben Laurie (CHATS)]
-
- *) Don't cache truncated DNS entries in the local cache (this could
- potentially lead to a spoofing attack).
- [Ben Laurie (CHATS)]
-
- *) Fix various buffers to be large enough for hex/decimal
- representations in a platform independent manner.
- [Ben Laurie (CHATS)]
-
- *) Add CRYPTO_realloc_clean() to avoid information leakage when
- resizing buffers containing secrets, and use where appropriate.
- [Ben Laurie (CHATS)]
-
- *) Add BIO_indent() to avoid much slightly worrying code to do
- indents.
- [Ben Laurie (CHATS)]
-
- *) Convert sprintf()/BIO_puts() to BIO_printf().
- [Ben Laurie (CHATS)]
-
- *) buffer_gets() could terminate with the buffer only half
- full. Fixed.
- [Ben Laurie (CHATS)]
-
- *) Add assertions to prevent user-supplied crypto functions from
- overflowing internal buffers by having large block sizes, etc.
- [Ben Laurie (CHATS)]
-
- *) New OPENSSL_assert() macro (similar to assert(), but enabled
- unconditionally).
- [Ben Laurie (CHATS)]
-
- *) Eliminate unused copy of key in RC4.
- [Ben Laurie (CHATS)]
-
- *) Eliminate unused and incorrectly sized buffers for IV in pem.h.
- [Ben Laurie (CHATS)]
-
- *) Fix off-by-one error in EGD path.
- [Ben Laurie (CHATS)]
-
- *) If RANDFILE path is too long, ignore instead of truncating.
- [Ben Laurie (CHATS)]
-
- *) Eliminate unused and incorrectly sized X.509 structure
- CBCParameter.
- [Ben Laurie (CHATS)]
-
- *) Eliminate unused and dangerous function knumber().
- [Ben Laurie (CHATS)]
-
- *) Eliminate unused and dangerous structure, KSSL_ERR.
- [Ben Laurie (CHATS)]
-
- *) Protect against overlong session ID context length in an encoded
- session object. Since these are local, this does not appear to be
- exploitable.
- [Ben Laurie (CHATS)]
-
- *) Change from security patch (see 0.9.6e below) that did not affect
- the 0.9.6 release series:
-
- Remote buffer overflow in SSL3 protocol - an attacker could
- supply an oversized master key in Kerberos-enabled versions.
- (CVE-2002-0657)
- [Ben Laurie (CHATS)]
-
- *) Change the SSL kerb5 codes to match RFC 2712.
- [Richard Levitte]
-
- *) Make -nameopt work fully for req and add -reqopt switch.
- [Michael Bell <michael.bell@rz.hu-berlin.de>, Steve Henson]
-
- *) The "block size" for block ciphers in CFB and OFB mode should be 1.
- [Steve Henson, reported by Yngve Nysaeter Pettersen <yngve@opera.com>]
-
- *) Make sure tests can be performed even if the corresponding algorithms
- have been removed entirely. This was also the last step to make
- OpenSSL compilable with DJGPP under all reasonable conditions.
- [Richard Levitte, Doug Kaufman <dkaufman@rahul.net>]
-
- *) Add cipher selection rules COMPLEMENTOFALL and COMPLEMENTOFDEFAULT
- to allow version independent disabling of normally unselected ciphers,
- which may be activated as a side-effect of selecting a single cipher.
-
- (E.g., cipher list string "RSA" enables ciphersuites that are left
- out of "ALL" because they do not provide symmetric encryption.
- "RSA:!COMPLEMEMENTOFALL" avoids these unsafe ciphersuites.)
- [Lutz Jaenicke, Bodo Moeller]
-
- *) Add appropriate support for separate platform-dependent build
- directories. The recommended way to make a platform-dependent
- build directory is the following (tested on Linux), maybe with
- some local tweaks:
-
- # Place yourself outside of the OpenSSL source tree. In
- # this example, the environment variable OPENSSL_SOURCE
- # is assumed to contain the absolute OpenSSL source directory.
- mkdir -p objtree/"`uname -s`-`uname -r`-`uname -m`"
- cd objtree/"`uname -s`-`uname -r`-`uname -m`"
- (cd $OPENSSL_SOURCE; find . -type f) | while read F; do
- mkdir -p `dirname $F`
- ln -s $OPENSSL_SOURCE/$F $F
- done
-
- To be absolutely sure not to disturb the source tree, a "make clean"
- is a good thing. If it isn't successfull, don't worry about it,
- it probably means the source directory is very clean.
- [Richard Levitte]
-
- *) Make sure any ENGINE control commands make local copies of string
- pointers passed to them whenever necessary. Otherwise it is possible
- the caller may have overwritten (or deallocated) the original string
- data when a later ENGINE operation tries to use the stored values.
- [Götz Babin-Ebell <babinebell@trustcenter.de>]
-
- *) Improve diagnostics in file reading and command-line digests.
- [Ben Laurie aided and abetted by Solar Designer <solar@openwall.com>]
-
- *) Add AES modes CFB and OFB to the object database. Correct an
- error in AES-CFB decryption.
- [Richard Levitte]
-
- *) Remove most calls to EVP_CIPHER_CTX_cleanup() in evp_enc.c, this
- allows existing EVP_CIPHER_CTX structures to be reused after
- calling EVP_*Final(). This behaviour is used by encryption
- BIOs and some applications. This has the side effect that
- applications must explicitly clean up cipher contexts with
- EVP_CIPHER_CTX_cleanup() or they will leak memory.
- [Steve Henson]
-
- *) Check the values of dna and dnb in bn_mul_recursive before calling
- bn_mul_comba (a non zero value means the a or b arrays do not contain
- n2 elements) and fallback to bn_mul_normal if either is not zero.
- [Steve Henson]
-
- *) Fix escaping of non-ASCII characters when using the -subj option
- of the "openssl req" command line tool. (Robert Joop <joop@fokus.gmd.de>)
- [Lutz Jaenicke]
-
- *) Make object definitions compliant to LDAP (RFC2256): SN is the short
- form for "surname", serialNumber has no short form.
- Use "mail" as the short name for "rfc822Mailbox" according to RFC2798;
- therefore remove "mail" short name for "internet 7".
- The OID for unique identifiers in X509 certificates is
- x500UniqueIdentifier, not uniqueIdentifier.
- Some more OID additions. (Michael Bell <michael.bell@rz.hu-berlin.de>)
- [Lutz Jaenicke]
-
- *) Add an "init" command to the ENGINE config module and auto initialize
- ENGINEs. Without any "init" command the ENGINE will be initialized
- after all ctrl commands have been executed on it. If init=1 the
- ENGINE is initailized at that point (ctrls before that point are run
- on the uninitialized ENGINE and after on the initialized one). If
- init=0 then the ENGINE will not be iniatialized at all.
- [Steve Henson]
-
- *) Fix the 'app_verify_callback' interface so that the user-defined
- argument is actually passed to the callback: In the
- SSL_CTX_set_cert_verify_callback() prototype, the callback
- declaration has been changed from
- int (*cb)()
- into
- int (*cb)(X509_STORE_CTX *,void *);
- in ssl_verify_cert_chain (ssl/ssl_cert.c), the call
- i=s->ctx->app_verify_callback(&ctx)
- has been changed into
- i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg).
-
- To update applications using SSL_CTX_set_cert_verify_callback(),
- a dummy argument can be added to their callback functions.
- [D. K. Smetters <smetters@parc.xerox.com>]
-
- *) Added the '4758cca' ENGINE to support IBM 4758 cards.
- [Maurice Gittens <maurice@gittens.nl>, touchups by Geoff Thorpe]
-
- *) Add and OPENSSL_LOAD_CONF define which will cause
- OpenSSL_add_all_algorithms() to load the openssl.cnf config file.
- This allows older applications to transparently support certain
- OpenSSL features: such as crypto acceleration and dynamic ENGINE loading.
- Two new functions OPENSSL_add_all_algorithms_noconf() which will never
- load the config file and OPENSSL_add_all_algorithms_conf() which will
- always load it have also been added.
- [Steve Henson]
-
- *) Add the OFB, CFB and CTR (all with 128 bit feedback) to AES.
- Adjust NIDs and EVP layer.
- [Stephen Sprunk <stephen@sprunk.org> and Richard Levitte]
-
- *) Config modules support in openssl utility.
-
- Most commands now load modules from the config file,
- though in a few (such as version) this isn't done
- because it couldn't be used for anything.
-
- In the case of ca and req the config file used is
- the same as the utility itself: that is the -config
- command line option can be used to specify an
- alternative file.
- [Steve Henson]
-
- *) Move default behaviour from OPENSSL_config(). If appname is NULL
- use "openssl_conf" if filename is NULL use default openssl config file.
- [Steve Henson]
-
- *) Add an argument to OPENSSL_config() to allow the use of an alternative
- config section name. Add a new flag to tolerate a missing config file
- and move code to CONF_modules_load_file().
- [Steve Henson]
-
- *) Support for crypto accelerator cards from Accelerated Encryption
- Processing, www.aep.ie. (Use engine 'aep')
- The support was copied from 0.9.6c [engine] and adapted/corrected
- to work with the new engine framework.
- [AEP Inc. and Richard Levitte]
-
- *) Support for SureWare crypto accelerator cards from Baltimore
- Technologies. (Use engine 'sureware')
- The support was copied from 0.9.6c [engine] and adapted
- to work with the new engine framework.
- [Richard Levitte]
-
- *) Have the CHIL engine fork-safe (as defined by nCipher) and actually
- make the newer ENGINE framework commands for the CHIL engine work.
- [Toomas Kiisk <vix@cyber.ee> and Richard Levitte]
-
- *) Make it possible to produce shared libraries on ReliantUNIX.
- [Robert Dahlem <Robert.Dahlem@ffm2.siemens.de> via Richard Levitte]
-
- *) Add the configuration target debug-linux-ppro.
- Make 'openssl rsa' use the general key loading routines
- implemented in apps.c, and make those routines able to
- handle the key format FORMAT_NETSCAPE and the variant
- FORMAT_IISSGC.
- [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
-
- *) Fix a crashbug and a logic bug in hwcrhk_load_pubkey().
- [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
-
- *) Add -keyform to rsautl, and document -engine.
- [Richard Levitte, inspired by Toomas Kiisk <vix@cyber.ee>]
-
- *) Change BIO_new_file (crypto/bio/bss_file.c) to use new
- BIO_R_NO_SUCH_FILE error code rather than the generic
- ERR_R_SYS_LIB error code if fopen() fails with ENOENT.
- [Ben Laurie]
-
- *) Add new functions
- ERR_peek_last_error
- ERR_peek_last_error_line
- ERR_peek_last_error_line_data.
- These are similar to
- ERR_peek_error
- ERR_peek_error_line
- ERR_peek_error_line_data,
- but report on the latest error recorded rather than the first one
- still in the error queue.
- [Ben Laurie, Bodo Moeller]
-
- *) default_algorithms option in ENGINE config module. This allows things
- like:
- default_algorithms = ALL
- default_algorithms = RSA, DSA, RAND, CIPHERS, DIGESTS
- [Steve Henson]
-
- *) Prelminary ENGINE config module.
- [Steve Henson]
-
- *) New experimental application configuration code.
- [Steve Henson]
-
- *) Change the AES code to follow the same name structure as all other
- symmetric ciphers, and behave the same way. Move everything to
- the directory crypto/aes, thereby obsoleting crypto/rijndael.
- [Stephen Sprunk <stephen@sprunk.org> and Richard Levitte]
-
- *) SECURITY: remove unsafe setjmp/signal interaction from ui_openssl.c.
- [Ben Laurie and Theo de Raadt]
-
- *) Add option to output public keys in req command.
- [Massimiliano Pala madwolf@openca.org]
-
- *) Use wNAFs in EC_POINTs_mul() for improved efficiency
- (up to about 10% better than before for P-192 and P-224).
- [Bodo Moeller]
-
- *) New functions/macros
-
- SSL_CTX_set_msg_callback(ctx, cb)
- SSL_CTX_set_msg_callback_arg(ctx, arg)
- SSL_set_msg_callback(ssl, cb)
- SSL_set_msg_callback_arg(ssl, arg)
-
- to request calling a callback function
-
- void cb(int write_p, int version, int content_type,
- const void *buf, size_t len, SSL *ssl, void *arg)
-
- whenever a protocol message has been completely received
- (write_p == 0) or sent (write_p == 1). Here 'version' is the
- protocol version according to which the SSL library interprets
- the current protocol message (SSL2_VERSION, SSL3_VERSION, or
- TLS1_VERSION). 'content_type' is 0 in the case of SSL 2.0, or
- the content type as defined in the SSL 3.0/TLS 1.0 protocol
- specification (change_cipher_spec(20), alert(21), handshake(22)).
- 'buf' and 'len' point to the actual message, 'ssl' to the
- SSL object, and 'arg' is the application-defined value set by
- SSL[_CTX]_set_msg_callback_arg().
-
- 'openssl s_client' and 'openssl s_server' have new '-msg' options
- to enable a callback that displays all protocol messages.
- [Bodo Moeller]
-
- *) Change the shared library support so shared libraries are built as
- soon as the corresponding static library is finished, and thereby get
- openssl and the test programs linked against the shared library.
- This still only happens when the keyword "shard" has been given to
- the configuration scripts.
-
- NOTE: shared library support is still an experimental thing, and
- backward binary compatibility is still not guaranteed.
- ["Maciej W. Rozycki" <macro@ds2.pg.gda.pl> and Richard Levitte]
-
- *) Add support for Subject Information Access extension.
- [Peter Sylvester <Peter.Sylvester@EdelWeb.fr>]
-
- *) Make BUF_MEM_grow() behaviour more consistent: Initialise to zero
- additional bytes when new memory had to be allocated, not just
- when reusing an existing buffer.
- [Bodo Moeller]
-
- *) New command line and configuration option 'utf8' for the req command.
- This allows field values to be specified as UTF8 strings.
- [Steve Henson]
-
- *) Add -multi and -mr options to "openssl speed" - giving multiple parallel
- runs for the former and machine-readable output for the latter.
- [Ben Laurie]
-
- *) Add '-noemailDN' option to 'openssl ca'. This prevents inclusion
- of the e-mail address in the DN (i.e., it will go into a certificate
- extension only). The new configuration file option 'email_in_dn = no'
- has the same effect.
- [Massimiliano Pala madwolf@openca.org]
-
- *) Change all functions with names starting with des_ to be starting
- with DES_ instead. Add wrappers that are compatible with libdes,
- but are named _ossl_old_des_*. Finally, add macros that map the
- des_* symbols to the corresponding _ossl_old_des_* if libdes
- compatibility is desired. If OpenSSL 0.9.6c compatibility is
- desired, the des_* symbols will be mapped to DES_*, with one
- exception.
-
- Since we provide two compatibility mappings, the user needs to
- define the macro OPENSSL_DES_LIBDES_COMPATIBILITY if libdes
- compatibility is desired. The default (i.e., when that macro
- isn't defined) is OpenSSL 0.9.6c compatibility.
-
- There are also macros that enable and disable the support of old
- des functions altogether. Those are OPENSSL_ENABLE_OLD_DES_SUPPORT
- and OPENSSL_DISABLE_OLD_DES_SUPPORT. If none or both of those
- are defined, the default will apply: to support the old des routines.
-
- In either case, one must include openssl/des.h to get the correct
- definitions. Do not try to just include openssl/des_old.h, that
- won't work.
-
- NOTE: This is a major break of an old API into a new one. Software
- authors are encouraged to switch to the DES_ style functions. Some
- time in the future, des_old.h and the libdes compatibility functions
- will be disable (i.e. OPENSSL_DISABLE_OLD_DES_SUPPORT will be the
- default), and then completely removed.
- [Richard Levitte]
-
- *) Test for certificates which contain unsupported critical extensions.
- If such a certificate is found during a verify operation it is
- rejected by default: this behaviour can be overridden by either
- handling the new error X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION or
- by setting the verify flag X509_V_FLAG_IGNORE_CRITICAL. A new function
- X509_supported_extension() has also been added which returns 1 if a
- particular extension is supported.
- [Steve Henson]
-
- *) Modify the behaviour of EVP cipher functions in similar way to digests
- to retain compatibility with existing code.
- [Steve Henson]
-
- *) Modify the behaviour of EVP_DigestInit() and EVP_DigestFinal() to retain
- compatibility with existing code. In particular the 'ctx' parameter does
- not have to be to be initialized before the call to EVP_DigestInit() and
- it is tidied up after a call to EVP_DigestFinal(). New function
- EVP_DigestFinal_ex() which does not tidy up the ctx. Similarly function
- EVP_MD_CTX_copy() changed to not require the destination to be
- initialized valid and new function EVP_MD_CTX_copy_ex() added which
- requires the destination to be valid.
-
- Modify all the OpenSSL digest calls to use EVP_DigestInit_ex(),
- EVP_DigestFinal_ex() and EVP_MD_CTX_copy_ex().
- [Steve Henson]
-
- *) Change ssl3_get_message (ssl/s3_both.c) and the functions using it
- so that complete 'Handshake' protocol structures are kept in memory
- instead of overwriting 'msg_type' and 'length' with 'body' data.
- [Bodo Moeller]
-
- *) Add an implementation of SSL_add_dir_cert_subjects_to_stack for Win32.
- [Massimo Santin via Richard Levitte]
-
- *) Major restructuring to the underlying ENGINE code. This includes
- reduction of linker bloat, separation of pure "ENGINE" manipulation
- (initialisation, etc) from functionality dealing with implementations
- of specific crypto iterfaces. This change also introduces integrated
- support for symmetric ciphers and digest implementations - so ENGINEs
- can now accelerate these by providing EVP_CIPHER and EVP_MD
- implementations of their own. This is detailed in crypto/engine/README
- as it couldn't be adequately described here. However, there are a few
- API changes worth noting - some RSA, DSA, DH, and RAND functions that
- were changed in the original introduction of ENGINE code have now
- reverted back - the hooking from this code to ENGINE is now a good
- deal more passive and at run-time, operations deal directly with
- RSA_METHODs, DSA_METHODs (etc) as they did before, rather than
- dereferencing through an ENGINE pointer any more. Also, the ENGINE
- functions dealing with BN_MOD_EXP[_CRT] handlers have been removed -
- they were not being used by the framework as there is no concept of a
- BIGNUM_METHOD and they could not be generalised to the new
- 'ENGINE_TABLE' mechanism that underlies the new code. Similarly,
- ENGINE_cpy() has been removed as it cannot be consistently defined in
- the new code.
- [Geoff Thorpe]
-
- *) Change ASN1_GENERALIZEDTIME_check() to allow fractional seconds.
- [Steve Henson]
-
- *) Change mkdef.pl to sort symbols that get the same entry number,
- and make sure the automatically generated functions ERR_load_*
- become part of libeay.num as well.
- [Richard Levitte]
-
- *) New function SSL_renegotiate_pending(). This returns true once
- renegotiation has been requested (either SSL_renegotiate() call
- or HelloRequest/ClientHello receveived from the peer) and becomes
- false once a handshake has been completed.
- (For servers, SSL_renegotiate() followed by SSL_do_handshake()
- sends a HelloRequest, but does not ensure that a handshake takes
- place. SSL_renegotiate_pending() is useful for checking if the
- client has followed the request.)
- [Bodo Moeller]
-
- *) New SSL option SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION.
- By default, clients may request session resumption even during
- renegotiation (if session ID contexts permit); with this option,
- session resumption is possible only in the first handshake.
-
- SSL_OP_ALL is now 0x00000FFFL instead of 0x000FFFFFL. This makes
- more bits available for options that should not be part of
- SSL_OP_ALL (such as SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION).
- [Bodo Moeller]
-
- *) Add some demos for certificate and certificate request creation.
- [Steve Henson]
-
- *) Make maximum certificate chain size accepted from the peer application
- settable (SSL*_get/set_max_cert_list()), as proposed by
- "Douglas E. Engert" <deengert@anl.gov>.
- [Lutz Jaenicke]
-
- *) Add support for shared libraries for Unixware-7
- (Boyd Lynn Gerber <gerberb@zenez.com>).
- [Lutz Jaenicke]
-
- *) Add a "destroy" handler to ENGINEs that allows structural cleanup to
- be done prior to destruction. Use this to unload error strings from
- ENGINEs that load their own error strings. NB: This adds two new API
- functions to "get" and "set" this destroy handler in an ENGINE.
- [Geoff Thorpe]
-
- *) Alter all existing ENGINE implementations (except "openssl" and
- "openbsd") to dynamically instantiate their own error strings. This
- makes them more flexible to be built both as statically-linked ENGINEs
- and self-contained shared-libraries loadable via the "dynamic" ENGINE.
- Also, add stub code to each that makes building them as self-contained
- shared-libraries easier (see README.ENGINE).
- [Geoff Thorpe]
-
- *) Add a "dynamic" ENGINE that provides a mechanism for binding ENGINE
- implementations into applications that are completely implemented in
- self-contained shared-libraries. The "dynamic" ENGINE exposes control
- commands that can be used to configure what shared-library to load and
- to control aspects of the way it is handled. Also, made an update to
- the README.ENGINE file that brings its information up-to-date and
- provides some information and instructions on the "dynamic" ENGINE
- (ie. how to use it, how to build "dynamic"-loadable ENGINEs, etc).
- [Geoff Thorpe]
-
- *) Make it possible to unload ranges of ERR strings with a new
- "ERR_unload_strings" function.
- [Geoff Thorpe]
-
- *) Add a copy() function to EVP_MD.
- [Ben Laurie]
-
- *) Make EVP_MD routines take a context pointer instead of just the
- md_data void pointer.
- [Ben Laurie]
-
- *) Add flags to EVP_MD and EVP_MD_CTX. EVP_MD_FLAG_ONESHOT indicates
- that the digest can only process a single chunk of data
- (typically because it is provided by a piece of
- hardware). EVP_MD_CTX_FLAG_ONESHOT indicates that the application
- is only going to provide a single chunk of data, and hence the
- framework needn't accumulate the data for oneshot drivers.
- [Ben Laurie]
-
- *) As with "ERR", make it possible to replace the underlying "ex_data"
- functions. This change also alters the storage and management of global
- ex_data state - it's now all inside ex_data.c and all "class" code (eg.
- RSA, BIO, SSL_CTX, etc) no longer stores its own STACKS and per-class
- index counters. The API functions that use this state have been changed
- to take a "class_index" rather than pointers to the class's local STACK
- and counter, and there is now an API function to dynamically create new
- classes. This centralisation allows us to (a) plug a lot of the
- thread-safety problems that existed, and (b) makes it possible to clean
- up all allocated state using "CRYPTO_cleanup_all_ex_data()". W.r.t. (b)
- such data would previously have always leaked in application code and
- workarounds were in place to make the memory debugging turn a blind eye
- to it. Application code that doesn't use this new function will still
- leak as before, but their memory debugging output will announce it now
- rather than letting it slide.
-
- Besides the addition of CRYPTO_cleanup_all_ex_data(), another API change
- induced by the "ex_data" overhaul is that X509_STORE_CTX_init() now
- has a return value to indicate success or failure.
- [Geoff Thorpe]
-
- *) Make it possible to replace the underlying "ERR" functions such that the
- global state (2 LHASH tables and 2 locks) is only used by the "default"
- implementation. This change also adds two functions to "get" and "set"
- the implementation prior to it being automatically set the first time
- any other ERR function takes place. Ie. an application can call "get",
- pass the return value to a module it has just loaded, and that module
- can call its own "set" function using that value. This means the
- module's "ERR" operations will use (and modify) the error state in the
- application and not in its own statically linked copy of OpenSSL code.
- [Geoff Thorpe]
-
- *) Give DH, DSA, and RSA types their own "**_up_ref()" function to increment
- reference counts. This performs normal REF_PRINT/REF_CHECK macros on
- the operation, and provides a more encapsulated way for external code
- (crypto/evp/ and ssl/) to do this. Also changed the evp and ssl code
- to use these functions rather than manually incrementing the counts.
-
- Also rename "DSO_up()" function to more descriptive "DSO_up_ref()".
- [Geoff Thorpe]
-
- *) Add EVP test program.
- [Ben Laurie]
-
- *) Add symmetric cipher support to ENGINE. Expect the API to change!
- [Ben Laurie]
-
- *) New CRL functions: X509_CRL_set_version(), X509_CRL_set_issuer_name()
- X509_CRL_set_lastUpdate(), X509_CRL_set_nextUpdate(), X509_CRL_sort(),
- X509_REVOKED_set_serialNumber(), and X509_REVOKED_set_revocationDate().
- These allow a CRL to be built without having to access X509_CRL fields
- directly. Modify 'ca' application to use new functions.
- [Steve Henson]
-
- *) Move SSL_OP_TLS_ROLLBACK_BUG out of the SSL_OP_ALL list of recommended
- bug workarounds. Rollback attack detection is a security feature.
- The problem will only arise on OpenSSL servers when TLSv1 is not
- available (sslv3_server_method() or SSL_OP_NO_TLSv1).
- Software authors not wanting to support TLSv1 will have special reasons
- for their choice and can explicitly enable this option.
- [Bodo Moeller, Lutz Jaenicke]
-
- *) Rationalise EVP so it can be extended: don't include a union of
- cipher/digest structures, add init/cleanup functions for EVP_MD_CTX
- (similar to those existing for EVP_CIPHER_CTX).
- Usage example:
-
- EVP_MD_CTX md;
-
- EVP_MD_CTX_init(&md); /* new function call */
- EVP_DigestInit(&md, EVP_sha1());
- EVP_DigestUpdate(&md, in, len);
- EVP_DigestFinal(&md, out, NULL);
- EVP_MD_CTX_cleanup(&md); /* new function call */
-
- [Ben Laurie]
-
- *) Make DES key schedule conform to the usual scheme, as well as
- correcting its structure. This means that calls to DES functions
- now have to pass a pointer to a des_key_schedule instead of a
- plain des_key_schedule (which was actually always a pointer
- anyway): E.g.,
-
- des_key_schedule ks;
-
- des_set_key_checked(..., &ks);
- des_ncbc_encrypt(..., &ks, ...);
-
- (Note that a later change renames 'des_...' into 'DES_...'.)
- [Ben Laurie]
-
- *) Initial reduction of linker bloat: the use of some functions, such as
- PEM causes large amounts of unused functions to be linked in due to
- poor organisation. For example pem_all.c contains every PEM function
- which has a knock on effect of linking in large amounts of (unused)
- ASN1 code. Grouping together similar functions and splitting unrelated
- functions prevents this.
- [Steve Henson]
-
- *) Cleanup of EVP macros.
- [Ben Laurie]
-
- *) Change historical references to {NID,SN,LN}_des_ede and ede3 to add the
- correct _ecb suffix.
- [Ben Laurie]
-
- *) Add initial OCSP responder support to ocsp application. The
- revocation information is handled using the text based index
- use by the ca application. The responder can either handle
- requests generated internally, supplied in files (for example
- via a CGI script) or using an internal minimal server.
- [Steve Henson]
-
- *) Add configuration choices to get zlib compression for TLS.
- [Richard Levitte]
-
- *) Changes to Kerberos SSL for RFC 2712 compliance:
- 1. Implemented real KerberosWrapper, instead of just using
- KRB5 AP_REQ message. [Thanks to Simon Wilkinson <sxw@sxw.org.uk>]
- 2. Implemented optional authenticator field of KerberosWrapper.
-
- Added openssl-style ASN.1 macros for Kerberos ticket, ap_req,
- and authenticator structs; see crypto/krb5/.
-
- Generalized Kerberos calls to support multiple Kerberos libraries.
- [Vern Staats <staatsvr@asc.hpc.mil>,
- Jeffrey Altman <jaltman@columbia.edu>
- via Richard Levitte]
-
- *) Cause 'openssl speed' to use fully hard-coded DSA keys as it
- already does with RSA. testdsa.h now has 'priv_key/pub_key'
- values for each of the key sizes rather than having just
- parameters (and 'speed' generating keys each time).
- [Geoff Thorpe]
-
- *) Speed up EVP routines.
- Before:
-encrypt
-type 8 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
-des-cbc 4408.85k 5560.51k 5778.46k 5862.20k 5825.16k
-des-cbc 4389.55k 5571.17k 5792.23k 5846.91k 5832.11k
-des-cbc 4394.32k 5575.92k 5807.44k 5848.37k 5841.30k
-decrypt
-des-cbc 3482.66k 5069.49k 5496.39k 5614.16k 5639.28k
-des-cbc 3480.74k 5068.76k 5510.34k 5609.87k 5635.52k
-des-cbc 3483.72k 5067.62k 5504.60k 5708.01k 5724.80k
- After:
-encrypt
-des-cbc 4660.16k 5650.19k 5807.19k 5827.13k 5783.32k
-decrypt
-des-cbc 3624.96k 5258.21k 5530.91k 5624.30k 5628.26k
- [Ben Laurie]
-
- *) Added the OS2-EMX target.
- ["Brian Havard" <brianh@kheldar.apana.org.au> and Richard Levitte]
-
- *) Rewrite apps to use NCONF routines instead of the old CONF. New functions
- to support NCONF routines in extension code. New function CONF_set_nconf()
- to allow functions which take an NCONF to also handle the old LHASH
- structure: this means that the old CONF compatible routines can be
- retained (in particular wrt extensions) without having to duplicate the
- code. New function X509V3_add_ext_nconf_sk to add extensions to a stack.
- [Steve Henson]
-
- *) Enhance the general user interface with mechanisms for inner control
- and with possibilities to have yes/no kind of prompts.
- [Richard Levitte]
-
- *) Change all calls to low level digest routines in the library and
- applications to use EVP. Add missing calls to HMAC_cleanup() and
- don't assume HMAC_CTX can be copied using memcpy().
- [Verdon Walker <VWalker@novell.com>, Steve Henson]
-
- *) Add the possibility to control engines through control names but with
- arbitrary arguments instead of just a string.
- Change the key loaders to take a UI_METHOD instead of a callback
- function pointer. NOTE: this breaks binary compatibility with earlier
- versions of OpenSSL [engine].
- Adapt the nCipher code for these new conditions and add a card insertion
- callback.
- [Richard Levitte]
-
- *) Enhance the general user interface with mechanisms to better support
- dialog box interfaces, application-defined prompts, the possibility
- to use defaults (for example default passwords from somewhere else)
- and interrupts/cancellations.
- [Richard Levitte]
-
- *) Tidy up PKCS#12 attribute handling. Add support for the CSP name
- attribute in PKCS#12 files, add new -CSP option to pkcs12 utility.
- [Steve Henson]
-
- *) Fix a memory leak in 'sk_dup()' in the case reallocation fails. (Also
- tidy up some unnecessarily weird code in 'sk_new()').
- [Geoff, reported by Diego Tartara <dtartara@novamens.com>]
-
- *) Change the key loading routines for ENGINEs to use the same kind
- callback (pem_password_cb) as all other routines that need this
- kind of callback.
- [Richard Levitte]
-
- *) Increase ENTROPY_NEEDED to 32 bytes, as Rijndael can operate with
- 256 bit (=32 byte) keys. Of course seeding with more entropy bytes
- than this minimum value is recommended.
- [Lutz Jaenicke]
-
- *) New random seeder for OpenVMS, using the system process statistics
- that are easily reachable.
- [Richard Levitte]
-
- *) Windows apparently can't transparently handle global
- variables defined in DLLs. Initialisations such as:
-
- const ASN1_ITEM *it = &ASN1_INTEGER_it;
-
- wont compile. This is used by the any applications that need to
- declare their own ASN1 modules. This was fixed by adding the option
- EXPORT_VAR_AS_FN to all Win32 platforms, although this isn't strictly
- needed for static libraries under Win32.
- [Steve Henson]
-
- *) New functions X509_PURPOSE_set() and X509_TRUST_set() to handle
- setting of purpose and trust fields. New X509_STORE trust and
- purpose functions and tidy up setting in other SSL functions.
- [Steve Henson]
-
- *) Add copies of X509_STORE_CTX fields and callbacks to X509_STORE
- structure. These are inherited by X509_STORE_CTX when it is
- initialised. This allows various defaults to be set in the
- X509_STORE structure (such as flags for CRL checking and custom
- purpose or trust settings) for functions which only use X509_STORE_CTX
- internally such as S/MIME.
-
- Modify X509_STORE_CTX_purpose_inherit() so it only sets purposes and
- trust settings if they are not set in X509_STORE. This allows X509_STORE
- purposes and trust (in S/MIME for example) to override any set by default.
-
- Add command line options for CRL checking to smime, s_client and s_server
- applications.
- [Steve Henson]
-
- *) Initial CRL based revocation checking. If the CRL checking flag(s)
- are set then the CRL is looked up in the X509_STORE structure and
- its validity and signature checked, then if the certificate is found
- in the CRL the verify fails with a revoked error.
-
- Various new CRL related callbacks added to X509_STORE_CTX structure.
-
- Command line options added to 'verify' application to support this.
-
- This needs some additional work, such as being able to handle multiple
- CRLs with different times, extension based lookup (rather than just
- by subject name) and ultimately more complete V2 CRL extension
- handling.
- [Steve Henson]
-
- *) Add a general user interface API (crypto/ui/). This is designed
- to replace things like des_read_password and friends (backward
- compatibility functions using this new API are provided).
- The purpose is to remove prompting functions from the DES code
- section as well as provide for prompting through dialog boxes in
- a window system and the like.
- [Richard Levitte]
-
- *) Add "ex_data" support to ENGINE so implementations can add state at a
- per-structure level rather than having to store it globally.
- [Geoff]
-
- *) Make it possible for ENGINE structures to be copied when retrieved by
- ENGINE_by_id() if the ENGINE specifies a new flag: ENGINE_FLAGS_BY_ID_COPY.
- This causes the "original" ENGINE structure to act like a template,
- analogous to the RSA vs. RSA_METHOD type of separation. Because of this
- operational state can be localised to each ENGINE structure, despite the
- fact they all share the same "methods". New ENGINE structures returned in
- this case have no functional references and the return value is the single
- structural reference. This matches the single structural reference returned
- by ENGINE_by_id() normally, when it is incremented on the pre-existing
- ENGINE structure.
- [Geoff]
-
- *) Fix ASN1 decoder when decoding type ANY and V_ASN1_OTHER: since this
- needs to match any other type at all we need to manually clear the
- tag cache.
- [Steve Henson]
-
- *) Changes to the "openssl engine" utility to include;
- - verbosity levels ('-v', '-vv', and '-vvv') that provide information
- about an ENGINE's available control commands.
- - executing control commands from command line arguments using the
- '-pre' and '-post' switches. '-post' is only used if '-t' is
- specified and the ENGINE is successfully initialised. The syntax for
- the individual commands are colon-separated, for example;
- openssl engine chil -pre FORK_CHECK:0 -pre SO_PATH:/lib/test.so
- [Geoff]
-
- *) New dynamic control command support for ENGINEs. ENGINEs can now
- declare their own commands (numbers), names (strings), descriptions,
- and input types for run-time discovery by calling applications. A
- subset of these commands are implicitly classed as "executable"
- depending on their input type, and only these can be invoked through
- the new string-based API function ENGINE_ctrl_cmd_string(). (Eg. this
- can be based on user input, config files, etc). The distinction is
- that "executable" commands cannot return anything other than a boolean
- result and can only support numeric or string input, whereas some
- discoverable commands may only be for direct use through
- ENGINE_ctrl(), eg. supporting the exchange of binary data, function
- pointers, or other custom uses. The "executable" commands are to
- support parameterisations of ENGINE behaviour that can be
- unambiguously defined by ENGINEs and used consistently across any
- OpenSSL-based application. Commands have been added to all the
- existing hardware-supporting ENGINEs, noticeably "SO_PATH" to allow
- control over shared-library paths without source code alterations.
- [Geoff]
-
- *) Changed all ENGINE implementations to dynamically allocate their
- ENGINEs rather than declaring them statically. Apart from this being
- necessary with the removal of the ENGINE_FLAGS_MALLOCED distinction,
- this also allows the implementations to compile without using the
- internal engine_int.h header.
- [Geoff]
-
- *) Minor adjustment to "rand" code. RAND_get_rand_method() now returns a
- 'const' value. Any code that should be able to modify a RAND_METHOD
- should already have non-const pointers to it (ie. they should only
- modify their own ones).
- [Geoff]
-
- *) Made a variety of little tweaks to the ENGINE code.
- - "atalla" and "ubsec" string definitions were moved from header files
- to C code. "nuron" string definitions were placed in variables
- rather than hard-coded - allowing parameterisation of these values
- later on via ctrl() commands.
- - Removed unused "#if 0"'d code.
- - Fixed engine list iteration code so it uses ENGINE_free() to release
- structural references.
- - Constified the RAND_METHOD element of ENGINE structures.
- - Constified various get/set functions as appropriate and added
- missing functions (including a catch-all ENGINE_cpy that duplicates
- all ENGINE values onto a new ENGINE except reference counts/state).
- - Removed NULL parameter checks in get/set functions. Setting a method
- or function to NULL is a way of cancelling out a previously set
- value. Passing a NULL ENGINE parameter is just plain stupid anyway
- and doesn't justify the extra error symbols and code.
- - Deprecate the ENGINE_FLAGS_MALLOCED define and move the area for
- flags from engine_int.h to engine.h.
- - Changed prototypes for ENGINE handler functions (init(), finish(),
- ctrl(), key-load functions, etc) to take an (ENGINE*) parameter.
- [Geoff]
-
- *) Implement binary inversion algorithm for BN_mod_inverse in addition
- to the algorithm using long division. The binary algorithm can be
- used only if the modulus is odd. On 32-bit systems, it is faster
- only for relatively small moduli (roughly 20-30% for 128-bit moduli,
- roughly 5-15% for 256-bit moduli), so we use it only for moduli
- up to 450 bits. In 64-bit environments, the binary algorithm
- appears to be advantageous for much longer moduli; here we use it
- for moduli up to 2048 bits.
- [Bodo Moeller]
-
- *) Rewrite CHOICE field setting in ASN1_item_ex_d2i(). The old code
- could not support the combine flag in choice fields.
- [Steve Henson]
-
- *) Add a 'copy_extensions' option to the 'ca' utility. This copies
- extensions from a certificate request to the certificate.
- [Steve Henson]
-
- *) Allow multiple 'certopt' and 'nameopt' options to be separated
- by commas. Add 'namopt' and 'certopt' options to the 'ca' config
- file: this allows the display of the certificate about to be
- signed to be customised, to allow certain fields to be included
- or excluded and extension details. The old system didn't display
- multicharacter strings properly, omitted fields not in the policy
- and couldn't display additional details such as extensions.
- [Steve Henson]
-
- *) Function EC_POINTs_mul for multiple scalar multiplication
- of an arbitrary number of elliptic curve points
- \sum scalars[i]*points[i],
- optionally including the generator defined for the EC_GROUP:
- scalar*generator + \sum scalars[i]*points[i].
-
- EC_POINT_mul is a simple wrapper function for the typical case
- that the point list has just one item (besides the optional
- generator).
- [Bodo Moeller]
-
- *) First EC_METHODs for curves over GF(p):
-
- EC_GFp_simple_method() uses the basic BN_mod_mul and BN_mod_sqr
- operations and provides various method functions that can also
- operate with faster implementations of modular arithmetic.
-
- EC_GFp_mont_method() reuses most functions that are part of
- EC_GFp_simple_method, but uses Montgomery arithmetic.
-
- [Bodo Moeller; point addition and point doubling
- implementation directly derived from source code provided by
- Lenka Fibikova <fibikova@exp-math.uni-essen.de>]
-
- *) Framework for elliptic curves (crypto/ec/ec.h, crypto/ec/ec_lcl.h,
- crypto/ec/ec_lib.c):
-
- Curves are EC_GROUP objects (with an optional group generator)
- based on EC_METHODs that are built into the library.
-
- Points are EC_POINT objects based on EC_GROUP objects.
-
- Most of the framework would be able to handle curves over arbitrary
- finite fields, but as there are no obvious types for fields other
- than GF(p), some functions are limited to that for now.
- [Bodo Moeller]
-
- *) Add the -HTTP option to s_server. It is similar to -WWW, but requires
- that the file contains a complete HTTP response.
- [Richard Levitte]
-
- *) Add the ec directory to mkdef.pl and mkfiles.pl. In mkdef.pl
- change the def and num file printf format specifier from "%-40sXXX"
- to "%-39s XXX". The latter will always guarantee a space after the
- field while the former will cause them to run together if the field
- is 40 of more characters long.
- [Steve Henson]
-
- *) Constify the cipher and digest 'method' functions and structures
- and modify related functions to take constant EVP_MD and EVP_CIPHER
- pointers.
- [Steve Henson]
-
- *) Hide BN_CTX structure details in bn_lcl.h instead of publishing them
- in <openssl/bn.h>. Also further increase BN_CTX_NUM to 32.
- [Bodo Moeller]
-
- *) Modify EVP_Digest*() routines so they now return values. Although the
- internal software routines can never fail additional hardware versions
- might.
- [Steve Henson]
-
- *) Clean up crypto/err/err.h and change some error codes to avoid conflicts:
-
- Previously ERR_R_FATAL was too small and coincided with ERR_LIB_PKCS7
- (= ERR_R_PKCS7_LIB); it is now 64 instead of 32.
-
- ASN1 error codes
- ERR_R_NESTED_ASN1_ERROR
- ...
- ERR_R_MISSING_ASN1_EOS
- were 4 .. 9, conflicting with
- ERR_LIB_RSA (= ERR_R_RSA_LIB)
- ...
- ERR_LIB_PEM (= ERR_R_PEM_LIB).
- They are now 58 .. 63 (i.e., just below ERR_R_FATAL).
-
- Add new error code 'ERR_R_INTERNAL_ERROR'.
- [Bodo Moeller]
-
- *) Don't overuse locks in crypto/err/err.c: For data retrieval, CRYPTO_r_lock
- suffices.
- [Bodo Moeller]
-
- *) New option '-subj arg' for 'openssl req' and 'openssl ca'. This
- sets the subject name for a new request or supersedes the
- subject name in a given request. Formats that can be parsed are
- 'CN=Some Name, OU=myOU, C=IT'
- and
- 'CN=Some Name/OU=myOU/C=IT'.
-
- Add options '-batch' and '-verbose' to 'openssl req'.
- [Massimiliano Pala <madwolf@hackmasters.net>]
-
- *) Introduce the possibility to access global variables through
- functions on platform were that's the best way to handle exporting
- global variables in shared libraries. To enable this functionality,
- one must configure with "EXPORT_VAR_AS_FN" or defined the C macro
- "OPENSSL_EXPORT_VAR_AS_FUNCTION" in crypto/opensslconf.h (the latter
- is normally done by Configure or something similar).
-
- To implement a global variable, use the macro OPENSSL_IMPLEMENT_GLOBAL
- in the source file (foo.c) like this:
-
- OPENSSL_IMPLEMENT_GLOBAL(int,foo)=1;
- OPENSSL_IMPLEMENT_GLOBAL(double,bar);
-
- To declare a global variable, use the macros OPENSSL_DECLARE_GLOBAL
- and OPENSSL_GLOBAL_REF in the header file (foo.h) like this:
-
- OPENSSL_DECLARE_GLOBAL(int,foo);
- #define foo OPENSSL_GLOBAL_REF(foo)
- OPENSSL_DECLARE_GLOBAL(double,bar);
- #define bar OPENSSL_GLOBAL_REF(bar)
-
- The #defines are very important, and therefore so is including the
- header file everywhere where the defined globals are used.
-
- The macro OPENSSL_EXPORT_VAR_AS_FUNCTION also affects the definition
- of ASN.1 items, but that structure is a bit different.
-
- The largest change is in util/mkdef.pl which has been enhanced with
- better and easier to understand logic to choose which symbols should
- go into the Windows .def files as well as a number of fixes and code
- cleanup (among others, algorithm keywords are now sorted
- lexicographically to avoid constant rewrites).
- [Richard Levitte]
-
- *) In BN_div() keep a copy of the sign of 'num' before writing the
- result to 'rm' because if rm==num the value will be overwritten
- and produce the wrong result if 'num' is negative: this caused
- problems with BN_mod() and BN_nnmod().
- [Steve Henson]
-
- *) Function OCSP_request_verify(). This checks the signature on an
- OCSP request and verifies the signer certificate. The signer
- certificate is just checked for a generic purpose and OCSP request
- trust settings.
- [Steve Henson]
-
- *) Add OCSP_check_validity() function to check the validity of OCSP
- responses. OCSP responses are prepared in real time and may only
- be a few seconds old. Simply checking that the current time lies
- between thisUpdate and nextUpdate max reject otherwise valid responses
- caused by either OCSP responder or client clock inaccuracy. Instead
- we allow thisUpdate and nextUpdate to fall within a certain period of
- the current time. The age of the response can also optionally be
- checked. Two new options -validity_period and -status_age added to
- ocsp utility.
- [Steve Henson]
-
- *) If signature or public key algorithm is unrecognized print out its
- OID rather that just UNKNOWN.
- [Steve Henson]
-
- *) Change OCSP_cert_to_id() to tolerate a NULL subject certificate and
- OCSP_cert_id_new() a NULL serialNumber. This allows a partial certificate
- ID to be generated from the issuer certificate alone which can then be
- passed to OCSP_id_issuer_cmp().
- [Steve Henson]
-
- *) New compilation option ASN1_ITEM_FUNCTIONS. This causes the new
- ASN1 modules to export functions returning ASN1_ITEM pointers
- instead of the ASN1_ITEM structures themselves. This adds several
- new macros which allow the underlying ASN1 function/structure to
- be accessed transparently. As a result code should not use ASN1_ITEM
- references directly (such as &X509_it) but instead use the relevant
- macros (such as ASN1_ITEM_rptr(X509)). This option is to allow
- use of the new ASN1 code on platforms where exporting structures
- is problematical (for example in shared libraries) but exporting
- functions returning pointers to structures is not.
- [Steve Henson]
-
- *) Add support for overriding the generation of SSL/TLS session IDs.
- These callbacks can be registered either in an SSL_CTX or per SSL.
- The purpose of this is to allow applications to control, if they wish,
- the arbitrary values chosen for use as session IDs, particularly as it
- can be useful for session caching in multiple-server environments. A
- command-line switch for testing this (and any client code that wishes
- to use such a feature) has been added to "s_server".
- [Geoff Thorpe, Lutz Jaenicke]
-
- *) Modify mkdef.pl to recognise and parse preprocessor conditionals
- of the form '#if defined(...) || defined(...) || ...' and
- '#if !defined(...) && !defined(...) && ...'. This also avoids
- the growing number of special cases it was previously handling.
- [Richard Levitte]
-
- *) Make all configuration macros available for application by making
- sure they are available in opensslconf.h, by giving them names starting
- with "OPENSSL_" to avoid conflicts with other packages and by making
- sure e_os2.h will cover all platform-specific cases together with
- opensslconf.h.
- Additionally, it is now possible to define configuration/platform-
- specific names (called "system identities"). In the C code, these
- are prefixed with "OPENSSL_SYSNAME_". e_os2.h will create another
- macro with the name beginning with "OPENSSL_SYS_", which is determined
- from "OPENSSL_SYSNAME_*" or compiler-specific macros depending on
- what is available.
- [Richard Levitte]
-
- *) New option -set_serial to 'req' and 'x509' this allows the serial
- number to use to be specified on the command line. Previously self
- signed certificates were hard coded with serial number 0 and the
- CA options of 'x509' had to use a serial number in a file which was
- auto incremented.
- [Steve Henson]
-
- *) New options to 'ca' utility to support V2 CRL entry extensions.
- Currently CRL reason, invalidity date and hold instruction are
- supported. Add new CRL extensions to V3 code and some new objects.
- [Steve Henson]
-
- *) New function EVP_CIPHER_CTX_set_padding() this is used to
- disable standard block padding (aka PKCS#5 padding) in the EVP
- API, which was previously mandatory. This means that the data is
- not padded in any way and so the total length much be a multiple
- of the block size, otherwise an error occurs.
- [Steve Henson]
-
- *) Initial (incomplete) OCSP SSL support.
- [Steve Henson]
-
- *) New function OCSP_parse_url(). This splits up a URL into its host,
- port and path components: primarily to parse OCSP URLs. New -url
- option to ocsp utility.
- [Steve Henson]
-
- *) New nonce behavior. The return value of OCSP_check_nonce() now
- reflects the various checks performed. Applications can decide
- whether to tolerate certain situations such as an absent nonce
- in a response when one was present in a request: the ocsp application
- just prints out a warning. New function OCSP_add1_basic_nonce()
- this is to allow responders to include a nonce in a response even if
- the request is nonce-less.
- [Steve Henson]
-
- *) Disable stdin buffering in load_cert (apps/apps.c) so that no certs are
- skipped when using openssl x509 multiple times on a single input file,
- e.g. "(openssl x509 -out cert1; openssl x509 -out cert2) <certs".
- [Bodo Moeller]
-
- *) Make ASN1_UTCTIME_set_string() and ASN1_GENERALIZEDTIME_set_string()
- set string type: to handle setting ASN1_TIME structures. Fix ca
- utility to correctly initialize revocation date of CRLs.
- [Steve Henson]
-
- *) New option SSL_OP_CIPHER_SERVER_PREFERENCE allows the server to override
- the clients preferred ciphersuites and rather use its own preferences.
- Should help to work around M$ SGC (Server Gated Cryptography) bug in
- Internet Explorer by ensuring unchanged hash method during stepup.
- (Also replaces the broken/deactivated SSL_OP_NON_EXPORT_FIRST option.)
- [Lutz Jaenicke]
-
- *) Make mkdef.pl recognise all DECLARE_ASN1 macros, change rijndael
- to aes and add a new 'exist' option to print out symbols that don't
- appear to exist.
- [Steve Henson]
-
- *) Additional options to ocsp utility to allow flags to be set and
- additional certificates supplied.
- [Steve Henson]
-
- *) Add the option -VAfile to 'openssl ocsp', so the user can give the
- OCSP client a number of certificate to only verify the response
- signature against.
- [Richard Levitte]
-
- *) Update Rijndael code to version 3.0 and change EVP AES ciphers to
- handle the new API. Currently only ECB, CBC modes supported. Add new
- AES OIDs.
-
- Add TLS AES ciphersuites as described in RFC3268, "Advanced
- Encryption Standard (AES) Ciphersuites for Transport Layer
- Security (TLS)". (In beta versions of OpenSSL 0.9.7, these were
- not enabled by default and were not part of the "ALL" ciphersuite
- alias because they were not yet official; they could be
- explicitly requested by specifying the "AESdraft" ciphersuite
- group alias. In the final release of OpenSSL 0.9.7, the group
- alias is called "AES" and is part of "ALL".)
- [Ben Laurie, Steve Henson, Bodo Moeller]
-
- *) New function OCSP_copy_nonce() to copy nonce value (if present) from
- request to response.
- [Steve Henson]
-
- *) Functions for OCSP responders. OCSP_request_onereq_count(),
- OCSP_request_onereq_get0(), OCSP_onereq_get0_id() and OCSP_id_get0_info()
- extract information from a certificate request. OCSP_response_create()
- creates a response and optionally adds a basic response structure.
- OCSP_basic_add1_status() adds a complete single response to a basic
- response and returns the OCSP_SINGLERESP structure just added (to allow
- extensions to be included for example). OCSP_basic_add1_cert() adds a
- certificate to a basic response and OCSP_basic_sign() signs a basic
- response with various flags. New helper functions ASN1_TIME_check()
- (checks validity of ASN1_TIME structure) and ASN1_TIME_to_generalizedtime()
- (converts ASN1_TIME to GeneralizedTime).
- [Steve Henson]
-
- *) Various new functions. EVP_Digest() combines EVP_Digest{Init,Update,Final}()
- in a single operation. X509_get0_pubkey_bitstr() extracts the public_key
- structure from a certificate. X509_pubkey_digest() digests the public_key
- contents: this is used in various key identifiers.
- [Steve Henson]
-
- *) Make sk_sort() tolerate a NULL argument.
- [Steve Henson reported by Massimiliano Pala <madwolf@comune.modena.it>]
-
- *) New OCSP verify flag OCSP_TRUSTOTHER. When set the "other" certificates
- passed by the function are trusted implicitly. If any of them signed the
- response then it is assumed to be valid and is not verified.
- [Steve Henson]
-
- *) In PKCS7_set_type() initialise content_type in PKCS7_ENC_CONTENT
- to data. This was previously part of the PKCS7 ASN1 code. This
- was causing problems with OpenSSL created PKCS#12 and PKCS#7 structures.
- [Steve Henson, reported by Kenneth R. Robinette
- <support@securenetterm.com>]
-
- *) Add CRYPTO_push_info() and CRYPTO_pop_info() calls to new ASN1
- routines: without these tracing memory leaks is very painful.
- Fix leaks in PKCS12 and PKCS7 routines.
- [Steve Henson]
-
- *) Make X509_time_adj() cope with the new behaviour of ASN1_TIME_new().
- Previously it initialised the 'type' argument to V_ASN1_UTCTIME which
- effectively meant GeneralizedTime would never be used. Now it
- is initialised to -1 but X509_time_adj() now has to check the value
- and use ASN1_TIME_set() if the value is not V_ASN1_UTCTIME or
- V_ASN1_GENERALIZEDTIME, without this it always uses GeneralizedTime.
- [Steve Henson, reported by Kenneth R. Robinette
- <support@securenetterm.com>]
-
- *) Fixes to BN_to_ASN1_INTEGER when bn is zero. This would previously
- result in a zero length in the ASN1_INTEGER structure which was
- not consistent with the structure when d2i_ASN1_INTEGER() was used
- and would cause ASN1_INTEGER_cmp() to fail. Enhance s2i_ASN1_INTEGER()
- to cope with hex and negative integers. Fix bug in i2a_ASN1_INTEGER()
- where it did not print out a minus for negative ASN1_INTEGER.
- [Steve Henson]
-
- *) Add summary printout to ocsp utility. The various functions which
- convert status values to strings have been renamed to:
- OCSP_response_status_str(), OCSP_cert_status_str() and
- OCSP_crl_reason_str() and are no longer static. New options
- to verify nonce values and to disable verification. OCSP response
- printout format cleaned up.
- [Steve Henson]
-
- *) Add additional OCSP certificate checks. These are those specified
- in RFC2560. This consists of two separate checks: the CA of the
- certificate being checked must either be the OCSP signer certificate
- or the issuer of the OCSP signer certificate. In the latter case the
- OCSP signer certificate must contain the OCSP signing extended key
- usage. This check is performed by attempting to match the OCSP
- signer or the OCSP signer CA to the issuerNameHash and issuerKeyHash
- in the OCSP_CERTID structures of the response.
- [Steve Henson]
-
- *) Initial OCSP certificate verification added to OCSP_basic_verify()
- and related routines. This uses the standard OpenSSL certificate
- verify routines to perform initial checks (just CA validity) and
- to obtain the certificate chain. Then additional checks will be
- performed on the chain. Currently the root CA is checked to see
- if it is explicitly trusted for OCSP signing. This is used to set
- a root CA as a global signing root: that is any certificate that
- chains to that CA is an acceptable OCSP signing certificate.
- [Steve Henson]
-
- *) New '-extfile ...' option to 'openssl ca' for reading X.509v3
- extensions from a separate configuration file.
- As when reading extensions from the main configuration file,
- the '-extensions ...' option may be used for specifying the
- section to use.
- [Massimiliano Pala <madwolf@comune.modena.it>]
-
- *) New OCSP utility. Allows OCSP requests to be generated or
- read. The request can be sent to a responder and the output
- parsed, outputed or printed in text form. Not complete yet:
- still needs to check the OCSP response validity.
- [Steve Henson]
-
- *) New subcommands for 'openssl ca':
- 'openssl ca -status <serial>' prints the status of the cert with
- the given serial number (according to the index file).
- 'openssl ca -updatedb' updates the expiry status of certificates
- in the index file.
- [Massimiliano Pala <madwolf@comune.modena.it>]
-
- *) New '-newreq-nodes' command option to CA.pl. This is like
- '-newreq', but calls 'openssl req' with the '-nodes' option
- so that the resulting key is not encrypted.
- [Damien Miller <djm@mindrot.org>]
-
- *) New configuration for the GNU Hurd.
- [Jonathan Bartlett <johnnyb@wolfram.com> via Richard Levitte]
-
- *) Initial code to implement OCSP basic response verify. This
- is currently incomplete. Currently just finds the signer's
- certificate and verifies the signature on the response.
- [Steve Henson]
-
- *) New SSLeay_version code SSLEAY_DIR to determine the compiled-in
- value of OPENSSLDIR. This is available via the new '-d' option
- to 'openssl version', and is also included in 'openssl version -a'.
- [Bodo Moeller]
-
- *) Allowing defining memory allocation callbacks that will be given
- file name and line number information in additional arguments
- (a const char* and an int). The basic functionality remains, as
- well as the original possibility to just replace malloc(),
- realloc() and free() by functions that do not know about these
- additional arguments. To register and find out the current
- settings for extended allocation functions, the following
- functions are provided:
-
- CRYPTO_set_mem_ex_functions
- CRYPTO_set_locked_mem_ex_functions
- CRYPTO_get_mem_ex_functions
- CRYPTO_get_locked_mem_ex_functions
-
- These work the same way as CRYPTO_set_mem_functions and friends.
- CRYPTO_get_[locked_]mem_functions now writes 0 where such an
- extended allocation function is enabled.
- Similarly, CRYPTO_get_[locked_]mem_ex_functions writes 0 where
- a conventional allocation function is enabled.
- [Richard Levitte, Bodo Moeller]
-
- *) Finish off removing the remaining LHASH function pointer casts.
- There should no longer be any prototype-casting required when using
- the LHASH abstraction, and any casts that remain are "bugs". See
- the callback types and macros at the head of lhash.h for details
- (and "OBJ_cleanup" in crypto/objects/obj_dat.c as an example).
- [Geoff Thorpe]
-
- *) Add automatic query of EGD sockets in RAND_poll() for the unix variant.
- If /dev/[u]random devices are not available or do not return enough
- entropy, EGD style sockets (served by EGD or PRNGD) will automatically
- be queried.
- The locations /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool, and
- /etc/entropy will be queried once each in this sequence, quering stops
- when enough entropy was collected without querying more sockets.
- [Lutz Jaenicke]
-
- *) Change the Unix RAND_poll() variant to be able to poll several
- random devices, as specified by DEVRANDOM, until a sufficient amount
- of data has been collected. We spend at most 10 ms on each file
- (select timeout) and read in non-blocking mode. DEVRANDOM now
- defaults to the list "/dev/urandom", "/dev/random", "/dev/srandom"
- (previously it was just the string "/dev/urandom"), so on typical
- platforms the 10 ms delay will never occur.
- Also separate out the Unix variant to its own file, rand_unix.c.
- For VMS, there's a currently-empty rand_vms.c.
- [Richard Levitte]
-
- *) Move OCSP client related routines to ocsp_cl.c. These
- provide utility functions which an application needing
- to issue a request to an OCSP responder and analyse the
- response will typically need: as opposed to those which an
- OCSP responder itself would need which will be added later.
-
- OCSP_request_sign() signs an OCSP request with an API similar
- to PKCS7_sign(). OCSP_response_status() returns status of OCSP
- response. OCSP_response_get1_basic() extracts basic response
- from response. OCSP_resp_find_status(): finds and extracts status
- information from an OCSP_CERTID structure (which will be created
- when the request structure is built). These are built from lower
- level functions which work on OCSP_SINGLERESP structures but
- wont normally be used unless the application wishes to examine
- extensions in the OCSP response for example.
-
- Replace nonce routines with a pair of functions.
- OCSP_request_add1_nonce() adds a nonce value and optionally
- generates a random value. OCSP_check_nonce() checks the
- validity of the nonce in an OCSP response.
- [Steve Henson]
-
- *) Change function OCSP_request_add() to OCSP_request_add0_id().
- This doesn't copy the supplied OCSP_CERTID and avoids the
- need to free up the newly created id. Change return type
- to OCSP_ONEREQ to return the internal OCSP_ONEREQ structure.
- This can then be used to add extensions to the request.
- Deleted OCSP_request_new(), since most of its functionality
- is now in OCSP_REQUEST_new() (and the case insensitive name
- clash) apart from the ability to set the request name which
- will be added elsewhere.
- [Steve Henson]
-
- *) Update OCSP API. Remove obsolete extensions argument from
- various functions. Extensions are now handled using the new
- OCSP extension code. New simple OCSP HTTP function which
- can be used to send requests and parse the response.
- [Steve Henson]
-
- *) Fix the PKCS#7 (S/MIME) code to work with new ASN1. Two new
- ASN1_ITEM structures help with sign and verify. PKCS7_ATTR_SIGN
- uses the special reorder version of SET OF to sort the attributes
- and reorder them to match the encoded order. This resolves a long
- standing problem: a verify on a PKCS7 structure just after signing
- it used to fail because the attribute order did not match the
- encoded order. PKCS7_ATTR_VERIFY does not reorder the attributes:
- it uses the received order. This is necessary to tolerate some broken
- software that does not order SET OF. This is handled by encoding
- as a SEQUENCE OF but using implicit tagging (with UNIVERSAL class)
- to produce the required SET OF.
- [Steve Henson]
-
- *) Have mk1mf.pl generate the macros OPENSSL_BUILD_SHLIBCRYPTO and
- OPENSSL_BUILD_SHLIBSSL and use them appropriately in the header
- files to get correct declarations of the ASN.1 item variables.
- [Richard Levitte]
-
- *) Rewrite of PKCS#12 code to use new ASN1 functionality. Replace many
- PKCS#12 macros with real functions. Fix two unrelated ASN1 bugs:
- asn1_check_tlen() would sometimes attempt to use 'ctx' when it was
- NULL and ASN1_TYPE was not dereferenced properly in asn1_ex_c2i().
- New ASN1 macro: DECLARE_ASN1_ITEM() which just declares the relevant
- ASN1_ITEM and no wrapper functions.
- [Steve Henson]
-
- *) New functions or ASN1_item_d2i_fp() and ASN1_item_d2i_bio(). These
- replace the old function pointer based I/O routines. Change most of
- the *_d2i_bio() and *_d2i_fp() functions to use these.
- [Steve Henson]
-
- *) Enhance mkdef.pl to be more accepting about spacing in C preprocessor
- lines, recognice more "algorithms" that can be deselected, and make
- it complain about algorithm deselection that isn't recognised.
- [Richard Levitte]
-
- *) New ASN1 functions to handle dup, sign, verify, digest, pack and
- unpack operations in terms of ASN1_ITEM. Modify existing wrappers
- to use new functions. Add NO_ASN1_OLD which can be set to remove
- some old style ASN1 functions: this can be used to determine if old
- code will still work when these eventually go away.
- [Steve Henson]
-
- *) New extension functions for OCSP structures, these follow the
- same conventions as certificates and CRLs.
- [Steve Henson]
-
- *) New function X509V3_add1_i2d(). This automatically encodes and
- adds an extension. Its behaviour can be customised with various
- flags to append, replace or delete. Various wrappers added for
- certifcates and CRLs.
- [Steve Henson]
-
- *) Fix to avoid calling the underlying ASN1 print routine when
- an extension cannot be parsed. Correct a typo in the
- OCSP_SERVICELOC extension. Tidy up print OCSP format.
- [Steve Henson]
-
- *) Make mkdef.pl parse some of the ASN1 macros and add apropriate
- entries for variables.
- [Steve Henson]
-
- *) Add functionality to apps/openssl.c for detecting locking
- problems: As the program is single-threaded, all we have
- to do is register a locking callback using an array for
- storing which locks are currently held by the program.
- [Bodo Moeller]
-
- *) Use a lock around the call to CRYPTO_get_ex_new_index() in
- SSL_get_ex_data_X509_STORE_idx(), which is used in
- ssl_verify_cert_chain() and thus can be called at any time
- during TLS/SSL handshakes so that thread-safety is essential.
- Unfortunately, the ex_data design is not at all suited
- for multi-threaded use, so it probably should be abolished.
- [Bodo Moeller]
-
- *) Added Broadcom "ubsec" ENGINE to OpenSSL.
- [Broadcom, tweaked and integrated by Geoff Thorpe]
-
- *) Move common extension printing code to new function
- X509V3_print_extensions(). Reorganise OCSP print routines and
- implement some needed OCSP ASN1 functions. Add OCSP extensions.
- [Steve Henson]
-
- *) New function X509_signature_print() to remove duplication in some
- print routines.
- [Steve Henson]
-
- *) Add a special meaning when SET OF and SEQUENCE OF flags are both
- set (this was treated exactly the same as SET OF previously). This
- is used to reorder the STACK representing the structure to match the
- encoding. This will be used to get round a problem where a PKCS7
- structure which was signed could not be verified because the STACK
- order did not reflect the encoded order.
- [Steve Henson]
-
- *) Reimplement the OCSP ASN1 module using the new code.
- [Steve Henson]
-
- *) Update the X509V3 code to permit the use of an ASN1_ITEM structure
- for its ASN1 operations. The old style function pointers still exist
- for now but they will eventually go away.
- [Steve Henson]
-
- *) Merge in replacement ASN1 code from the ASN1 branch. This almost
- completely replaces the old ASN1 functionality with a table driven
- encoder and decoder which interprets an ASN1_ITEM structure describing
- the ASN1 module. Compatibility with the existing ASN1 API (i2d,d2i) is
- largely maintained. Almost all of the old asn1_mac.h macro based ASN1
- has also been converted to the new form.
- [Steve Henson]
-
- *) Change BN_mod_exp_recp so that negative moduli are tolerated
- (the sign is ignored). Similarly, ignore the sign in BN_MONT_CTX_set
- so that BN_mod_exp_mont and BN_mod_exp_mont_word work
- for negative moduli.
- [Bodo Moeller]
-
- *) Fix BN_uadd and BN_usub: Always return non-negative results instead
- of not touching the result's sign bit.
- [Bodo Moeller]
-
- *) BN_div bugfix: If the result is 0, the sign (res->neg) must not be
- set.
- [Bodo Moeller]
-
- *) Changed the LHASH code to use prototypes for callbacks, and created
- macros to declare and implement thin (optionally static) functions
- that provide type-safety and avoid function pointer casting for the
- type-specific callbacks.
- [Geoff Thorpe]
-
- *) Added Kerberos Cipher Suites to be used with TLS, as written in
- RFC 2712.
- [Veers Staats <staatsvr@asc.hpc.mil>,
- Jeffrey Altman <jaltman@columbia.edu>, via Richard Levitte]
-
- *) Reformat the FAQ so the different questions and answers can be divided
- in sections depending on the subject.
- [Richard Levitte]
-
- *) Have the zlib compression code load ZLIB.DLL dynamically under
- Windows.
- [Richard Levitte]
-
- *) New function BN_mod_sqrt for computing square roots modulo a prime
- (using the probabilistic Tonelli-Shanks algorithm unless
- p == 3 (mod 4) or p == 5 (mod 8), which are cases that can
- be handled deterministically).
- [Lenka Fibikova <fibikova@exp-math.uni-essen.de>, Bodo Moeller]
-
- *) Make BN_mod_inverse faster by explicitly handling small quotients
- in the Euclid loop. (Speed gain about 20% for small moduli [256 or
- 512 bits], about 30% for larger ones [1024 or 2048 bits].)
- [Bodo Moeller]
-
- *) New function BN_kronecker.
- [Bodo Moeller]
-
- *) Fix BN_gcd so that it works on negative inputs; the result is
- positive unless both parameters are zero.
- Previously something reasonably close to an infinite loop was
- possible because numbers could be growing instead of shrinking
- in the implementation of Euclid's algorithm.
- [Bodo Moeller]
-
- *) Fix BN_is_word() and BN_is_one() macros to take into account the
- sign of the number in question.
-
- Fix BN_is_word(a,w) to work correctly for w == 0.
-
- The old BN_is_word(a,w) macro is now called BN_abs_is_word(a,w)
- because its test if the absolute value of 'a' equals 'w'.
- Note that BN_abs_is_word does *not* handle w == 0 reliably;
- it exists mostly for use in the implementations of BN_is_zero(),
- BN_is_one(), and BN_is_word().
- [Bodo Moeller]
-
- *) New function BN_swap.
- [Bodo Moeller]
-
- *) Use BN_nnmod instead of BN_mod in crypto/bn/bn_exp.c so that
- the exponentiation functions are more likely to produce reasonable
- results on negative inputs.
- [Bodo Moeller]
-
- *) Change BN_mod_mul so that the result is always non-negative.
- Previously, it could be negative if one of the factors was negative;
- I don't think anyone really wanted that behaviour.
- [Bodo Moeller]
-
- *) Move BN_mod_... functions into new file crypto/bn/bn_mod.c
- (except for exponentiation, which stays in crypto/bn/bn_exp.c,
- and BN_mod_mul_reciprocal, which stays in crypto/bn/bn_recp.c)
- and add new functions:
-
- BN_nnmod
- BN_mod_sqr
- BN_mod_add
- BN_mod_add_quick
- BN_mod_sub
- BN_mod_sub_quick
- BN_mod_lshift1
- BN_mod_lshift1_quick
- BN_mod_lshift
- BN_mod_lshift_quick
-
- These functions always generate non-negative results.
-
- BN_nnmod otherwise is like BN_mod (if BN_mod computes a remainder r
- such that |m| < r < 0, BN_nnmod will output rem + |m| instead).
-
- BN_mod_XXX_quick(r, a, [b,] m) generates the same result as
- BN_mod_XXX(r, a, [b,] m, ctx), but requires that a [and b]
- be reduced modulo m.
- [Lenka Fibikova <fibikova@exp-math.uni-essen.de>, Bodo Moeller]
-
-#if 0
- The following entry accidentily appeared in the CHANGES file
- distributed with OpenSSL 0.9.7. The modifications described in
- it do *not* apply to OpenSSL 0.9.7.
-
- *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there
- was actually never needed) and in BN_mul(). The removal in BN_mul()
- required a small change in bn_mul_part_recursive() and the addition
- of the functions bn_cmp_part_words(), bn_sub_part_words() and
- bn_add_part_words(), which do the same thing as bn_cmp_words(),
- bn_sub_words() and bn_add_words() except they take arrays with
- differing sizes.
- [Richard Levitte]
-#endif
-
- *) In 'openssl passwd', verify passwords read from the terminal
- unless the '-salt' option is used (which usually means that
- verification would just waste user's time since the resulting
- hash is going to be compared with some given password hash)
- or the new '-noverify' option is used.
-
- This is an incompatible change, but it does not affect
- non-interactive use of 'openssl passwd' (passwords on the command
- line, '-stdin' option, '-in ...' option) and thus should not
- cause any problems.
- [Bodo Moeller]
-
- *) Remove all references to RSAref, since there's no more need for it.
- [Richard Levitte]
-
- *) Make DSO load along a path given through an environment variable
- (SHLIB_PATH) with shl_load().
- [Richard Levitte]
-
- *) Constify the ENGINE code as a result of BIGNUM constification.
- Also constify the RSA code and most things related to it. In a
- few places, most notable in the depth of the ASN.1 code, ugly
- casts back to non-const were required (to be solved at a later
- time)
- [Richard Levitte]
-
- *) Make it so the openssl application has all engines loaded by default.
- [Richard Levitte]
-
- *) Constify the BIGNUM routines a little more.
- [Richard Levitte]
-
- *) Add the following functions:
-
- ENGINE_load_cswift()
- ENGINE_load_chil()
- ENGINE_load_atalla()
- ENGINE_load_nuron()
- ENGINE_load_builtin_engines()
-
- That way, an application can itself choose if external engines that
- are built-in in OpenSSL shall ever be used or not. The benefit is
- that applications won't have to be linked with libdl or other dso
- libraries unless it's really needed.
-
- Changed 'openssl engine' to load all engines on demand.
- Changed the engine header files to avoid the duplication of some
- declarations (they differed!).
- [Richard Levitte]
-
- *) 'openssl engine' can now list capabilities.
- [Richard Levitte]
-
- *) Better error reporting in 'openssl engine'.
- [Richard Levitte]
-
- *) Never call load_dh_param(NULL) in s_server.
- [Bodo Moeller]
-
- *) Add engine application. It can currently list engines by name and
- identity, and test if they are actually available.
- [Richard Levitte]
-
- *) Improve RPM specification file by forcing symbolic linking and making
- sure the installed documentation is also owned by root.root.
- [Damien Miller <djm@mindrot.org>]
-
- *) Give the OpenSSL applications more possibilities to make use of
- keys (public as well as private) handled by engines.
- [Richard Levitte]
-
- *) Add OCSP code that comes from CertCo.
- [Richard Levitte]
-
- *) Add VMS support for the Rijndael code.
- [Richard Levitte]
-
- *) Added untested support for Nuron crypto accelerator.
- [Ben Laurie]
-
- *) Add support for external cryptographic devices. This code was
- previously distributed separately as the "engine" branch.
- [Geoff Thorpe, Richard Levitte]
-
- *) Rework the filename-translation in the DSO code. It is now possible to
- have far greater control over how a "name" is turned into a filename
- depending on the operating environment and any oddities about the
- different shared library filenames on each system.
- [Geoff Thorpe]
-
- *) Support threads on FreeBSD-elf in Configure.
- [Richard Levitte]
-
- *) Fix for SHA1 assembly problem with MASM: it produces
- warnings about corrupt line number information when assembling
- with debugging information. This is caused by the overlapping
- of two sections.
- [Bernd Matthes <mainbug@celocom.de>, Steve Henson]
-
- *) NCONF changes.
- NCONF_get_number() has no error checking at all. As a replacement,
- NCONF_get_number_e() is defined (_e for "error checking") and is
- promoted strongly. The old NCONF_get_number is kept around for
- binary backward compatibility.
- Make it possible for methods to load from something other than a BIO,
- by providing a function pointer that is given a name instead of a BIO.
- For example, this could be used to load configuration data from an
- LDAP server.
- [Richard Levitte]
-
- *) Fix for non blocking accept BIOs. Added new I/O special reason
- BIO_RR_ACCEPT to cover this case. Previously use of accept BIOs
- with non blocking I/O was not possible because no retry code was
- implemented. Also added new SSL code SSL_WANT_ACCEPT to cover
- this case.
- [Steve Henson]
-
- *) Added the beginnings of Rijndael support.
- [Ben Laurie]
-
- *) Fix for bug in DirectoryString mask setting. Add support for
- X509_NAME_print_ex() in 'req' and X509_print_ex() function
- to allow certificate printing to more controllable, additional
- 'certopt' option to 'x509' to allow new printing options to be
- set.
- [Steve Henson]
-
- *) Clean old EAY MD5 hack from e_os.h.
- [Richard Levitte]
-
- Changes between 0.9.6l and 0.9.6m [17 Mar 2004]
-
- *) Fix null-pointer assignment in do_change_cipher_spec() revealed
- by using the Codenomicon TLS Test Tool (CVE-2004-0079)
- [Joe Orton, Steve Henson]
-
- Changes between 0.9.6k and 0.9.6l [04 Nov 2003]
-
- *) Fix additional bug revealed by the NISCC test suite:
-
- Stop bug triggering large recursion when presented with
- certain ASN.1 tags (CVE-2003-0851)
- [Steve Henson]
-
- Changes between 0.9.6j and 0.9.6k [30 Sep 2003]
-
- *) Fix various bugs revealed by running the NISCC test suite:
-
- Stop out of bounds reads in the ASN1 code when presented with
- invalid tags (CVE-2003-0543 and CVE-2003-0544).
-
- If verify callback ignores invalid public key errors don't try to check
- certificate signature with the NULL public key.
-
- [Steve Henson]
-
- *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate
- if the server requested one: as stated in TLS 1.0 and SSL 3.0
- specifications.
- [Steve Henson]
-
- *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional
- extra data after the compression methods not only for TLS 1.0
- but also for SSL 3.0 (as required by the specification).
- [Bodo Moeller; problem pointed out by Matthias Loepfe]
-
- *) Change X509_certificate_type() to mark the key as exported/exportable
- when it's 512 *bits* long, not 512 bytes.
- [Richard Levitte]
-
- Changes between 0.9.6i and 0.9.6j [10 Apr 2003]
-
- *) Countermeasure against the Klima-Pokorny-Rosa extension of
- Bleichbacher's attack on PKCS #1 v1.5 padding: treat
- a protocol version number mismatch like a decryption error
- in ssl3_get_client_key_exchange (ssl/s3_srvr.c).
- [Bodo Moeller]
-
- *) Turn on RSA blinding by default in the default implementation
- to avoid a timing attack. Applications that don't want it can call
- RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING.
- They would be ill-advised to do so in most cases.
- [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller]
-
- *) Change RSA blinding code so that it works when the PRNG is not
- seeded (in this case, the secret RSA exponent is abused as
- an unpredictable seed -- if it is not unpredictable, there
- is no point in blinding anyway). Make RSA blinding thread-safe
- by remembering the creator's thread ID in rsa->blinding and
- having all other threads use local one-time blinding factors
- (this requires more computation than sharing rsa->blinding, but
- avoids excessive locking; and if an RSA object is not shared
- between threads, blinding will still be very fast).
- [Bodo Moeller]
-
- Changes between 0.9.6h and 0.9.6i [19 Feb 2003]
-
- *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked
- via timing by performing a MAC computation even if incorrrect
- block cipher padding has been found. This is a countermeasure
- against active attacks where the attacker has to distinguish
- between bad padding and a MAC verification error. (CVE-2003-0078)
-
- [Bodo Moeller; problem pointed out by Brice Canvel (EPFL),
- Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and
- Martin Vuagnoux (EPFL, Ilion)]
-
- Changes between 0.9.6g and 0.9.6h [5 Dec 2002]
-
- *) New function OPENSSL_cleanse(), which is used to cleanse a section of
- memory from it's contents. This is done with a counter that will
- place alternating values in each byte. This can be used to solve
- two issues: 1) the removal of calls to memset() by highly optimizing
- compilers, and 2) cleansing with other values than 0, since those can
- be read through on certain media, for example a swap space on disk.
- [Geoff Thorpe]
-
- *) Bugfix: client side session caching did not work with external caching,
- because the session->cipher setting was not restored when reloading
- from the external cache. This problem was masked, when
- SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG (part of SSL_OP_ALL) was set.
- (Found by Steve Haslam <steve@araqnid.ddts.net>.)
- [Lutz Jaenicke]
-
- *) Fix client_certificate (ssl/s2_clnt.c): The permissible total
- length of the REQUEST-CERTIFICATE message is 18 .. 34, not 17 .. 33.
- [Zeev Lieber <zeev-l@yahoo.com>]
-
- *) Undo an undocumented change introduced in 0.9.6e which caused
- repeated calls to OpenSSL_add_all_ciphers() and
- OpenSSL_add_all_digests() to be ignored, even after calling
- EVP_cleanup().
- [Richard Levitte]
-
- *) Change the default configuration reader to deal with last line not
- being properly terminated.
- [Richard Levitte]
-
- *) Change X509_NAME_cmp() so it applies the special rules on handling
- DN values that are of type PrintableString, as well as RDNs of type
- emailAddress where the value has the type ia5String.
- [stefank@valicert.com via Richard Levitte]
-
- *) Add a SSL_SESS_CACHE_NO_INTERNAL_STORE flag to take over half
- the job SSL_SESS_CACHE_NO_INTERNAL_LOOKUP was inconsistently
- doing, define a new flag (SSL_SESS_CACHE_NO_INTERNAL) to be
- the bitwise-OR of the two for use by the majority of applications
- wanting this behaviour, and update the docs. The documented
- behaviour and actual behaviour were inconsistent and had been
- changing anyway, so this is more a bug-fix than a behavioural
- change.
- [Geoff Thorpe, diagnosed by Nadav Har'El]
-
- *) Don't impose a 16-byte length minimum on session IDs in ssl/s3_clnt.c
- (the SSL 3.0 and TLS 1.0 specifications allow any length up to 32 bytes).
- [Bodo Moeller]
-
- *) Fix initialization code race conditions in
- SSLv23_method(), SSLv23_client_method(), SSLv23_server_method(),
- SSLv2_method(), SSLv2_client_method(), SSLv2_server_method(),
- SSLv3_method(), SSLv3_client_method(), SSLv3_server_method(),
- TLSv1_method(), TLSv1_client_method(), TLSv1_server_method(),
- ssl2_get_cipher_by_char(),
- ssl3_get_cipher_by_char().
- [Patrick McCormick <patrick@tellme.com>, Bodo Moeller]
-
- *) Reorder cleanup sequence in SSL_CTX_free(): only remove the ex_data after
- the cached sessions are flushed, as the remove_cb() might use ex_data
- contents. Bug found by Sam Varshavchik <mrsam@courier-mta.com>
- (see [openssl.org #212]).
- [Geoff Thorpe, Lutz Jaenicke]
-
- *) Fix typo in OBJ_txt2obj which incorrectly passed the content
- length, instead of the encoding length to d2i_ASN1_OBJECT.
- [Steve Henson]
-
- Changes between 0.9.6f and 0.9.6g [9 Aug 2002]
-
- *) [In 0.9.6g-engine release:]
- Fix crypto/engine/vendor_defns/cswift.h for WIN32 (use '_stdcall').
- [Lynn Gazis <lgazis@rainbow.com>]
-
- Changes between 0.9.6e and 0.9.6f [8 Aug 2002]
-
- *) Fix ASN1 checks. Check for overflow by comparing with LONG_MAX
- and get fix the header length calculation.
- [Florian Weimer <Weimer@CERT.Uni-Stuttgart.DE>,
- Alon Kantor <alonk@checkpoint.com> (and others),
- Steve Henson]
-
- *) Use proper error handling instead of 'assertions' in buffer
- overflow checks added in 0.9.6e. This prevents DoS (the
- assertions could call abort()).
- [Arne Ansper <arne@ats.cyber.ee>, Bodo Moeller]
-
- Changes between 0.9.6d and 0.9.6e [30 Jul 2002]
-
- *) Add various sanity checks to asn1_get_length() to reject
- the ASN1 length bytes if they exceed sizeof(long), will appear
- negative or the content length exceeds the length of the
- supplied buffer.
- [Steve Henson, Adi Stav <stav@mercury.co.il>, James Yonan <jim@ntlp.com>]
-
- *) Fix cipher selection routines: ciphers without encryption had no flags
- for the cipher strength set and where therefore not handled correctly
- by the selection routines (PR #130).
- [Lutz Jaenicke]
-
- *) Fix EVP_dsa_sha macro.
- [Nils Larsch]
-
- *) New option
- SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
- for disabling the SSL 3.0/TLS 1.0 CBC vulnerability countermeasure
- that was added in OpenSSL 0.9.6d.
-
- As the countermeasure turned out to be incompatible with some
- broken SSL implementations, the new option is part of SSL_OP_ALL.
- SSL_OP_ALL is usually employed when compatibility with weird SSL
- implementations is desired (e.g. '-bugs' option to 's_client' and
- 's_server'), so the new option is automatically set in many
- applications.
- [Bodo Moeller]
-
- *) Changes in security patch:
-
- Changes marked "(CHATS)" were sponsored by the Defense Advanced
- Research Projects Agency (DARPA) and Air Force Research Laboratory,
- Air Force Materiel Command, USAF, under agreement number
- F30602-01-2-0537.
-
- *) Add various sanity checks to asn1_get_length() to reject
- the ASN1 length bytes if they exceed sizeof(long), will appear
- negative or the content length exceeds the length of the
- supplied buffer. (CVE-2002-0659)
- [Steve Henson, Adi Stav <stav@mercury.co.il>, James Yonan <jim@ntlp.com>]
-
- *) Assertions for various potential buffer overflows, not known to
- happen in practice.
- [Ben Laurie (CHATS)]
-
- *) Various temporary buffers to hold ASCII versions of integers were
- too small for 64 bit platforms. (CVE-2002-0655)
- [Matthew Byng-Maddick <mbm@aldigital.co.uk> and Ben Laurie (CHATS)>
-
- *) Remote buffer overflow in SSL3 protocol - an attacker could
- supply an oversized session ID to a client. (CVE-2002-0656)
- [Ben Laurie (CHATS)]
-
- *) Remote buffer overflow in SSL2 protocol - an attacker could
- supply an oversized client master key. (CVE-2002-0656)
- [Ben Laurie (CHATS)]
-
- Changes between 0.9.6c and 0.9.6d [9 May 2002]
-
- *) Fix crypto/asn1/a_sign.c so that 'parameters' is omitted (not
- encoded as NULL) with id-dsa-with-sha1.
- [Nils Larsch <nla@trustcenter.de>; problem pointed out by Bodo Moeller]
-
- *) Check various X509_...() return values in apps/req.c.
- [Nils Larsch <nla@trustcenter.de>]
-
- *) Fix BASE64 decode (EVP_DecodeUpdate) for data with CR/LF ended lines:
- an end-of-file condition would erronously be flagged, when the CRLF
- was just at the end of a processed block. The bug was discovered when
- processing data through a buffering memory BIO handing the data to a
- BASE64-decoding BIO. Bug fund and patch submitted by Pavel Tsekov
- <ptsekov@syntrex.com> and Nedelcho Stanev.
- [Lutz Jaenicke]
-
- *) Implement a countermeasure against a vulnerability recently found
- in CBC ciphersuites in SSL 3.0/TLS 1.0: Send an empty fragment
- before application data chunks to avoid the use of known IVs
- with data potentially chosen by the attacker.
- [Bodo Moeller]
-
- *) Fix length checks in ssl3_get_client_hello().
- [Bodo Moeller]
-
- *) TLS/SSL library bugfix: use s->s3->in_read_app_data differently
- to prevent ssl3_read_internal() from incorrectly assuming that
- ssl3_read_bytes() found application data while handshake
- processing was enabled when in fact s->s3->in_read_app_data was
- merely automatically cleared during the initial handshake.
- [Bodo Moeller; problem pointed out by Arne Ansper <arne@ats.cyber.ee>]
-
- *) Fix object definitions for Private and Enterprise: they were not
- recognized in their shortname (=lowercase) representation. Extend
- obj_dat.pl to issue an error when using undefined keywords instead
- of silently ignoring the problem (Svenning Sorensen
- <sss@sss.dnsalias.net>).
- [Lutz Jaenicke]
-
- *) Fix DH_generate_parameters() so that it works for 'non-standard'
- generators, i.e. generators other than 2 and 5. (Previously, the
- code did not properly initialise the 'add' and 'rem' values to
- BN_generate_prime().)
-
- In the new general case, we do not insist that 'generator' is
- actually a primitive root: This requirement is rather pointless;
- a generator of the order-q subgroup is just as good, if not
- better.
- [Bodo Moeller]
-
- *) Map new X509 verification errors to alerts. Discovered and submitted by
- Tom Wu <tom@arcot.com>.
- [Lutz Jaenicke]
-
- *) Fix ssl3_pending() (ssl/s3_lib.c) to prevent SSL_pending() from
- returning non-zero before the data has been completely received
- when using non-blocking I/O.
- [Bodo Moeller; problem pointed out by John Hughes]
-
- *) Some of the ciphers missed the strength entry (SSL_LOW etc).
- [Ben Laurie, Lutz Jaenicke]
-
- *) Fix bug in SSL_clear(): bad sessions were not removed (found by
- Yoram Zahavi <YoramZ@gilian.com>).
- [Lutz Jaenicke]
-
- *) Add information about CygWin 1.3 and on, and preserve proper
- configuration for the versions before that.
- [Corinna Vinschen <vinschen@redhat.com> and Richard Levitte]
-
- *) Make removal from session cache (SSL_CTX_remove_session()) more robust:
- check whether we deal with a copy of a session and do not delete from
- the cache in this case. Problem reported by "Izhar Shoshani Levi"
- <izhar@checkpoint.com>.
- [Lutz Jaenicke]
-
- *) Do not store session data into the internal session cache, if it
- is never intended to be looked up (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
- flag is set). Proposed by Aslam <aslam@funk.com>.
- [Lutz Jaenicke]
-
- *) Have ASN1_BIT_STRING_set_bit() really clear a bit when the requested
- value is 0.
- [Richard Levitte]
-
- *) [In 0.9.6d-engine release:]
- Fix a crashbug and a logic bug in hwcrhk_load_pubkey().
- [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
-
- *) Add the configuration target linux-s390x.
- [Neale Ferguson <Neale.Ferguson@SoftwareAG-USA.com> via Richard Levitte]
-
- *) The earlier bugfix for the SSL3_ST_SW_HELLO_REQ_C case of
- ssl3_accept (ssl/s3_srvr.c) incorrectly used a local flag
- variable as an indication that a ClientHello message has been
- received. As the flag value will be lost between multiple
- invocations of ssl3_accept when using non-blocking I/O, the
- function may not be aware that a handshake has actually taken
- place, thus preventing a new session from being added to the
- session cache.
-
- To avoid this problem, we now set s->new_session to 2 instead of
- using a local variable.
- [Lutz Jaenicke, Bodo Moeller]
-
- *) Bugfix: Return -1 from ssl3_get_server_done (ssl3/s3_clnt.c)
- if the SSL_R_LENGTH_MISMATCH error is detected.
- [Geoff Thorpe, Bodo Moeller]
-
- *) New 'shared_ldflag' column in Configure platform table.
- [Richard Levitte]
-
- *) Fix EVP_CIPHER_mode macro.
- ["Dan S. Camper" <dan@bti.net>]
-
- *) Fix ssl3_read_bytes (ssl/s3_pkt.c): To ignore messages of unknown
- type, we must throw them away by setting rr->length to 0.
- [D P Chang <dpc@qualys.com>]
-
- Changes between 0.9.6b and 0.9.6c [21 dec 2001]
-
- *) Fix BN_rand_range bug pointed out by Dominikus Scherkl
- <Dominikus.Scherkl@biodata.com>. (The previous implementation
- worked incorrectly for those cases where range = 10..._2 and
- 3*range is two bits longer than range.)
- [Bodo Moeller]
-
- *) Only add signing time to PKCS7 structures if it is not already
- present.
- [Steve Henson]
-
- *) Fix crypto/objects/objects.h: "ld-ce" should be "id-ce",
- OBJ_ld_ce should be OBJ_id_ce.
- Also some ip-pda OIDs in crypto/objects/objects.txt were
- incorrect (cf. RFC 3039).
- [Matt Cooper, Frederic Giudicelli, Bodo Moeller]
-
- *) Release CRYPTO_LOCK_DYNLOCK when CRYPTO_destroy_dynlockid()
- returns early because it has nothing to do.
- [Andy Schneider <andy.schneider@bjss.co.uk>]
-
- *) [In 0.9.6c-engine release:]
- Fix mutex callback return values in crypto/engine/hw_ncipher.c.
- [Andy Schneider <andy.schneider@bjss.co.uk>]
-
- *) [In 0.9.6c-engine release:]
- Add support for Cryptographic Appliance's keyserver technology.
- (Use engine 'keyclient')
- [Cryptographic Appliances and Geoff Thorpe]
-
- *) Add a configuration entry for OS/390 Unix. The C compiler 'c89'
- is called via tools/c89.sh because arguments have to be
- rearranged (all '-L' options must appear before the first object
- modules).
- [Richard Shapiro <rshapiro@abinitio.com>]
-
- *) [In 0.9.6c-engine release:]
- Add support for Broadcom crypto accelerator cards, backported
- from 0.9.7.
- [Broadcom, Nalin Dahyabhai <nalin@redhat.com>, Mark Cox]
-
- *) [In 0.9.6c-engine release:]
- Add support for SureWare crypto accelerator cards from
- Baltimore Technologies. (Use engine 'sureware')
- [Baltimore Technologies and Mark Cox]
-
- *) [In 0.9.6c-engine release:]
- Add support for crypto accelerator cards from Accelerated
- Encryption Processing, www.aep.ie. (Use engine 'aep')
- [AEP Inc. and Mark Cox]
-
- *) Add a configuration entry for gcc on UnixWare.
- [Gary Benson <gbenson@redhat.com>]
-
- *) Change ssl/s2_clnt.c and ssl/s2_srvr.c so that received handshake
- messages are stored in a single piece (fixed-length part and
- variable-length part combined) and fix various bugs found on the way.
- [Bodo Moeller]
-
- *) Disable caching in BIO_gethostbyname(), directly use gethostbyname()
- instead. BIO_gethostbyname() does not know what timeouts are
- appropriate, so entries would stay in cache even when they have
- become invalid.
- [Bodo Moeller; problem pointed out by Rich Salz <rsalz@zolera.com>
-
- *) Change ssl23_get_client_hello (ssl/s23_srvr.c) behaviour when
- faced with a pathologically small ClientHello fragment that does
- not contain client_version: Instead of aborting with an error,
- simply choose the highest available protocol version (i.e.,
- TLS 1.0 unless it is disabled). In practice, ClientHello
- messages are never sent like this, but this change gives us
- strictly correct behaviour at least for TLS.
- [Bodo Moeller]
-
- *) Fix SSL handshake functions and SSL_clear() such that SSL_clear()
- never resets s->method to s->ctx->method when called from within
- one of the SSL handshake functions.
- [Bodo Moeller; problem pointed out by Niko Baric]
-
- *) In ssl3_get_client_hello (ssl/s3_srvr.c), generate a fatal alert
- (sent using the client's version number) if client_version is
- smaller than the protocol version in use. Also change
- ssl23_get_client_hello (ssl/s23_srvr.c) to select TLS 1.0 if
- the client demanded SSL 3.0 but only TLS 1.0 is enabled; then
- the client will at least see that alert.
- [Bodo Moeller]
-
- *) Fix ssl3_get_message (ssl/s3_both.c) to handle message fragmentation
- correctly.
- [Bodo Moeller]
-
- *) Avoid infinite loop in ssl3_get_message (ssl/s3_both.c) if a
- client receives HelloRequest while in a handshake.
- [Bodo Moeller; bug noticed by Andy Schneider <andy.schneider@bjss.co.uk>]
-
- *) Bugfix in ssl3_accept (ssl/s3_srvr.c): Case SSL3_ST_SW_HELLO_REQ_C
- should end in 'break', not 'goto end' which circuments various
- cleanups done in state SSL_ST_OK. But session related stuff
- must be disabled for SSL_ST_OK in the case that we just sent a
- HelloRequest.
-
- Also avoid some overhead by not calling ssl_init_wbio_buffer()
- before just sending a HelloRequest.
- [Bodo Moeller, Eric Rescorla <ekr@rtfm.com>]
-
- *) Fix ssl/s3_enc.c, ssl/t1_enc.c and ssl/s3_pkt.c so that we don't
- reveal whether illegal block cipher padding was found or a MAC
- verification error occured. (Neither SSLerr() codes nor alerts
- are directly visible to potential attackers, but the information
- may leak via logfiles.)
-
- Similar changes are not required for the SSL 2.0 implementation
- because the number of padding bytes is sent in clear for SSL 2.0,
- and the extra bytes are just ignored. However ssl/s2_pkt.c
- failed to verify that the purported number of padding bytes is in
- the legal range.
- [Bodo Moeller]
-
- *) Add OpenUNIX-8 support including shared libraries
- (Boyd Lynn Gerber <gerberb@zenez.com>).
- [Lutz Jaenicke]
-
- *) Improve RSA_padding_check_PKCS1_OAEP() check again to avoid
- 'wristwatch attack' using huge encoding parameters (cf.
- James H. Manger's CRYPTO 2001 paper). Note that the
- RSA_PKCS1_OAEP_PADDING case of RSA_private_decrypt() does not use
- encoding parameters and hence was not vulnerable.
- [Bodo Moeller]
-
- *) BN_sqr() bug fix.
- [Ulf Möller, reported by Jim Ellis <jim.ellis@cavium.com>]
-
- *) Rabin-Miller test analyses assume uniformly distributed witnesses,
- so use BN_pseudo_rand_range() instead of using BN_pseudo_rand()
- followed by modular reduction.
- [Bodo Moeller; pointed out by Adam Young <AYoung1@NCSUS.JNJ.COM>]
-
- *) Add BN_pseudo_rand_range() with obvious functionality: BN_rand_range()
- equivalent based on BN_pseudo_rand() instead of BN_rand().
- [Bodo Moeller]
-
- *) s3_srvr.c: allow sending of large client certificate lists (> 16 kB).
- This function was broken, as the check for a new client hello message
- to handle SGC did not allow these large messages.
- (Tracked down by "Douglas E. Engert" <deengert@anl.gov>.)
- [Lutz Jaenicke]
-
- *) Add alert descriptions for TLSv1 to SSL_alert_desc_string[_long]().
- [Lutz Jaenicke]
-
- *) Fix buggy behaviour of BIO_get_num_renegotiates() and BIO_ctrl()
- for BIO_C_GET_WRITE_BUF_SIZE ("Stephen Hinton" <shinton@netopia.com>).
- [Lutz Jaenicke]
-
- *) Rework the configuration and shared library support for Tru64 Unix.
- The configuration part makes use of modern compiler features and
- still retains old compiler behavior for those that run older versions
- of the OS. The shared library support part includes a variant that
- uses the RPATH feature, and is available through the special
- configuration target "alpha-cc-rpath", which will never be selected
- automatically.
- [Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu> via Richard Levitte]
-
- *) In ssl3_get_key_exchange (ssl/s3_clnt.c), call ssl3_get_message()
- with the same message size as in ssl3_get_certificate_request().
- Otherwise, if no ServerKeyExchange message occurs, CertificateRequest
- messages might inadvertently be reject as too long.
- [Petr Lampa <lampa@fee.vutbr.cz>]
-
- *) Enhanced support for IA-64 Unix platforms (well, Linux and HP-UX).
- [Andy Polyakov]
-
- *) Modified SSL library such that the verify_callback that has been set
- specificly for an SSL object with SSL_set_verify() is actually being
- used. Before the change, a verify_callback set with this function was
- ignored and the verify_callback() set in the SSL_CTX at the time of
- the call was used. New function X509_STORE_CTX_set_verify_cb() introduced
- to allow the necessary settings.
- [Lutz Jaenicke]
-
- *) Initialize static variable in crypto/dsa/dsa_lib.c and crypto/dh/dh_lib.c
- explicitly to NULL, as at least on Solaris 8 this seems not always to be
- done automatically (in contradiction to the requirements of the C
- standard). This made problems when used from OpenSSH.
- [Lutz Jaenicke]
-
- *) In OpenSSL 0.9.6a and 0.9.6b, crypto/dh/dh_key.c ignored
- dh->length and always used
-
- BN_rand_range(priv_key, dh->p).
-
- BN_rand_range() is not necessary for Diffie-Hellman, and this
- specific range makes Diffie-Hellman unnecessarily inefficient if
- dh->length (recommended exponent length) is much smaller than the
- length of dh->p. We could use BN_rand_range() if the order of
- the subgroup was stored in the DH structure, but we only have
- dh->length.
-
- So switch back to
-
- BN_rand(priv_key, l, ...)
-
- where 'l' is dh->length if this is defined, or BN_num_bits(dh->p)-1
- otherwise.
- [Bodo Moeller]
-
- *) In
-
- RSA_eay_public_encrypt
- RSA_eay_private_decrypt
- RSA_eay_private_encrypt (signing)
- RSA_eay_public_decrypt (signature verification)
-
- (default implementations for RSA_public_encrypt,
- RSA_private_decrypt, RSA_private_encrypt, RSA_public_decrypt),
- always reject numbers >= n.
- [Bodo Moeller]
-
- *) In crypto/rand/md_rand.c, use a new short-time lock CRYPTO_LOCK_RAND2
- to synchronize access to 'locking_thread'. This is necessary on
- systems where access to 'locking_thread' (an 'unsigned long'
- variable) is not atomic.
- [Bodo Moeller]
-
- *) In crypto/rand/md_rand.c, set 'locking_thread' to current thread's ID
- *before* setting the 'crypto_lock_rand' flag. The previous code had
- a race condition if 0 is a valid thread ID.
- [Travis Vitek <vitek@roguewave.com>]
-
- *) Add support for shared libraries under Irix.
- [Albert Chin-A-Young <china@thewrittenword.com>]
-
- *) Add configuration option to build on Linux on both big-endian and
- little-endian MIPS.
- [Ralf Baechle <ralf@uni-koblenz.de>]
-
- *) Add the possibility to create shared libraries on HP-UX.
- [Richard Levitte]
-
- Changes between 0.9.6a and 0.9.6b [9 Jul 2001]
-
- *) Change ssleay_rand_bytes (crypto/rand/md_rand.c)
- to avoid a SSLeay/OpenSSL PRNG weakness pointed out by
- Markku-Juhani O. Saarinen <markku-juhani.saarinen@nokia.com>:
- PRNG state recovery was possible based on the output of
- one PRNG request appropriately sized to gain knowledge on
- 'md' followed by enough consecutive 1-byte PRNG requests
- to traverse all of 'state'.
-
- 1. When updating 'md_local' (the current thread's copy of 'md')
- during PRNG output generation, hash all of the previous
- 'md_local' value, not just the half used for PRNG output.
-
- 2. Make the number of bytes from 'state' included into the hash
- independent from the number of PRNG bytes requested.
-
- The first measure alone would be sufficient to avoid
- Markku-Juhani's attack. (Actually it had never occurred
- to me that the half of 'md_local' used for chaining was the
- half from which PRNG output bytes were taken -- I had always
- assumed that the secret half would be used.) The second
- measure makes sure that additional data from 'state' is never
- mixed into 'md_local' in small portions; this heuristically
- further strengthens the PRNG.
- [Bodo Moeller]
-
- *) Fix crypto/bn/asm/mips3.s.
- [Andy Polyakov]
-
- *) When only the key is given to "enc", the IV is undefined. Print out
- an error message in this case.
- [Lutz Jaenicke]
-
- *) Handle special case when X509_NAME is empty in X509 printing routines.
- [Steve Henson]
-
- *) In dsa_do_verify (crypto/dsa/dsa_ossl.c), verify that r and s are
- positive and less than q.
- [Bodo Moeller]
-
- *) Don't change *pointer in CRYPTO_add_lock() is add_lock_callback is
- used: it isn't thread safe and the add_lock_callback should handle
- that itself.
- [Paul Rose <Paul.Rose@bridge.com>]
-
- *) Verify that incoming data obeys the block size in
- ssl3_enc (ssl/s3_enc.c) and tls1_enc (ssl/t1_enc.c).
- [Bodo Moeller]
-
- *) Fix OAEP check.
- [Ulf Möller, Bodo Möller]
-
- *) The countermeasure against Bleichbacher's attack on PKCS #1 v1.5
- RSA encryption was accidentally removed in s3_srvr.c in OpenSSL 0.9.5
- when fixing the server behaviour for backwards-compatible 'client
- hello' messages. (Note that the attack is impractical against
- SSL 3.0 and TLS 1.0 anyway because length and version checking
- means that the probability of guessing a valid ciphertext is
- around 2^-40; see section 5 in Bleichenbacher's CRYPTO '98
- paper.)
-
- Before 0.9.5, the countermeasure (hide the error by generating a
- random 'decryption result') did not work properly because
- ERR_clear_error() was missing, meaning that SSL_get_error() would
- detect the supposedly ignored error.
-
- Both problems are now fixed.
- [Bodo Moeller]
-
- *) In crypto/bio/bf_buff.c, increase DEFAULT_BUFFER_SIZE to 4096
- (previously it was 1024).
- [Bodo Moeller]
-
- *) Fix for compatibility mode trust settings: ignore trust settings
- unless some valid trust or reject settings are present.
- [Steve Henson]
-
- *) Fix for blowfish EVP: its a variable length cipher.
- [Steve Henson]
-
- *) Fix various bugs related to DSA S/MIME verification. Handle missing
- parameters in DSA public key structures and return an error in the
- DSA routines if parameters are absent.
- [Steve Henson]
-
- *) In versions up to 0.9.6, RAND_file_name() resorted to file ".rnd"
- in the current directory if neither $RANDFILE nor $HOME was set.
- RAND_file_name() in 0.9.6a returned NULL in this case. This has
- caused some confusion to Windows users who haven't defined $HOME.
- Thus RAND_file_name() is changed again: e_os.h can define a
- DEFAULT_HOME, which will be used if $HOME is not set.
- For Windows, we use "C:"; on other platforms, we still require
- environment variables.
-
- *) Move 'if (!initialized) RAND_poll()' into regions protected by
- CRYPTO_LOCK_RAND. This is not strictly necessary, but avoids
- having multiple threads call RAND_poll() concurrently.
- [Bodo Moeller]
-
- *) In crypto/rand/md_rand.c, replace 'add_do_not_lock' flag by a
- combination of a flag and a thread ID variable.
- Otherwise while one thread is in ssleay_rand_bytes (which sets the
- flag), *other* threads can enter ssleay_add_bytes without obeying
- the CRYPTO_LOCK_RAND lock (and may even illegally release the lock
- that they do not hold after the first thread unsets add_do_not_lock).
- [Bodo Moeller]
-
- *) Change bctest again: '-x' expressions are not available in all
- versions of 'test'.
- [Bodo Moeller]
-
- Changes between 0.9.6 and 0.9.6a [5 Apr 2001]
-
- *) Fix a couple of memory leaks in PKCS7_dataDecode()
- [Steve Henson, reported by Heyun Zheng <hzheng@atdsprint.com>]
-
- *) Change Configure and Makefiles to provide EXE_EXT, which will contain
- the default extension for executables, if any. Also, make the perl
- scripts that use symlink() to test if it really exists and use "cp"
- if it doesn't. All this made OpenSSL compilable and installable in
- CygWin.
- [Richard Levitte]
-
- *) Fix for asn1_GetSequence() for indefinite length constructed data.
- If SEQUENCE is length is indefinite just set c->slen to the total
- amount of data available.
- [Steve Henson, reported by shige@FreeBSD.org]
- [This change does not apply to 0.9.7.]
-
- *) Change bctest to avoid here-documents inside command substitution
- (workaround for FreeBSD /bin/sh bug).
- For compatibility with Ultrix, avoid shell functions (introduced
- in the bctest version that searches along $PATH).
- [Bodo Moeller]
-
- *) Rename 'des_encrypt' to 'des_encrypt1'. This avoids the clashes
- with des_encrypt() defined on some operating systems, like Solaris
- and UnixWare.
- [Richard Levitte]
-
- *) Check the result of RSA-CRT (see D. Boneh, R. DeMillo, R. Lipton:
- On the Importance of Eliminating Errors in Cryptographic
- Computations, J. Cryptology 14 (2001) 2, 101-119,
- http://theory.stanford.edu/~dabo/papers/faults.ps.gz).
- [Ulf Moeller]
-
- *) MIPS assembler BIGNUM division bug fix.
- [Andy Polyakov]
-
- *) Disabled incorrect Alpha assembler code.
- [Richard Levitte]
-
- *) Fix PKCS#7 decode routines so they correctly update the length
- after reading an EOC for the EXPLICIT tag.
- [Steve Henson]
- [This change does not apply to 0.9.7.]
-
- *) Fix bug in PKCS#12 key generation routines. This was triggered
- if a 3DES key was generated with a 0 initial byte. Include
- PKCS12_BROKEN_KEYGEN compilation option to retain the old
- (but broken) behaviour.
- [Steve Henson]
-
- *) Enhance bctest to search for a working bc along $PATH and print
- it when found.
- [Tim Rice <tim@multitalents.net> via Richard Levitte]
-
- *) Fix memory leaks in err.c: free err_data string if necessary;
- don't write to the wrong index in ERR_set_error_data.
- [Bodo Moeller]
-
- *) Implement ssl23_peek (analogous to ssl23_read), which previously
- did not exist.
- [Bodo Moeller]
-
- *) Replace rdtsc with _emit statements for VC++ version 5.
- [Jeremy Cooper <jeremy@baymoo.org>]
-
- *) Make it possible to reuse SSLv2 sessions.
- [Richard Levitte]
-
- *) In copy_email() check for >= 0 as a return value for
- X509_NAME_get_index_by_NID() since 0 is a valid index.
- [Steve Henson reported by Massimiliano Pala <madwolf@opensca.org>]
-
- *) Avoid coredump with unsupported or invalid public keys by checking if
- X509_get_pubkey() fails in PKCS7_verify(). Fix memory leak when
- PKCS7_verify() fails with non detached data.
- [Steve Henson]
-
- *) Don't use getenv in library functions when run as setuid/setgid.
- New function OPENSSL_issetugid().
- [Ulf Moeller]
-
- *) Avoid false positives in memory leak detection code (crypto/mem_dbg.c)
- due to incorrect handling of multi-threading:
-
- 1. Fix timing glitch in the MemCheck_off() portion of CRYPTO_mem_ctrl().
-
- 2. Fix logical glitch in is_MemCheck_on() aka CRYPTO_is_mem_check_on().
-
- 3. Count how many times MemCheck_off() has been called so that
- nested use can be treated correctly. This also avoids
- inband-signalling in the previous code (which relied on the
- assumption that thread ID 0 is impossible).
- [Bodo Moeller]
-
- *) Add "-rand" option also to s_client and s_server.
- [Lutz Jaenicke]
-
- *) Fix CPU detection on Irix 6.x.
- [Kurt Hockenbury <khockenb@stevens-tech.edu> and
- "Bruce W. Forsberg" <bruce.forsberg@baesystems.com>]
-
- *) Fix X509_NAME bug which produced incorrect encoding if X509_NAME
- was empty.
- [Steve Henson]
- [This change does not apply to 0.9.7.]
-
- *) Use the cached encoding of an X509_NAME structure rather than
- copying it. This is apparently the reason for the libsafe "errors"
- but the code is actually correct.
- [Steve Henson]
-
- *) Add new function BN_rand_range(), and fix DSA_sign_setup() to prevent
- Bleichenbacher's DSA attack.
- Extend BN_[pseudo_]rand: As before, top=1 forces the highest two bits
- to be set and top=0 forces the highest bit to be set; top=-1 is new
- and leaves the highest bit random.
- [Ulf Moeller, Bodo Moeller]
-
- *) In the NCONF_...-based implementations for CONF_... queries
- (crypto/conf/conf_lib.c), if the input LHASH is NULL, avoid using
- a temporary CONF structure with the data component set to NULL
- (which gives segmentation faults in lh_retrieve).
- Instead, use NULL for the CONF pointer in CONF_get_string and
- CONF_get_number (which may use environment variables) and directly
- return NULL from CONF_get_section.
- [Bodo Moeller]
-
- *) Fix potential buffer overrun for EBCDIC.
- [Ulf Moeller]
-
- *) Tolerate nonRepudiation as being valid for S/MIME signing and certSign
- keyUsage if basicConstraints absent for a CA.
- [Steve Henson]
-
- *) Make SMIME_write_PKCS7() write mail header values with a format that
- is more generally accepted (no spaces before the semicolon), since
- some programs can't parse those values properly otherwise. Also make
- sure BIO's that break lines after each write do not create invalid
- headers.
- [Richard Levitte]
-
- *) Make the CRL encoding routines work with empty SEQUENCE OF. The
- macros previously used would not encode an empty SEQUENCE OF
- and break the signature.
- [Steve Henson]
- [This change does not apply to 0.9.7.]
-
- *) Zero the premaster secret after deriving the master secret in
- DH ciphersuites.
- [Steve Henson]
-
- *) Add some EVP_add_digest_alias registrations (as found in
- OpenSSL_add_all_digests()) to SSL_library_init()
- aka OpenSSL_add_ssl_algorithms(). This provides improved
- compatibility with peers using X.509 certificates
- with unconventional AlgorithmIdentifier OIDs.
- [Bodo Moeller]
-
- *) Fix for Irix with NO_ASM.
- ["Bruce W. Forsberg" <bruce.forsberg@baesystems.com>]
-
- *) ./config script fixes.
- [Ulf Moeller, Richard Levitte]
-
- *) Fix 'openssl passwd -1'.
- [Bodo Moeller]
-
- *) Change PKCS12_key_gen_asc() so it can cope with non null
- terminated strings whose length is passed in the passlen
- parameter, for example from PEM callbacks. This was done
- by adding an extra length parameter to asc2uni().
- [Steve Henson, reported by <oddissey@samsung.co.kr>]
-
- *) Fix C code generated by 'openssl dsaparam -C': If a BN_bin2bn
- call failed, free the DSA structure.
- [Bodo Moeller]
-
- *) Fix to uni2asc() to cope with zero length Unicode strings.
- These are present in some PKCS#12 files.
- [Steve Henson]
-
- *) Increase s2->wbuf allocation by one byte in ssl2_new (ssl/s2_lib.c).
- Otherwise do_ssl_write (ssl/s2_pkt.c) will write beyond buffer limits
- when writing a 32767 byte record.
- [Bodo Moeller; problem reported by Eric Day <eday@concentric.net>]
-
- *) In RSA_eay_public_{en,ed}crypt and RSA_eay_mod_exp (rsa_eay.c),
- obtain lock CRYPTO_LOCK_RSA before setting rsa->_method_mod_{n,p,q}.
-
- (RSA objects have a reference count access to which is protected
- by CRYPTO_LOCK_RSA [see rsa_lib.c, s3_srvr.c, ssl_cert.c, ssl_rsa.c],
- so they are meant to be shared between threads.)
- [Bodo Moeller, Geoff Thorpe; original patch submitted by
- "Reddie, Steven" <Steven.Reddie@ca.com>]
-
- *) Fix a deadlock in CRYPTO_mem_leaks().
- [Bodo Moeller]
-
- *) Use better test patterns in bntest.
- [Ulf Möller]
-
- *) rand_win.c fix for Borland C.
- [Ulf Möller]
-
- *) BN_rshift bugfix for n == 0.
- [Bodo Moeller]
-
- *) Add a 'bctest' script that checks for some known 'bc' bugs
- so that 'make test' does not abort just because 'bc' is broken.
- [Bodo Moeller]
-
- *) Store verify_result within SSL_SESSION also for client side to
- avoid potential security hole. (Re-used sessions on the client side
- always resulted in verify_result==X509_V_OK, not using the original
- result of the server certificate verification.)
- [Lutz Jaenicke]
-
- *) Fix ssl3_pending: If the record in s->s3->rrec is not of type
- SSL3_RT_APPLICATION_DATA, return 0.
- Similarly, change ssl2_pending to return 0 if SSL_in_init(s) is true.
- [Bodo Moeller]
-
- *) Fix SSL_peek:
- Both ssl2_peek and ssl3_peek, which were totally broken in earlier
- releases, have been re-implemented by renaming the previous
- implementations of ssl2_read and ssl3_read to ssl2_read_internal
- and ssl3_read_internal, respectively, and adding 'peek' parameters
- to them. The new ssl[23]_{read,peek} functions are calls to
- ssl[23]_read_internal with the 'peek' flag set appropriately.
- A 'peek' parameter has also been added to ssl3_read_bytes, which
- does the actual work for ssl3_read_internal.
- [Bodo Moeller]
-
- *) Initialise "ex_data" member of RSA/DSA/DH structures prior to calling
- the method-specific "init()" handler. Also clean up ex_data after
- calling the method-specific "finish()" handler. Previously, this was
- happening the other way round.
- [Geoff Thorpe]
-
- *) Increase BN_CTX_NUM (the number of BIGNUMs in a BN_CTX) to 16.
- The previous value, 12, was not always sufficient for BN_mod_exp().
- [Bodo Moeller]
-
- *) Make sure that shared libraries get the internal name engine with
- the full version number and not just 0. This should mark the
- shared libraries as not backward compatible. Of course, this should
- be changed again when we can guarantee backward binary compatibility.
- [Richard Levitte]
-
- *) Fix typo in get_cert_by_subject() in by_dir.c
- [Jean-Marc Desperrier <jean-marc.desperrier@certplus.com>]
-
- *) Rework the system to generate shared libraries:
-
- - Make note of the expected extension for the shared libraries and
- if there is a need for symbolic links from for example libcrypto.so.0
- to libcrypto.so.0.9.7. There is extended info in Configure for
- that.
-
- - Make as few rebuilds of the shared libraries as possible.
-
- - Still avoid linking the OpenSSL programs with the shared libraries.
-
- - When installing, install the shared libraries separately from the
- static ones.
- [Richard Levitte]
-
- *) Fix SSL_CTX_set_read_ahead macro to actually use its argument.
-
- Copy SSL_CTX's read_ahead flag to SSL object directly in SSL_new
- and not in SSL_clear because the latter is also used by the
- accept/connect functions; previously, the settings made by
- SSL_set_read_ahead would be lost during the handshake.
- [Bodo Moeller; problems reported by Anders Gertz <gertz@epact.se>]
-
- *) Correct util/mkdef.pl to be selective about disabled algorithms.
- Previously, it would create entries for disableed algorithms no
- matter what.
- [Richard Levitte]
-
- *) Added several new manual pages for SSL_* function.
- [Lutz Jaenicke]
-
- Changes between 0.9.5a and 0.9.6 [24 Sep 2000]
-
- *) In ssl23_get_client_hello, generate an error message when faced
- with an initial SSL 3.0/TLS record that is too small to contain the
- first two bytes of the ClientHello message, i.e. client_version.
- (Note that this is a pathologic case that probably has never happened
- in real life.) The previous approach was to use the version number
- from the record header as a substitute; but our protocol choice
- should not depend on that one because it is not authenticated
- by the Finished messages.
- [Bodo Moeller]
-
- *) More robust randomness gathering functions for Windows.
- [Jeffrey Altman <jaltman@columbia.edu>]
-
- *) For compatibility reasons if the flag X509_V_FLAG_ISSUER_CHECK is
- not set then we don't setup the error code for issuer check errors
- to avoid possibly overwriting other errors which the callback does
- handle. If an application does set the flag then we assume it knows
- what it is doing and can handle the new informational codes
- appropriately.
- [Steve Henson]
-
- *) Fix for a nasty bug in ASN1_TYPE handling. ASN1_TYPE is used for
- a general "ANY" type, as such it should be able to decode anything
- including tagged types. However it didn't check the class so it would
- wrongly interpret tagged types in the same way as their universal
- counterpart and unknown types were just rejected. Changed so that the
- tagged and unknown types are handled in the same way as a SEQUENCE:
- that is the encoding is stored intact. There is also a new type
- "V_ASN1_OTHER" which is used when the class is not universal, in this
- case we have no idea what the actual type is so we just lump them all
- together.
- [Steve Henson]
-
- *) On VMS, stdout may very well lead to a file that is written to
- in a record-oriented fashion. That means that every write() will
- write a separate record, which will be read separately by the
- programs trying to read from it. This can be very confusing.
-
- The solution is to put a BIO filter in the way that will buffer
- text until a linefeed is reached, and then write everything a
- line at a time, so every record written will be an actual line,
- not chunks of lines and not (usually doesn't happen, but I've
- seen it once) several lines in one record. BIO_f_linebuffer() is
- the answer.
-
- Currently, it's a VMS-only method, because that's where it has
- been tested well enough.
- [Richard Levitte]
-
- *) Remove 'optimized' squaring variant in BN_mod_mul_montgomery,
- it can return incorrect results.
- (Note: The buggy variant was not enabled in OpenSSL 0.9.5a,
- but it was in 0.9.6-beta[12].)
- [Bodo Moeller]
-
- *) Disable the check for content being present when verifying detached
- signatures in pk7_smime.c. Some versions of Netscape (wrongly)
- include zero length content when signing messages.
- [Steve Henson]
-
- *) New BIO_shutdown_wr macro, which invokes the BIO_C_SHUTDOWN_WR
- BIO_ctrl (for BIO pairs).
- [Bodo Möller]
-
- *) Add DSO method for VMS.
- [Richard Levitte]
-
- *) Bug fix: Montgomery multiplication could produce results with the
- wrong sign.
- [Ulf Möller]
-
- *) Add RPM specification openssl.spec and modify it to build three
- packages. The default package contains applications, application
- documentation and run-time libraries. The devel package contains
- include files, static libraries and function documentation. The
- doc package contains the contents of the doc directory. The original
- openssl.spec was provided by Damien Miller <djm@mindrot.org>.
- [Richard Levitte]
-
- *) Add a large number of documentation files for many SSL routines.
- [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>]
-
- *) Add a configuration entry for Sony News 4.
- [NAKAJI Hiroyuki <nakaji@tutrp.tut.ac.jp>]
-
- *) Don't set the two most significant bits to one when generating a
- random number < q in the DSA library.
- [Ulf Möller]
-
- *) New SSL API mode 'SSL_MODE_AUTO_RETRY'. This disables the default
- behaviour that SSL_read may result in SSL_ERROR_WANT_READ (even if
- the underlying transport is blocking) if a handshake took place.
- (The default behaviour is needed by applications such as s_client
- and s_server that use select() to determine when to use SSL_read;
- but for applications that know in advance when to expect data, it
- just makes things more complicated.)
- [Bodo Moeller]
-
- *) Add RAND_egd_bytes(), which gives control over the number of bytes read
- from EGD.
- [Ben Laurie]
-
- *) Add a few more EBCDIC conditionals that make `req' and `x509'
- work better on such systems.
- [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
-
- *) Add two demo programs for PKCS12_parse() and PKCS12_create().
- Update PKCS12_parse() so it copies the friendlyName and the
- keyid to the certificates aux info.
- [Steve Henson]
-
- *) Fix bug in PKCS7_verify() which caused an infinite loop
- if there was more than one signature.
- [Sven Uszpelkat <su@celocom.de>]
-
- *) Major change in util/mkdef.pl to include extra information
- about each symbol, as well as presentig variables as well
- as functions. This change means that there's n more need
- to rebuild the .num files when some algorithms are excluded.
- [Richard Levitte]
-
- *) Allow the verify time to be set by an application,
- rather than always using the current time.
- [Steve Henson]
-
- *) Phase 2 verify code reorganisation. The certificate
- verify code now looks up an issuer certificate by a
- number of criteria: subject name, authority key id
- and key usage. It also verifies self signed certificates
- by the same criteria. The main comparison function is
- X509_check_issued() which performs these checks.
-
- Lot of changes were necessary in order to support this
- without completely rewriting the lookup code.
-
- Authority and subject key identifier are now cached.
-
- The LHASH 'certs' is X509_STORE has now been replaced
- by a STACK_OF(X509_OBJECT). This is mainly because an
- LHASH can't store or retrieve multiple objects with
- the same hash value.
-
- As a result various functions (which were all internal
- use only) have changed to handle the new X509_STORE
- structure. This will break anything that messed round
- with X509_STORE internally.
-
- The functions X509_STORE_add_cert() now checks for an
- exact match, rather than just subject name.
-
- The X509_STORE API doesn't directly support the retrieval
- of multiple certificates matching a given criteria, however
- this can be worked round by performing a lookup first
- (which will fill the cache with candidate certificates)
- and then examining the cache for matches. This is probably
- the best we can do without throwing out X509_LOOKUP
- entirely (maybe later...).
-
- The X509_VERIFY_CTX structure has been enhanced considerably.
-
- All certificate lookup operations now go via a get_issuer()
- callback. Although this currently uses an X509_STORE it
- can be replaced by custom lookups. This is a simple way
- to bypass the X509_STORE hackery necessary to make this
- work and makes it possible to use more efficient techniques
- in future. A very simple version which uses a simple
- STACK for its trusted certificate store is also provided
- using X509_STORE_CTX_trusted_stack().
-
- The verify_cb() and verify() callbacks now have equivalents
- in the X509_STORE_CTX structure.
-
- X509_STORE_CTX also has a 'flags' field which can be used
- to customise the verify behaviour.
- [Steve Henson]
-
- *) Add new PKCS#7 signing option PKCS7_NOSMIMECAP which
- excludes S/MIME capabilities.
- [Steve Henson]
-
- *) When a certificate request is read in keep a copy of the
- original encoding of the signed data and use it when outputing
- again. Signatures then use the original encoding rather than
- a decoded, encoded version which may cause problems if the
- request is improperly encoded.
- [Steve Henson]
-
- *) For consistency with other BIO_puts implementations, call
- buffer_write(b, ...) directly in buffer_puts instead of calling
- BIO_write(b, ...).
-
- In BIO_puts, increment b->num_write as in BIO_write.
- [Peter.Sylvester@EdelWeb.fr]
-
- *) Fix BN_mul_word for the case where the word is 0. (We have to use
- BN_zero, we may not return a BIGNUM with an array consisting of
- words set to zero.)
- [Bodo Moeller]
-
- *) Avoid calling abort() from within the library when problems are
- detected, except if preprocessor symbols have been defined
- (such as REF_CHECK, BN_DEBUG etc.).
- [Bodo Moeller]
-
- *) New openssl application 'rsautl'. This utility can be
- used for low level RSA operations. DER public key
- BIO/fp routines also added.
- [Steve Henson]
-
- *) New Configure entry and patches for compiling on QNX 4.
- [Andreas Schneider <andreas@ds3.etech.fh-hamburg.de>]
-
- *) A demo state-machine implementation was sponsored by
- Nuron (http://www.nuron.com/) and is now available in
- demos/state_machine.
- [Ben Laurie]
-
- *) New options added to the 'dgst' utility for signature
- generation and verification.
- [Steve Henson]
-
- *) Unrecognized PKCS#7 content types are now handled via a
- catch all ASN1_TYPE structure. This allows unsupported
- types to be stored as a "blob" and an application can
- encode and decode it manually.
- [Steve Henson]
-
- *) Fix various signed/unsigned issues to make a_strex.c
- compile under VC++.
- [Oscar Jacobsson <oscar.jacobsson@celocom.com>]
-
- *) ASN1 fixes. i2d_ASN1_OBJECT was not returning the correct
- length if passed a buffer. ASN1_INTEGER_to_BN failed
- if passed a NULL BN and its argument was negative.
- [Steve Henson, pointed out by Sven Heiberg <sven@tartu.cyber.ee>]
-
- *) Modification to PKCS#7 encoding routines to output definite
- length encoding. Since currently the whole structures are in
- memory there's not real point in using indefinite length
- constructed encoding. However if OpenSSL is compiled with
- the flag PKCS7_INDEFINITE_ENCODING the old form is used.
- [Steve Henson]
-
- *) Added BIO_vprintf() and BIO_vsnprintf().
- [Richard Levitte]
-
- *) Added more prefixes to parse for in the the strings written
- through a logging bio, to cover all the levels that are available
- through syslog. The prefixes are now:
-
- PANIC, EMERG, EMR => LOG_EMERG
- ALERT, ALR => LOG_ALERT
- CRIT, CRI => LOG_CRIT
- ERROR, ERR => LOG_ERR
- WARNING, WARN, WAR => LOG_WARNING
- NOTICE, NOTE, NOT => LOG_NOTICE
- INFO, INF => LOG_INFO
- DEBUG, DBG => LOG_DEBUG
-
- and as before, if none of those prefixes are present at the
- beginning of the string, LOG_ERR is chosen.
-
- On Win32, the LOG_* levels are mapped according to this:
-
- LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR => EVENTLOG_ERROR_TYPE
- LOG_WARNING => EVENTLOG_WARNING_TYPE
- LOG_NOTICE, LOG_INFO, LOG_DEBUG => EVENTLOG_INFORMATION_TYPE
-
- [Richard Levitte]
-
- *) Made it possible to reconfigure with just the configuration
- argument "reconf" or "reconfigure". The command line arguments
- are stored in Makefile.ssl in the variable CONFIGURE_ARGS,
- and are retrieved from there when reconfiguring.
- [Richard Levitte]
-
- *) MD4 implemented.
- [Assar Westerlund <assar@sics.se>, Richard Levitte]
-
- *) Add the arguments -CAfile and -CApath to the pkcs12 utility.
- [Richard Levitte]
-
- *) The obj_dat.pl script was messing up the sorting of object
- names. The reason was that it compared the quoted version
- of strings as a result "OCSP" > "OCSP Signing" because
- " > SPACE. Changed script to store unquoted versions of
- names and add quotes on output. It was also omitting some
- names from the lookup table if they were given a default
- value (that is if SN is missing it is given the same
- value as LN and vice versa), these are now added on the
- grounds that if an object has a name we should be able to
- look it up. Finally added warning output when duplicate
- short or long names are found.
- [Steve Henson]
-
- *) Changes needed for Tandem NSK.
- [Scott Uroff <scott@xypro.com>]
-
- *) Fix SSL 2.0 rollback checking: Due to an off-by-one error in
- RSA_padding_check_SSLv23(), special padding was never detected
- and thus the SSL 3.0/TLS 1.0 countermeasure against protocol
- version rollback attacks was not effective.
-
- In s23_clnt.c, don't use special rollback-attack detection padding
- (RSA_SSLV23_PADDING) if SSL 2.0 is the only protocol enabled in the
- client; similarly, in s23_srvr.c, don't do the rollback check if
- SSL 2.0 is the only protocol enabled in the server.
- [Bodo Moeller]
-
- *) Make it possible to get hexdumps of unprintable data with 'openssl
- asn1parse'. By implication, the functions ASN1_parse_dump() and
- BIO_dump_indent() are added.
- [Richard Levitte]
-
- *) New functions ASN1_STRING_print_ex() and X509_NAME_print_ex()
- these print out strings and name structures based on various
- flags including RFC2253 support and proper handling of
- multibyte characters. Added options to the 'x509' utility
- to allow the various flags to be set.
- [Steve Henson]
-
- *) Various fixes to use ASN1_TIME instead of ASN1_UTCTIME.
- Also change the functions X509_cmp_current_time() and
- X509_gmtime_adj() work with an ASN1_TIME structure,
- this will enable certificates using GeneralizedTime in validity
- dates to be checked.
- [Steve Henson]
-
- *) Make the NEG_PUBKEY_BUG code (which tolerates invalid
- negative public key encodings) on by default,
- NO_NEG_PUBKEY_BUG can be set to disable it.
- [Steve Henson]
-
- *) New function c2i_ASN1_OBJECT() which acts on ASN1_OBJECT
- content octets. An i2c_ASN1_OBJECT is unnecessary because
- the encoding can be trivially obtained from the structure.
- [Steve Henson]
-
- *) crypto/err.c locking bugfix: Use write locks (CRYPTO_w_[un]lock),
- not read locks (CRYPTO_r_[un]lock).
- [Bodo Moeller]
-
- *) A first attempt at creating official support for shared
- libraries through configuration. I've kept it so the
- default is static libraries only, and the OpenSSL programs
- are always statically linked for now, but there are
- preparations for dynamic linking in place.
- This has been tested on Linux and Tru64.
- [Richard Levitte]
-
- *) Randomness polling function for Win9x, as described in:
- Peter Gutmann, Software Generation of Practically Strong
- Random Numbers.
- [Ulf Möller]
-
- *) Fix so PRNG is seeded in req if using an already existing
- DSA key.
- [Steve Henson]
-
- *) New options to smime application. -inform and -outform
- allow alternative formats for the S/MIME message including
- PEM and DER. The -content option allows the content to be
- specified separately. This should allow things like Netscape
- form signing output easier to verify.
- [Steve Henson]
-
- *) Fix the ASN1 encoding of tags using the 'long form'.
- [Steve Henson]
-
- *) New ASN1 functions, i2c_* and c2i_* for INTEGER and BIT
- STRING types. These convert content octets to and from the
- underlying type. The actual tag and length octets are
- already assumed to have been read in and checked. These
- are needed because all other string types have virtually
- identical handling apart from the tag. By having versions
- of the ASN1 functions that just operate on content octets
- IMPLICIT tagging can be handled properly. It also allows
- the ASN1_ENUMERATED code to be cut down because ASN1_ENUMERATED
- and ASN1_INTEGER are identical apart from the tag.
- [Steve Henson]
-
- *) Change the handling of OID objects as follows:
-
- - New object identifiers are inserted in objects.txt, following
- the syntax given in objects.README.
- - objects.pl is used to process obj_mac.num and create a new
- obj_mac.h.
- - obj_dat.pl is used to create a new obj_dat.h, using the data in
- obj_mac.h.
-
- This is currently kind of a hack, and the perl code in objects.pl
- isn't very elegant, but it works as I intended. The simplest way
- to check that it worked correctly is to look in obj_dat.h and
- check the array nid_objs and make sure the objects haven't moved
- around (this is important!). Additions are OK, as well as
- consistent name changes.
- [Richard Levitte]
-
- *) Add BSD-style MD5-based passwords to 'openssl passwd' (option '-1').
- [Bodo Moeller]
-
- *) Addition of the command line parameter '-rand file' to 'openssl req'.
- The given file adds to whatever has already been seeded into the
- random pool through the RANDFILE configuration file option or
- environment variable, or the default random state file.
- [Richard Levitte]
-
- *) mkstack.pl now sorts each macro group into lexical order.
- Previously the output order depended on the order the files
- appeared in the directory, resulting in needless rewriting
- of safestack.h .
- [Steve Henson]
-
- *) Patches to make OpenSSL compile under Win32 again. Mostly
- work arounds for the VC++ problem that it treats func() as
- func(void). Also stripped out the parts of mkdef.pl that
- added extra typesafe functions: these no longer exist.
- [Steve Henson]
-
- *) Reorganisation of the stack code. The macros are now all
- collected in safestack.h . Each macro is defined in terms of
- a "stack macro" of the form SKM_<name>(type, a, b). The
- DEBUG_SAFESTACK is now handled in terms of function casts,
- this has the advantage of retaining type safety without the
- use of additional functions. If DEBUG_SAFESTACK is not defined
- then the non typesafe macros are used instead. Also modified the
- mkstack.pl script to handle the new form. Needs testing to see
- if which (if any) compilers it chokes and maybe make DEBUG_SAFESTACK
- the default if no major problems. Similar behaviour for ASN1_SET_OF
- and PKCS12_STACK_OF.
- [Steve Henson]
-
- *) When some versions of IIS use the 'NET' form of private key the
- key derivation algorithm is different. Normally MD5(password) is
- used as a 128 bit RC4 key. In the modified case
- MD5(MD5(password) + "SGCKEYSALT") is used insted. Added some
- new functions i2d_RSA_NET(), d2i_RSA_NET() etc which are the same
- as the old Netscape_RSA functions except they have an additional
- 'sgckey' parameter which uses the modified algorithm. Also added
- an -sgckey command line option to the rsa utility. Thanks to
- Adrian Peck <bertie@ncipher.com> for posting details of the modified
- algorithm to openssl-dev.
- [Steve Henson]
-
- *) The evp_local.h macros were using 'c.##kname' which resulted in
- invalid expansion on some systems (SCO 5.0.5 for example).
- Corrected to 'c.kname'.
- [Phillip Porch <root@theporch.com>]
-
- *) New X509_get1_email() and X509_REQ_get1_email() functions that return
- a STACK of email addresses from a certificate or request, these look
- in the subject name and the subject alternative name extensions and
- omit any duplicate addresses.
- [Steve Henson]
-
- *) Re-implement BN_mod_exp2_mont using independent (and larger) windows.
- This makes DSA verification about 2 % faster.
- [Bodo Moeller]
-
- *) Increase maximum window size in BN_mod_exp_... to 6 bits instead of 5
- (meaning that now 2^5 values will be precomputed, which is only 4 KB
- plus overhead for 1024 bit moduli).
- This makes exponentiations about 0.5 % faster for 1024 bit
- exponents (as measured by "openssl speed rsa2048").
- [Bodo Moeller]
-
- *) Rename memory handling macros to avoid conflicts with other
- software:
- Malloc => OPENSSL_malloc
- Malloc_locked => OPENSSL_malloc_locked
- Realloc => OPENSSL_realloc
- Free => OPENSSL_free
- [Richard Levitte]
-
- *) New function BN_mod_exp_mont_word for small bases (roughly 15%
- faster than BN_mod_exp_mont, i.e. 7% for a full DH exchange).
- [Bodo Moeller]
-
- *) CygWin32 support.
- [John Jarvie <jjarvie@newsguy.com>]
-
- *) The type-safe stack code has been rejigged. It is now only compiled
- in when OpenSSL is configured with the DEBUG_SAFESTACK option and
- by default all type-specific stack functions are "#define"d back to
- standard stack functions. This results in more streamlined output
- but retains the type-safety checking possibilities of the original
- approach.
- [Geoff Thorpe]
-
- *) The STACK code has been cleaned up, and certain type declarations
- that didn't make a lot of sense have been brought in line. This has
- also involved a cleanup of sorts in safestack.h to more correctly
- map type-safe stack functions onto their plain stack counterparts.
- This work has also resulted in a variety of "const"ifications of
- lots of the code, especially "_cmp" operations which should normally
- be prototyped with "const" parameters anyway.
- [Geoff Thorpe]
-
- *) When generating bytes for the first time in md_rand.c, 'stir the pool'
- by seeding with STATE_SIZE dummy bytes (with zero entropy count).
- (The PRNG state consists of two parts, the large pool 'state' and 'md',
- where all of 'md' is used each time the PRNG is used, but 'state'
- is used only indexed by a cyclic counter. As entropy may not be
- well distributed from the beginning, 'md' is important as a
- chaining variable. However, the output function chains only half
- of 'md', i.e. 80 bits. ssleay_rand_add, on the other hand, chains
- all of 'md', and seeding with STATE_SIZE dummy bytes will result
- in all of 'state' being rewritten, with the new values depending
- on virtually all of 'md'. This overcomes the 80 bit limitation.)
- [Bodo Moeller]
-
- *) In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when
- the handshake is continued after ssl_verify_cert_chain();
- otherwise, if SSL_VERIFY_NONE is set, remaining error codes
- can lead to 'unexplainable' connection aborts later.
- [Bodo Moeller; problem tracked down by Lutz Jaenicke]
-
- *) Major EVP API cipher revision.
- Add hooks for extra EVP features. This allows various cipher
- parameters to be set in the EVP interface. Support added for variable
- key length ciphers via the EVP_CIPHER_CTX_set_key_length() function and
- setting of RC2 and RC5 parameters.
-
- Modify EVP_OpenInit() and EVP_SealInit() to cope with variable key length
- ciphers.
-
- Remove lots of duplicated code from the EVP library. For example *every*
- cipher init() function handles the 'iv' in the same way according to the
- cipher mode. They also all do nothing if the 'key' parameter is NULL and
- for CFB and OFB modes they zero ctx->num.
-
- New functionality allows removal of S/MIME code RC2 hack.
-
- Most of the routines have the same form and so can be declared in terms
- of macros.
-
- By shifting this to the top level EVP_CipherInit() it can be removed from
- all individual ciphers. If the cipher wants to handle IVs or keys
- differently it can set the EVP_CIPH_CUSTOM_IV or EVP_CIPH_ALWAYS_CALL_INIT
- flags.
-
- Change lots of functions like EVP_EncryptUpdate() to now return a
- value: although software versions of the algorithms cannot fail
- any installed hardware versions can.
- [Steve Henson]
-
- *) Implement SSL_OP_TLS_ROLLBACK_BUG: In ssl3_get_client_key_exchange, if
- this option is set, tolerate broken clients that send the negotiated
- protocol version number instead of the requested protocol version
- number.
- [Bodo Moeller]
-
- *) Call dh_tmp_cb (set by ..._TMP_DH_CB) with correct 'is_export' flag;
- i.e. non-zero for export ciphersuites, zero otherwise.
- Previous versions had this flag inverted, inconsistent with
- rsa_tmp_cb (..._TMP_RSA_CB).
- [Bodo Moeller; problem reported by Amit Chopra]
-
- *) Add missing DSA library text string. Work around for some IIS
- key files with invalid SEQUENCE encoding.
- [Steve Henson]
-
- *) Add a document (doc/standards.txt) that list all kinds of standards
- and so on that are implemented in OpenSSL.
- [Richard Levitte]
-
- *) Enhance c_rehash script. Old version would mishandle certificates
- with the same subject name hash and wouldn't handle CRLs at all.
- Added -fingerprint option to crl utility, to support new c_rehash
- features.
- [Steve Henson]
-
- *) Eliminate non-ANSI declarations in crypto.h and stack.h.
- [Ulf Möller]
-
- *) Fix for SSL server purpose checking. Server checking was
- rejecting certificates which had extended key usage present
- but no ssl client purpose.
- [Steve Henson, reported by Rene Grosser <grosser@hisolutions.com>]
-
- *) Make PKCS#12 code work with no password. The PKCS#12 spec
- is a little unclear about how a blank password is handled.
- Since the password in encoded as a BMPString with terminating
- double NULL a zero length password would end up as just the
- double NULL. However no password at all is different and is
- handled differently in the PKCS#12 key generation code. NS
- treats a blank password as zero length. MSIE treats it as no
- password on export: but it will try both on import. We now do
- the same: PKCS12_parse() tries zero length and no password if
- the password is set to "" or NULL (NULL is now a valid password:
- it wasn't before) as does the pkcs12 application.
- [Steve Henson]
-
- *) Bugfixes in apps/x509.c: Avoid a memory leak; and don't use
- perror when PEM_read_bio_X509_REQ fails, the error message must
- be obtained from the error queue.
- [Bodo Moeller]
-
- *) Avoid 'thread_hash' memory leak in crypto/err/err.c by freeing
- it in ERR_remove_state if appropriate, and change ERR_get_state
- accordingly to avoid race conditions (this is necessary because
- thread_hash is no longer constant once set).
- [Bodo Moeller]
-
- *) Bugfix for linux-elf makefile.one.
- [Ulf Möller]
-
- *) RSA_get_default_method() will now cause a default
- RSA_METHOD to be chosen if one doesn't exist already.
- Previously this was only set during a call to RSA_new()
- or RSA_new_method(NULL) meaning it was possible for
- RSA_get_default_method() to return NULL.
- [Geoff Thorpe]
-
- *) Added native name translation to the existing DSO code
- that will convert (if the flag to do so is set) filenames
- that are sufficiently small and have no path information
- into a canonical native form. Eg. "blah" converted to
- "libblah.so" or "blah.dll" etc.
- [Geoff Thorpe]
-
- *) New function ERR_error_string_n(e, buf, len) which is like
- ERR_error_string(e, buf), but writes at most 'len' bytes
- including the 0 terminator. For ERR_error_string_n, 'buf'
- may not be NULL.
- [Damien Miller <djm@mindrot.org>, Bodo Moeller]
-
- *) CONF library reworked to become more general. A new CONF
- configuration file reader "class" is implemented as well as a
- new functions (NCONF_*, for "New CONF") to handle it. The now
- old CONF_* functions are still there, but are reimplemented to
- work in terms of the new functions. Also, a set of functions
- to handle the internal storage of the configuration data is
- provided to make it easier to write new configuration file
- reader "classes" (I can definitely see something reading a
- configuration file in XML format, for example), called _CONF_*,
- or "the configuration storage API"...
-
- The new configuration file reading functions are:
-
- NCONF_new, NCONF_free, NCONF_load, NCONF_load_fp, NCONF_load_bio,
- NCONF_get_section, NCONF_get_string, NCONF_get_numbre
-
- NCONF_default, NCONF_WIN32
-
- NCONF_dump_fp, NCONF_dump_bio
-
- NCONF_default and NCONF_WIN32 are method (or "class") choosers,
- NCONF_new creates a new CONF object. This works in the same way
- as other interfaces in OpenSSL, like the BIO interface.
- NCONF_dump_* dump the internal storage of the configuration file,
- which is useful for debugging. All other functions take the same
- arguments as the old CONF_* functions wth the exception of the
- first that must be a `CONF *' instead of a `LHASH *'.
-
- To make it easer to use the new classes with the old CONF_* functions,
- the function CONF_set_default_method is provided.
- [Richard Levitte]
-
- *) Add '-tls1' option to 'openssl ciphers', which was already
- mentioned in the documentation but had not been implemented.
- (This option is not yet really useful because even the additional
- experimental TLS 1.0 ciphers are currently treated as SSL 3.0 ciphers.)
- [Bodo Moeller]
-
- *) Initial DSO code added into libcrypto for letting OpenSSL (and
- OpenSSL-based applications) load shared libraries and bind to
- them in a portable way.
- [Geoff Thorpe, with contributions from Richard Levitte]
-
- Changes between 0.9.5 and 0.9.5a [1 Apr 2000]
-
- *) Make sure _lrotl and _lrotr are only used with MSVC.
-
- *) Use lock CRYPTO_LOCK_RAND correctly in ssleay_rand_status
- (the default implementation of RAND_status).
-
- *) Rename openssl x509 option '-crlext', which was added in 0.9.5,
- to '-clrext' (= clear extensions), as intended and documented.
- [Bodo Moeller; inconsistency pointed out by Michael Attili
- <attili@amaxo.com>]
-
- *) Fix for HMAC. It wasn't zeroing the rest of the block if the key length
- was larger than the MD block size.
- [Steve Henson, pointed out by Yost William <YostW@tce.com>]
-
- *) Modernise PKCS12_parse() so it uses STACK_OF(X509) for its ca argument
- fix a leak when the ca argument was passed as NULL. Stop X509_PUBKEY_set()
- using the passed key: if the passed key was a private key the result
- of X509_print(), for example, would be to print out all the private key
- components.
- [Steve Henson]
-
- *) des_quad_cksum() byte order bug fix.
- [Ulf Möller, using the problem description in krb4-0.9.7, where
- the solution is attributed to Derrick J Brashear <shadow@DEMENTIA.ORG>]
-
- *) Fix so V_ASN1_APP_CHOOSE works again: however its use is strongly
- discouraged.
- [Steve Henson, pointed out by Brian Korver <briank@cs.stanford.edu>]
-
- *) For easily testing in shell scripts whether some command
- 'openssl XXX' exists, the new pseudo-command 'openssl no-XXX'
- returns with exit code 0 iff no command of the given name is available.
- 'no-XXX' is printed in this case, 'XXX' otherwise. In both cases,
- the output goes to stdout and nothing is printed to stderr.
- Additional arguments are always ignored.
-
- Since for each cipher there is a command of the same name,
- the 'no-cipher' compilation switches can be tested this way.
-
- ('openssl no-XXX' is not able to detect pseudo-commands such
- as 'quit', 'list-XXX-commands', or 'no-XXX' itself.)
- [Bodo Moeller]
-
- *) Update test suite so that 'make test' succeeds in 'no-rsa' configuration.
- [Bodo Moeller]
-
- *) For SSL_[CTX_]set_tmp_dh, don't create a DH key if SSL_OP_SINGLE_DH_USE
- is set; it will be thrown away anyway because each handshake creates
- its own key.
- ssl_cert_dup, which is used by SSL_new, now copies DH keys in addition
- to parameters -- in previous versions (since OpenSSL 0.9.3) the
- 'default key' from SSL_CTX_set_tmp_dh would always be lost, meanining
- you effectivly got SSL_OP_SINGLE_DH_USE when using this macro.
- [Bodo Moeller]
-
- *) New s_client option -ign_eof: EOF at stdin is ignored, and
- 'Q' and 'R' lose their special meanings (quit/renegotiate).
- This is part of what -quiet does; unlike -quiet, -ign_eof
- does not suppress any output.
- [Richard Levitte]
-
- *) Add compatibility options to the purpose and trust code. The
- purpose X509_PURPOSE_ANY is "any purpose" which automatically
- accepts a certificate or CA, this was the previous behaviour,
- with all the associated security issues.
-
- X509_TRUST_COMPAT is the old trust behaviour: only and
- automatically trust self signed roots in certificate store. A
- new trust setting X509_TRUST_DEFAULT is used to specify that
- a purpose has no associated trust setting and it should instead
- use the value in the default purpose.
- [Steve Henson]
-
- *) Fix the PKCS#8 DSA private key code so it decodes keys again
- and fix a memory leak.
- [Steve Henson]
-
- *) In util/mkerr.pl (which implements 'make errors'), preserve
- reason strings from the previous version of the .c file, as
- the default to have only downcase letters (and digits) in
- automatically generated reasons codes is not always appropriate.
- [Bodo Moeller]
-
- *) In ERR_load_ERR_strings(), build an ERR_LIB_SYS error reason table
- using strerror. Previously, ERR_reason_error_string() returned
- library names as reason strings for SYSerr; but SYSerr is a special
- case where small numbers are errno values, not library numbers.
- [Bodo Moeller]
-
- *) Add '-dsaparam' option to 'openssl dhparam' application. This
- converts DSA parameters into DH parameters. (When creating parameters,
- DSA_generate_parameters is used.)
- [Bodo Moeller]
-
- *) Include 'length' (recommended exponent length) in C code generated
- by 'openssl dhparam -C'.
- [Bodo Moeller]
-
- *) The second argument to set_label in perlasm was already being used
- so couldn't be used as a "file scope" flag. Moved to third argument
- which was free.
- [Steve Henson]
-
- *) In PEM_ASN1_write_bio and some other functions, use RAND_pseudo_bytes
- instead of RAND_bytes for encryption IVs and salts.
- [Bodo Moeller]
-
- *) Include RAND_status() into RAND_METHOD instead of implementing
- it only for md_rand.c Otherwise replacing the PRNG by calling
- RAND_set_rand_method would be impossible.
- [Bodo Moeller]
-
- *) Don't let DSA_generate_key() enter an infinite loop if the random
- number generation fails.
- [Bodo Moeller]
-
- *) New 'rand' application for creating pseudo-random output.
- [Bodo Moeller]
-
- *) Added configuration support for Linux/IA64
- [Rolf Haberrecker <rolf@suse.de>]
-
- *) Assembler module support for Mingw32.
- [Ulf Möller]
-
- *) Shared library support for HPUX (in shlib/).
- [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> and Anonymous]
-
- *) Shared library support for Solaris gcc.
- [Lutz Behnke <behnke@trustcenter.de>]
-
- Changes between 0.9.4 and 0.9.5 [28 Feb 2000]
-
- *) PKCS7_encrypt() was adding text MIME headers twice because they
- were added manually and by SMIME_crlf_copy().
- [Steve Henson]
-
- *) In bntest.c don't call BN_rand with zero bits argument.
- [Steve Henson, pointed out by Andrew W. Gray <agray@iconsinc.com>]
-
- *) BN_mul bugfix: In bn_mul_part_recursion() only the a>a[n] && b>b[n]
- case was implemented. This caused BN_div_recp() to fail occasionally.
- [Ulf Möller]
-
- *) Add an optional second argument to the set_label() in the perl
- assembly language builder. If this argument exists and is set
- to 1 it signals that the assembler should use a symbol whose
- scope is the entire file, not just the current function. This
- is needed with MASM which uses the format label:: for this scope.
- [Steve Henson, pointed out by Peter Runestig <peter@runestig.com>]
-
- *) Change the ASN1 types so they are typedefs by default. Before
- almost all types were #define'd to ASN1_STRING which was causing
- STACK_OF() problems: you couldn't declare STACK_OF(ASN1_UTF8STRING)
- for example.
- [Steve Henson]
-
- *) Change names of new functions to the new get1/get0 naming
- convention: After 'get1', the caller owns a reference count
- and has to call ..._free; 'get0' returns a pointer to some
- data structure without incrementing reference counters.
- (Some of the existing 'get' functions increment a reference
- counter, some don't.)
- Similarly, 'set1' and 'add1' functions increase reference
- counters or duplicate objects.
- [Steve Henson]
-
- *) Allow for the possibility of temp RSA key generation failure:
- the code used to assume it always worked and crashed on failure.
- [Steve Henson]
-
- *) Fix potential buffer overrun problem in BIO_printf().
- [Ulf Möller, using public domain code by Patrick Powell; problem
- pointed out by David Sacerdote <das33@cornell.edu>]
-
- *) Support EGD <http://www.lothar.com/tech/crypto/>. New functions
- RAND_egd() and RAND_status(). In the command line application,
- the EGD socket can be specified like a seed file using RANDFILE
- or -rand.
- [Ulf Möller]
-
- *) Allow the string CERTIFICATE to be tolerated in PKCS#7 structures.
- Some CAs (e.g. Verisign) distribute certificates in this form.
- [Steve Henson]
-
- *) Remove the SSL_ALLOW_ADH compile option and set the default cipher
- list to exclude them. This means that no special compilation option
- is needed to use anonymous DH: it just needs to be included in the
- cipher list.
- [Steve Henson]
-
- *) Change the EVP_MD_CTX_type macro so its meaning consistent with
- EVP_MD_type. The old functionality is available in a new macro called
- EVP_MD_md(). Change code that uses it and update docs.
- [Steve Henson]
-
- *) ..._ctrl functions now have corresponding ..._callback_ctrl functions
- where the 'void *' argument is replaced by a function pointer argument.
- Previously 'void *' was abused to point to functions, which works on
- many platforms, but is not correct. As these functions are usually
- called by macros defined in OpenSSL header files, most source code
- should work without changes.
- [Richard Levitte]
-
- *) <openssl/opensslconf.h> (which is created by Configure) now contains
- sections with information on -D... compiler switches used for
- compiling the library so that applications can see them. To enable
- one of these sections, a pre-processor symbol OPENSSL_..._DEFINES
- must be defined. E.g.,
- #define OPENSSL_ALGORITHM_DEFINES
- #include <openssl/opensslconf.h>
- defines all pertinent NO_<algo> symbols, such as NO_IDEA, NO_RSA, etc.
- [Richard Levitte, Ulf and Bodo Möller]
-
- *) Bugfix: Tolerate fragmentation and interleaving in the SSL 3/TLS
- record layer.
- [Bodo Moeller]
-
- *) Change the 'other' type in certificate aux info to a STACK_OF
- X509_ALGOR. Although not an AlgorithmIdentifier as such it has
- the required ASN1 format: arbitrary types determined by an OID.
- [Steve Henson]
-
- *) Add some PEM_write_X509_REQ_NEW() functions and a command line
- argument to 'req'. This is not because the function is newer or
- better than others it just uses the work 'NEW' in the certificate
- request header lines. Some software needs this.
- [Steve Henson]
-
- *) Reorganise password command line arguments: now passwords can be
- obtained from various sources. Delete the PEM_cb function and make
- it the default behaviour: i.e. if the callback is NULL and the
- usrdata argument is not NULL interpret it as a null terminated pass
- phrase. If usrdata and the callback are NULL then the pass phrase
- is prompted for as usual.
- [Steve Henson]
-
- *) Add support for the Compaq Atalla crypto accelerator. If it is installed,
- the support is automatically enabled. The resulting binaries will
- autodetect the card and use it if present.
- [Ben Laurie and Compaq Inc.]
-
- *) Work around for Netscape hang bug. This sends certificate request
- and server done in one record. Since this is perfectly legal in the
- SSL/TLS protocol it isn't a "bug" option and is on by default. See
- the bugs/SSLv3 entry for more info.
- [Steve Henson]
-
- *) HP-UX tune-up: new unified configs, HP C compiler bug workaround.
- [Andy Polyakov]
-
- *) Add -rand argument to smime and pkcs12 applications and read/write
- of seed file.
- [Steve Henson]
-
- *) New 'passwd' tool for crypt(3) and apr1 password hashes.
- [Bodo Moeller]
-
- *) Add command line password options to the remaining applications.
- [Steve Henson]
-
- *) Bug fix for BN_div_recp() for numerators with an even number of
- bits.
- [Ulf Möller]
-
- *) More tests in bntest.c, and changed test_bn output.
- [Ulf Möller]
-
- *) ./config recognizes MacOS X now.
- [Andy Polyakov]
-
- *) Bug fix for BN_div() when the first words of num and divsor are
- equal (it gave wrong results if (rem=(n1-q*d0)&BN_MASK2) < d0).
- [Ulf Möller]
-
- *) Add support for various broken PKCS#8 formats, and command line
- options to produce them.
- [Steve Henson]
-
- *) New functions BN_CTX_start(), BN_CTX_get() and BT_CTX_end() to
- get temporary BIGNUMs from a BN_CTX.
- [Ulf Möller]
-
- *) Correct return values in BN_mod_exp_mont() and BN_mod_exp2_mont()
- for p == 0.
- [Ulf Möller]
-
- *) Change the SSLeay_add_all_*() functions to OpenSSL_add_all_*() and
- include a #define from the old name to the new. The original intent
- was that statically linked binaries could for example just call
- SSLeay_add_all_ciphers() to just add ciphers to the table and not
- link with digests. This never worked becayse SSLeay_add_all_digests()
- and SSLeay_add_all_ciphers() were in the same source file so calling
- one would link with the other. They are now in separate source files.
- [Steve Henson]
-
- *) Add a new -notext option to 'ca' and a -pubkey option to 'spkac'.
- [Steve Henson]
-
- *) Use a less unusual form of the Miller-Rabin primality test (it used
- a binary algorithm for exponentiation integrated into the Miller-Rabin
- loop, our standard modexp algorithms are faster).
- [Bodo Moeller]
-
- *) Support for the EBCDIC character set completed.
- [Martin Kraemer <Martin.Kraemer@Mch.SNI.De>]
-
- *) Source code cleanups: use const where appropriate, eliminate casts,
- use void * instead of char * in lhash.
- [Ulf Möller]
-
- *) Bugfix: ssl3_send_server_key_exchange was not restartable
- (the state was not changed to SSL3_ST_SW_KEY_EXCH_B, and because of
- this the server could overwrite ephemeral keys that the client
- has already seen).
- [Bodo Moeller]
-
- *) Turn DSA_is_prime into a macro that calls BN_is_prime,
- using 50 iterations of the Rabin-Miller test.
-
- DSA_generate_parameters now uses BN_is_prime_fasttest (with 50
- iterations of the Rabin-Miller test as required by the appendix
- to FIPS PUB 186[-1]) instead of DSA_is_prime.
- As BN_is_prime_fasttest includes trial division, DSA parameter
- generation becomes much faster.
-
- This implies a change for the callback functions in DSA_is_prime
- and DSA_generate_parameters: The callback function is called once
- for each positive witness in the Rabin-Miller test, not just
- occasionally in the inner loop; and the parameters to the
- callback function now provide an iteration count for the outer
- loop rather than for the current invocation of the inner loop.
- DSA_generate_parameters additionally can call the callback
- function with an 'iteration count' of -1, meaning that a
- candidate has passed the trial division test (when q is generated
- from an application-provided seed, trial division is skipped).
- [Bodo Moeller]
-
- *) New function BN_is_prime_fasttest that optionally does trial
- division before starting the Rabin-Miller test and has
- an additional BN_CTX * argument (whereas BN_is_prime always
- has to allocate at least one BN_CTX).
- 'callback(1, -1, cb_arg)' is called when a number has passed the
- trial division stage.
- [Bodo Moeller]
-
- *) Fix for bug in CRL encoding. The validity dates weren't being handled
- as ASN1_TIME.
- [Steve Henson]
-
- *) New -pkcs12 option to CA.pl script to write out a PKCS#12 file.
- [Steve Henson]
-
- *) New function BN_pseudo_rand().
- [Ulf Möller]
-
- *) Clean up BN_mod_mul_montgomery(): replace the broken (and unreadable)
- bignum version of BN_from_montgomery() with the working code from
- SSLeay 0.9.0 (the word based version is faster anyway), and clean up
- the comments.
- [Ulf Möller]
-
- *) Avoid a race condition in s2_clnt.c (function get_server_hello) that
- made it impossible to use the same SSL_SESSION data structure in
- SSL2 clients in multiple threads.
- [Bodo Moeller]
-
- *) The return value of RAND_load_file() no longer counts bytes obtained
- by stat(). RAND_load_file(..., -1) is new and uses the complete file
- to seed the PRNG (previously an explicit byte count was required).
- [Ulf Möller, Bodo Möller]
-
- *) Clean up CRYPTO_EX_DATA functions, some of these didn't have prototypes
- used (char *) instead of (void *) and had casts all over the place.
- [Steve Henson]
-
- *) Make BN_generate_prime() return NULL on error if ret!=NULL.
- [Ulf Möller]
-
- *) Retain source code compatibility for BN_prime_checks macro:
- BN_is_prime(..., BN_prime_checks, ...) now uses
- BN_prime_checks_for_size to determine the appropriate number of
- Rabin-Miller iterations.
- [Ulf Möller]
-
- *) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to
- DH_CHECK_P_NOT_SAFE_PRIME.
- (Check if this is true? OpenPGP calls them "strong".)
- [Ulf Möller]
-
- *) Merge the functionality of "dh" and "gendh" programs into a new program
- "dhparam". The old programs are retained for now but will handle DH keys
- (instead of parameters) in future.
- [Steve Henson]
-
- *) Make the ciphers, s_server and s_client programs check the return values
- when a new cipher list is set.
- [Steve Henson]
-
- *) Enhance the SSL/TLS cipher mechanism to correctly handle the TLS 56bit
- ciphers. Before when the 56bit ciphers were enabled the sorting was
- wrong.
-
- The syntax for the cipher sorting has been extended to support sorting by
- cipher-strength (using the strength_bits hard coded in the tables).
- The new command is "@STRENGTH" (see also doc/apps/ciphers.pod).
-
- Fix a bug in the cipher-command parser: when supplying a cipher command
- string with an "undefined" symbol (neither command nor alphanumeric
- [A-Za-z0-9], ssl_set_cipher_list used to hang in an endless loop. Now
- an error is flagged.
-
- Due to the strength-sorting extension, the code of the
- ssl_create_cipher_list() function was completely rearranged. I hope that
- the readability was also increased :-)
- [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>]
-
- *) Minor change to 'x509' utility. The -CAcreateserial option now uses 1
- for the first serial number and places 2 in the serial number file. This
- avoids problems when the root CA is created with serial number zero and
- the first user certificate has the same issuer name and serial number
- as the root CA.
- [Steve Henson]
-
- *) Fixes to X509_ATTRIBUTE utilities, change the 'req' program so it uses
- the new code. Add documentation for this stuff.
- [Steve Henson]
-
- *) Changes to X509_ATTRIBUTE utilities. These have been renamed from
- X509_*() to X509at_*() on the grounds that they don't handle X509
- structures and behave in an analagous way to the X509v3 functions:
- they shouldn't be called directly but wrapper functions should be used
- instead.
-
- So we also now have some wrapper functions that call the X509at functions
- when passed certificate requests. (TO DO: similar things can be done with
- PKCS#7 signed and unsigned attributes, PKCS#12 attributes and a few other
- things. Some of these need some d2i or i2d and print functionality
- because they handle more complex structures.)
- [Steve Henson]
-
- *) Add missing #ifndefs that caused missing symbols when building libssl
- as a shared library without RSA. Use #ifndef NO_SSL2 instead of
- NO_RSA in ssl/s2*.c.
- [Kris Kennaway <kris@hub.freebsd.org>, modified by Ulf Möller]
-
- *) Precautions against using the PRNG uninitialized: RAND_bytes() now
- has a return value which indicates the quality of the random data
- (1 = ok, 0 = not seeded). Also an error is recorded on the thread's
- error queue. New function RAND_pseudo_bytes() generates output that is
- guaranteed to be unique but not unpredictable. RAND_add is like
- RAND_seed, but takes an extra argument for an entropy estimate
- (RAND_seed always assumes full entropy).
- [Ulf Möller]
-
- *) Do more iterations of Rabin-Miller probable prime test (specifically,
- 3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes
- instead of only 2 for all lengths; see BN_prime_checks_for_size definition
- in crypto/bn/bn_prime.c for the complete table). This guarantees a
- false-positive rate of at most 2^-80 for random input.
- [Bodo Moeller]
-
- *) Rewrite ssl3_read_n (ssl/s3_pkt.c) avoiding a couple of bugs.
- [Bodo Moeller]
-
- *) New function X509_CTX_rget_chain() (renamed to X509_CTX_get1_chain
- in the 0.9.5 release), this returns the chain
- from an X509_CTX structure with a dup of the stack and all
- the X509 reference counts upped: so the stack will exist
- after X509_CTX_cleanup() has been called. Modify pkcs12.c
- to use this.
-
- Also make SSL_SESSION_print() print out the verify return
- code.
- [Steve Henson]
-
- *) Add manpage for the pkcs12 command. Also change the default
- behaviour so MAC iteration counts are used unless the new
- -nomaciter option is used. This improves file security and
- only older versions of MSIE (4.0 for example) need it.
- [Steve Henson]
-
- *) Honor the no-xxx Configure options when creating .DEF files.
- [Ulf Möller]
-
- *) Add PKCS#10 attributes to field table: challengePassword,
- unstructuredName and unstructuredAddress. These are taken from
- draft PKCS#9 v2.0 but are compatible with v1.2 provided no
- international characters are used.
-
- More changes to X509_ATTRIBUTE code: allow the setting of types
- based on strings. Remove the 'loc' parameter when adding
- attributes because these will be a SET OF encoding which is sorted
- in ASN1 order.
- [Steve Henson]
-
- *) Initial changes to the 'req' utility to allow request generation
- automation. This will allow an application to just generate a template
- file containing all the field values and have req construct the
- request.
-
- Initial support for X509_ATTRIBUTE handling. Stacks of these are
- used all over the place including certificate requests and PKCS#7
- structures. They are currently handled manually where necessary with
- some primitive wrappers for PKCS#7. The new functions behave in a
- manner analogous to the X509 extension functions: they allow
- attributes to be looked up by NID and added.
-
- Later something similar to the X509V3 code would be desirable to
- automatically handle the encoding, decoding and printing of the
- more complex types. The string types like challengePassword can
- be handled by the string table functions.
-
- Also modified the multi byte string table handling. Now there is
- a 'global mask' which masks out certain types. The table itself
- can use the flag STABLE_NO_MASK to ignore the mask setting: this
- is useful when for example there is only one permissible type
- (as in countryName) and using the mask might result in no valid
- types at all.
- [Steve Henson]
-
- *) Clean up 'Finished' handling, and add functions SSL_get_finished and
- SSL_get_peer_finished to allow applications to obtain the latest
- Finished messages sent to the peer or expected from the peer,
- respectively. (SSL_get_peer_finished is usually the Finished message
- actually received from the peer, otherwise the protocol will be aborted.)
-
- As the Finished message are message digests of the complete handshake
- (with a total of 192 bits for TLS 1.0 and more for SSL 3.0), they can
- be used for external authentication procedures when the authentication
- provided by SSL/TLS is not desired or is not enough.
- [Bodo Moeller]
-
- *) Enhanced support for Alpha Linux is added. Now ./config checks if
- the host supports BWX extension and if Compaq C is present on the
- $PATH. Just exploiting of the BWX extension results in 20-30%
- performance kick for some algorithms, e.g. DES and RC4 to mention
- a couple. Compaq C in turn generates ~20% faster code for MD5 and
- SHA1.
- [Andy Polyakov]
-
- *) Add support for MS "fast SGC". This is arguably a violation of the
- SSL3/TLS protocol. Netscape SGC does two handshakes: the first with
- weak crypto and after checking the certificate is SGC a second one
- with strong crypto. MS SGC stops the first handshake after receiving
- the server certificate message and sends a second client hello. Since
- a server will typically do all the time consuming operations before
- expecting any further messages from the client (server key exchange
- is the most expensive) there is little difference between the two.
-
- To get OpenSSL to support MS SGC we have to permit a second client
- hello message after we have sent server done. In addition we have to
- reset the MAC if we do get this second client hello.
- [Steve Henson]
-
- *) Add a function 'd2i_AutoPrivateKey()' this will automatically decide
- if a DER encoded private key is RSA or DSA traditional format. Changed
- d2i_PrivateKey_bio() to use it. This is only needed for the "traditional"
- format DER encoded private key. Newer code should use PKCS#8 format which
- has the key type encoded in the ASN1 structure. Added DER private key
- support to pkcs8 application.
- [Steve Henson]
-
- *) SSL 3/TLS 1 servers now don't request certificates when an anonymous
- ciphersuites has been selected (as required by the SSL 3/TLS 1
- specifications). Exception: When SSL_VERIFY_FAIL_IF_NO_PEER_CERT
- is set, we interpret this as a request to violate the specification
- (the worst that can happen is a handshake failure, and 'correct'
- behaviour would result in a handshake failure anyway).
- [Bodo Moeller]
-
- *) In SSL_CTX_add_session, take into account that there might be multiple
- SSL_SESSION structures with the same session ID (e.g. when two threads
- concurrently obtain them from an external cache).
- The internal cache can handle only one SSL_SESSION with a given ID,
- so if there's a conflict, we now throw out the old one to achieve
- consistency.
- [Bodo Moeller]
-
- *) Add OIDs for idea and blowfish in CBC mode. This will allow both
- to be used in PKCS#5 v2.0 and S/MIME. Also add checking to
- some routines that use cipher OIDs: some ciphers do not have OIDs
- defined and so they cannot be used for S/MIME and PKCS#5 v2.0 for
- example.
- [Steve Henson]
-
- *) Simplify the trust setting structure and code. Now we just have
- two sequences of OIDs for trusted and rejected settings. These will
- typically have values the same as the extended key usage extension
- and any application specific purposes.
-
- The trust checking code now has a default behaviour: it will just
- check for an object with the same NID as the passed id. Functions can
- be provided to override either the default behaviour or the behaviour
- for a given id. SSL client, server and email already have functions
- in place for compatibility: they check the NID and also return "trusted"
- if the certificate is self signed.
- [Steve Henson]
-
- *) Add d2i,i2d bio/fp functions for PrivateKey: these convert the
- traditional format into an EVP_PKEY structure.
- [Steve Henson]
-
- *) Add a password callback function PEM_cb() which either prompts for
- a password if usr_data is NULL or otherwise assumes it is a null
- terminated password. Allow passwords to be passed on command line
- environment or config files in a few more utilities.
- [Steve Henson]
-
- *) Add a bunch of DER and PEM functions to handle PKCS#8 format private
- keys. Add some short names for PKCS#8 PBE algorithms and allow them
- to be specified on the command line for the pkcs8 and pkcs12 utilities.
- Update documentation.
- [Steve Henson]
-
- *) Support for ASN1 "NULL" type. This could be handled before by using
- ASN1_TYPE but there wasn't any function that would try to read a NULL
- and produce an error if it couldn't. For compatibility we also have
- ASN1_NULL_new() and ASN1_NULL_free() functions but these are faked and
- don't allocate anything because they don't need to.
- [Steve Henson]
-
- *) Initial support for MacOS is now provided. Examine INSTALL.MacOS
- for details.
- [Andy Polyakov, Roy Woods <roy@centicsystems.ca>]
-
- *) Rebuild of the memory allocation routines used by OpenSSL code and
- possibly others as well. The purpose is to make an interface that
- provide hooks so anyone can build a separate set of allocation and
- deallocation routines to be used by OpenSSL, for example memory
- pool implementations, or something else, which was previously hard
- since Malloc(), Realloc() and Free() were defined as macros having
- the values malloc, realloc and free, respectively (except for Win32
- compilations). The same is provided for memory debugging code.
- OpenSSL already comes with functionality to find memory leaks, but
- this gives people a chance to debug other memory problems.
-
- With these changes, a new set of functions and macros have appeared:
-
- CRYPTO_set_mem_debug_functions() [F]
- CRYPTO_get_mem_debug_functions() [F]
- CRYPTO_dbg_set_options() [F]
- CRYPTO_dbg_get_options() [F]
- CRYPTO_malloc_debug_init() [M]
-
- The memory debug functions are NULL by default, unless the library
- is compiled with CRYPTO_MDEBUG or friends is defined. If someone
- wants to debug memory anyway, CRYPTO_malloc_debug_init() (which
- gives the standard debugging functions that come with OpenSSL) or
- CRYPTO_set_mem_debug_functions() (tells OpenSSL to use functions
- provided by the library user) must be used. When the standard
- debugging functions are used, CRYPTO_dbg_set_options can be used to
- request additional information:
- CRYPTO_dbg_set_options(V_CYRPTO_MDEBUG_xxx) corresponds to setting
- the CRYPTO_MDEBUG_xxx macro when compiling the library.
-
- Also, things like CRYPTO_set_mem_functions will always give the
- expected result (the new set of functions is used for allocation
- and deallocation) at all times, regardless of platform and compiler
- options.
-
- To finish it up, some functions that were never use in any other
- way than through macros have a new API and new semantic:
-
- CRYPTO_dbg_malloc()
- CRYPTO_dbg_realloc()
- CRYPTO_dbg_free()
-
- All macros of value have retained their old syntax.
- [Richard Levitte and Bodo Moeller]
-
- *) Some S/MIME fixes. The OID for SMIMECapabilities was wrong, the
- ordering of SMIMECapabilities wasn't in "strength order" and there
- was a missing NULL in the AlgorithmIdentifier for the SHA1 signature
- algorithm.
- [Steve Henson]
-
- *) Some ASN1 types with illegal zero length encoding (INTEGER,
- ENUMERATED and OBJECT IDENTIFIER) choked the ASN1 routines.
- [Frans Heymans <fheymans@isaserver.be>, modified by Steve Henson]
-
- *) Merge in my S/MIME library for OpenSSL. This provides a simple
- S/MIME API on top of the PKCS#7 code, a MIME parser (with enough
- functionality to handle multipart/signed properly) and a utility
- called 'smime' to call all this stuff. This is based on code I
- originally wrote for Celo who have kindly allowed it to be
- included in OpenSSL.
- [Steve Henson]
-
- *) Add variants des_set_key_checked and des_set_key_unchecked of
- des_set_key (aka des_key_sched). Global variable des_check_key
- decides which of these is called by des_set_key; this way
- des_check_key behaves as it always did, but applications and
- the library itself, which was buggy for des_check_key == 1,
- have a cleaner way to pick the version they need.
- [Bodo Moeller]
-
- *) New function PKCS12_newpass() which changes the password of a
- PKCS12 structure.
- [Steve Henson]
-
- *) Modify X509_TRUST and X509_PURPOSE so it also uses a static and
- dynamic mix. In both cases the ids can be used as an index into the
- table. Also modified the X509_TRUST_add() and X509_PURPOSE_add()
- functions so they accept a list of the field values and the
- application doesn't need to directly manipulate the X509_TRUST
- structure.
- [Steve Henson]
-
- *) Modify the ASN1_STRING_TABLE stuff so it also uses bsearch and doesn't
- need initialising.
- [Steve Henson]
-
- *) Modify the way the V3 extension code looks up extensions. This now
- works in a similar way to the object code: we have some "standard"
- extensions in a static table which is searched with OBJ_bsearch()
- and the application can add dynamic ones if needed. The file
- crypto/x509v3/ext_dat.h now has the info: this file needs to be
- updated whenever a new extension is added to the core code and kept
- in ext_nid order. There is a simple program 'tabtest.c' which checks
- this. New extensions are not added too often so this file can readily
- be maintained manually.
-
- There are two big advantages in doing things this way. The extensions
- can be looked up immediately and no longer need to be "added" using
- X509V3_add_standard_extensions(): this function now does nothing.
- [Side note: I get *lots* of email saying the extension code doesn't
- work because people forget to call this function]
- Also no dynamic allocation is done unless new extensions are added:
- so if we don't add custom extensions there is no need to call
- X509V3_EXT_cleanup().
- [Steve Henson]
-
- *) Modify enc utility's salting as follows: make salting the default. Add a
- magic header, so unsalted files fail gracefully instead of just decrypting
- to garbage. This is because not salting is a big security hole, so people
- should be discouraged from doing it.
- [Ben Laurie]
-
- *) Fixes and enhancements to the 'x509' utility. It allowed a message
- digest to be passed on the command line but it only used this
- parameter when signing a certificate. Modified so all relevant
- operations are affected by the digest parameter including the
- -fingerprint and -x509toreq options. Also -x509toreq choked if a
- DSA key was used because it didn't fix the digest.
- [Steve Henson]
-
- *) Initial certificate chain verify code. Currently tests the untrusted
- certificates for consistency with the verify purpose (which is set
- when the X509_STORE_CTX structure is set up) and checks the pathlength.
-
- There is a NO_CHAIN_VERIFY compilation option to keep the old behaviour:
- this is because it will reject chains with invalid extensions whereas
- every previous version of OpenSSL and SSLeay made no checks at all.
-
- Trust code: checks the root CA for the relevant trust settings. Trust
- settings have an initial value consistent with the verify purpose: e.g.
- if the verify purpose is for SSL client use it expects the CA to be
- trusted for SSL client use. However the default value can be changed to
- permit custom trust settings: one example of this would be to only trust
- certificates from a specific "secure" set of CAs.
-
- Also added X509_STORE_CTX_new() and X509_STORE_CTX_free() functions
- which should be used for version portability: especially since the
- verify structure is likely to change more often now.
-
- SSL integration. Add purpose and trust to SSL_CTX and SSL and functions
- to set them. If not set then assume SSL clients will verify SSL servers
- and vice versa.
-
- Two new options to the verify program: -untrusted allows a set of
- untrusted certificates to be passed in and -purpose which sets the
- intended purpose of the certificate. If a purpose is set then the
- new chain verify code is used to check extension consistency.
- [Steve Henson]
-
- *) Support for the authority information access extension.
- [Steve Henson]
-
- *) Modify RSA and DSA PEM read routines to transparently handle
- PKCS#8 format private keys. New *_PUBKEY_* functions that handle
- public keys in a format compatible with certificate
- SubjectPublicKeyInfo structures. Unfortunately there were already
- functions called *_PublicKey_* which used various odd formats so
- these are retained for compatibility: however the DSA variants were
- never in a public release so they have been deleted. Changed dsa/rsa
- utilities to handle the new format: note no releases ever handled public
- keys so we should be OK.
-
- The primary motivation for this change is to avoid the same fiasco
- that dogs private keys: there are several incompatible private key
- formats some of which are standard and some OpenSSL specific and
- require various evil hacks to allow partial transparent handling and
- even then it doesn't work with DER formats. Given the option anything
- other than PKCS#8 should be dumped: but the other formats have to
- stay in the name of compatibility.
-
- With public keys and the benefit of hindsight one standard format
- is used which works with EVP_PKEY, RSA or DSA structures: though
- it clearly returns an error if you try to read the wrong kind of key.
-
- Added a -pubkey option to the 'x509' utility to output the public key.
- Also rename the EVP_PKEY_get_*() to EVP_PKEY_rget_*()
- (renamed to EVP_PKEY_get1_*() in the OpenSSL 0.9.5 release) and add
- EVP_PKEY_rset_*() functions (renamed to EVP_PKEY_set1_*())
- that do the same as the EVP_PKEY_assign_*() except they up the
- reference count of the added key (they don't "swallow" the
- supplied key).
- [Steve Henson]
-
- *) Fixes to crypto/x509/by_file.c the code to read in certificates and
- CRLs would fail if the file contained no certificates or no CRLs:
- added a new function to read in both types and return the number
- read: this means that if none are read it will be an error. The
- DER versions of the certificate and CRL reader would always fail
- because it isn't possible to mix certificates and CRLs in DER format
- without choking one or the other routine. Changed this to just read
- a certificate: this is the best we can do. Also modified the code
- in apps/verify.c to take notice of return codes: it was previously
- attempting to read in certificates from NULL pointers and ignoring
- any errors: this is one reason why the cert and CRL reader seemed
- to work. It doesn't check return codes from the default certificate
- routines: these may well fail if the certificates aren't installed.
- [Steve Henson]
-
- *) Code to support otherName option in GeneralName.
- [Steve Henson]
-
- *) First update to verify code. Change the verify utility
- so it warns if it is passed a self signed certificate:
- for consistency with the normal behaviour. X509_verify
- has been modified to it will now verify a self signed
- certificate if *exactly* the same certificate appears
- in the store: it was previously impossible to trust a
- single self signed certificate. This means that:
- openssl verify ss.pem
- now gives a warning about a self signed certificate but
- openssl verify -CAfile ss.pem ss.pem
- is OK.
- [Steve Henson]
-
- *) For servers, store verify_result in SSL_SESSION data structure
- (and add it to external session representation).
- This is needed when client certificate verifications fails,
- but an application-provided verification callback (set by
- SSL_CTX_set_cert_verify_callback) allows accepting the session
- anyway (i.e. leaves x509_store_ctx->error != X509_V_OK
- but returns 1): When the session is reused, we have to set
- ssl->verify_result to the appropriate error code to avoid
- security holes.
- [Bodo Moeller, problem pointed out by Lutz Jaenicke]
-
- *) Fix a bug in the new PKCS#7 code: it didn't consider the
- case in PKCS7_dataInit() where the signed PKCS7 structure
- didn't contain any existing data because it was being created.
- [Po-Cheng Chen <pocheng@nst.com.tw>, slightly modified by Steve Henson]
-
- *) Add a salt to the key derivation routines in enc.c. This
- forms the first 8 bytes of the encrypted file. Also add a
- -S option to allow a salt to be input on the command line.
- [Steve Henson]
-
- *) New function X509_cmp(). Oddly enough there wasn't a function
- to compare two certificates. We do this by working out the SHA1
- hash and comparing that. X509_cmp() will be needed by the trust
- code.
- [Steve Henson]
-
- *) SSL_get1_session() is like SSL_get_session(), but increments
- the reference count in the SSL_SESSION returned.
- [Geoff Thorpe <geoff@eu.c2.net>]
-
- *) Fix for 'req': it was adding a null to request attributes.
- Also change the X509_LOOKUP and X509_INFO code to handle
- certificate auxiliary information.
- [Steve Henson]
-
- *) Add support for 40 and 64 bit RC2 and RC4 algorithms: document
- the 'enc' command.
- [Steve Henson]
-
- *) Add the possibility to add extra information to the memory leak
- detecting output, to form tracebacks, showing from where each
- allocation was originated: CRYPTO_push_info("constant string") adds
- the string plus current file name and line number to a per-thread
- stack, CRYPTO_pop_info() does the obvious, CRYPTO_remove_all_info()
- is like calling CYRPTO_pop_info() until the stack is empty.
- Also updated memory leak detection code to be multi-thread-safe.
- [Richard Levitte]
-
- *) Add options -text and -noout to pkcs7 utility and delete the
- encryption options which never did anything. Update docs.
- [Steve Henson]
-
- *) Add options to some of the utilities to allow the pass phrase
- to be included on either the command line (not recommended on
- OSes like Unix) or read from the environment. Update the
- manpages and fix a few bugs.
- [Steve Henson]
-
- *) Add a few manpages for some of the openssl commands.
- [Steve Henson]
-
- *) Fix the -revoke option in ca. It was freeing up memory twice,
- leaking and not finding already revoked certificates.
- [Steve Henson]
-
- *) Extensive changes to support certificate auxiliary information.
- This involves the use of X509_CERT_AUX structure and X509_AUX
- functions. An X509_AUX function such as PEM_read_X509_AUX()
- can still read in a certificate file in the usual way but it
- will also read in any additional "auxiliary information". By
- doing things this way a fair degree of compatibility can be
- retained: existing certificates can have this information added
- using the new 'x509' options.
-
- Current auxiliary information includes an "alias" and some trust
- settings. The trust settings will ultimately be used in enhanced
- certificate chain verification routines: currently a certificate
- can only be trusted if it is self signed and then it is trusted
- for all purposes.
- [Steve Henson]
-
- *) Fix assembler for Alpha (tested only on DEC OSF not Linux or *BSD).
- The problem was that one of the replacement routines had not been working
- since SSLeay releases. For now the offending routine has been replaced
- with non-optimised assembler. Even so, this now gives around 95%
- performance improvement for 1024 bit RSA signs.
- [Mark Cox]
-
- *) Hack to fix PKCS#7 decryption when used with some unorthodox RC2
- handling. Most clients have the effective key size in bits equal to
- the key length in bits: so a 40 bit RC2 key uses a 40 bit (5 byte) key.
- A few however don't do this and instead use the size of the decrypted key
- to determine the RC2 key length and the AlgorithmIdentifier to determine
- the effective key length. In this case the effective key length can still
- be 40 bits but the key length can be 168 bits for example. This is fixed
- by manually forcing an RC2 key into the EVP_PKEY structure because the
- EVP code can't currently handle unusual RC2 key sizes: it always assumes
- the key length and effective key length are equal.
- [Steve Henson]
-
- *) Add a bunch of functions that should simplify the creation of
- X509_NAME structures. Now you should be able to do:
- X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, "Steve", -1, -1, 0);
- and have it automatically work out the correct field type and fill in
- the structures. The more adventurous can try:
- X509_NAME_add_entry_by_txt(nm, field, MBSTRING_UTF8, str, -1, -1, 0);
- and it will (hopefully) work out the correct multibyte encoding.
- [Steve Henson]
-
- *) Change the 'req' utility to use the new field handling and multibyte
- copy routines. Before the DN field creation was handled in an ad hoc
- way in req, ca, and x509 which was rather broken and didn't support
- BMPStrings or UTF8Strings. Since some software doesn't implement
- BMPStrings or UTF8Strings yet, they can be enabled using the config file
- using the dirstring_type option. See the new comment in the default
- openssl.cnf for more info.
- [Steve Henson]
-
- *) Make crypto/rand/md_rand.c more robust:
- - Assure unique random numbers after fork().
- - Make sure that concurrent threads access the global counter and
- md serializably so that we never lose entropy in them
- or use exactly the same state in multiple threads.
- Access to the large state is not always serializable because
- the additional locking could be a performance killer, and
- md should be large enough anyway.
- [Bodo Moeller]
-
- *) New file apps/app_rand.c with commonly needed functionality
- for handling the random seed file.
-
- Use the random seed file in some applications that previously did not:
- ca,
- dsaparam -genkey (which also ignored its '-rand' option),
- s_client,
- s_server,
- x509 (when signing).
- Except on systems with /dev/urandom, it is crucial to have a random
- seed file at least for key creation, DSA signing, and for DH exchanges;
- for RSA signatures we could do without one.
-
- gendh and gendsa (unlike genrsa) used to read only the first byte
- of each file listed in the '-rand' option. The function as previously
- found in genrsa is now in app_rand.c and is used by all programs
- that support '-rand'.
- [Bodo Moeller]
-
- *) In RAND_write_file, use mode 0600 for creating files;
- don't just chmod when it may be too late.
- [Bodo Moeller]
-
- *) Report an error from X509_STORE_load_locations
- when X509_LOOKUP_load_file or X509_LOOKUP_add_dir failed.
- [Bill Perry]
-
- *) New function ASN1_mbstring_copy() this copies a string in either
- ASCII, Unicode, Universal (4 bytes per character) or UTF8 format
- into an ASN1_STRING type. A mask of permissible types is passed
- and it chooses the "minimal" type to use or an error if not type
- is suitable.
- [Steve Henson]
-
- *) Add function equivalents to the various macros in asn1.h. The old
- macros are retained with an M_ prefix. Code inside the library can
- use the M_ macros. External code (including the openssl utility)
- should *NOT* in order to be "shared library friendly".
- [Steve Henson]
-
- *) Add various functions that can check a certificate's extensions
- to see if it usable for various purposes such as SSL client,
- server or S/MIME and CAs of these types. This is currently
- VERY EXPERIMENTAL but will ultimately be used for certificate chain
- verification. Also added a -purpose flag to x509 utility to
- print out all the purposes.
- [Steve Henson]
-
- *) Add a CRYPTO_EX_DATA to X509 certificate structure and associated
- functions.
- [Steve Henson]
-
- *) New X509V3_{X509,CRL,REVOKED}_get_d2i() functions. These will search
- for, obtain and decode and extension and obtain its critical flag.
- This allows all the necessary extension code to be handled in a
- single function call.
- [Steve Henson]
-
- *) RC4 tune-up featuring 30-40% performance improvement on most RISC
- platforms. See crypto/rc4/rc4_enc.c for further details.
- [Andy Polyakov]
-
- *) New -noout option to asn1parse. This causes no output to be produced
- its main use is when combined with -strparse and -out to extract data
- from a file (which may not be in ASN.1 format).
- [Steve Henson]
-
- *) Fix for pkcs12 program. It was hashing an invalid certificate pointer
- when producing the local key id.
- [Richard Levitte <levitte@stacken.kth.se>]
-
- *) New option -dhparam in s_server. This allows a DH parameter file to be
- stated explicitly. If it is not stated then it tries the first server
- certificate file. The previous behaviour hard coded the filename
- "server.pem".
- [Steve Henson]
-
- *) Add -pubin and -pubout options to the rsa and dsa commands. These allow
- a public key to be input or output. For example:
- openssl rsa -in key.pem -pubout -out pubkey.pem
- Also added necessary DSA public key functions to handle this.
- [Steve Henson]
-
- *) Fix so PKCS7_dataVerify() doesn't crash if no certificates are contained
- in the message. This was handled by allowing
- X509_find_by_issuer_and_serial() to tolerate a NULL passed to it.
- [Steve Henson, reported by Sampo Kellomaki <sampo@mail.neuronio.pt>]
-
- *) Fix for bug in d2i_ASN1_bytes(): other ASN1 functions add an extra null
- to the end of the strings whereas this didn't. This would cause problems
- if strings read with d2i_ASN1_bytes() were later modified.
- [Steve Henson, reported by Arne Ansper <arne@ats.cyber.ee>]
-
- *) Fix for base64 decode bug. When a base64 bio reads only one line of
- data and it contains EOF it will end up returning an error. This is
- caused by input 46 bytes long. The cause is due to the way base64
- BIOs find the start of base64 encoded data. They do this by trying a
- trial decode on each line until they find one that works. When they
- do a flag is set and it starts again knowing it can pass all the
- data directly through the decoder. Unfortunately it doesn't reset
- the context it uses. This means that if EOF is reached an attempt
- is made to pass two EOFs through the context and this causes the
- resulting error. This can also cause other problems as well. As is
- usual with these problems it takes *ages* to find and the fix is
- trivial: move one line.
- [Steve Henson, reported by ian@uns.ns.ac.yu (Ivan Nejgebauer) ]
-
- *) Ugly workaround to get s_client and s_server working under Windows. The
- old code wouldn't work because it needed to select() on sockets and the
- tty (for keypresses and to see if data could be written). Win32 only
- supports select() on sockets so we select() with a 1s timeout on the
- sockets and then see if any characters are waiting to be read, if none
- are present then we retry, we also assume we can always write data to
- the tty. This isn't nice because the code then blocks until we've
- received a complete line of data and it is effectively polling the
- keyboard at 1s intervals: however it's quite a bit better than not
- working at all :-) A dedicated Windows application might handle this
- with an event loop for example.
- [Steve Henson]
-
- *) Enhance RSA_METHOD structure. Now there are two extra methods, rsa_sign
- and rsa_verify. When the RSA_FLAGS_SIGN_VER option is set these functions
- will be called when RSA_sign() and RSA_verify() are used. This is useful
- if rsa_pub_dec() and rsa_priv_enc() equivalents are not available.
- For this to work properly RSA_public_decrypt() and RSA_private_encrypt()
- should *not* be used: RSA_sign() and RSA_verify() must be used instead.
- This necessitated the support of an extra signature type NID_md5_sha1
- for SSL signatures and modifications to the SSL library to use it instead
- of calling RSA_public_decrypt() and RSA_private_encrypt().
- [Steve Henson]
-
- *) Add new -verify -CAfile and -CApath options to the crl program, these
- will lookup a CRL issuers certificate and verify the signature in a
- similar way to the verify program. Tidy up the crl program so it
- no longer accesses structures directly. Make the ASN1 CRL parsing a bit
- less strict. It will now permit CRL extensions even if it is not
- a V2 CRL: this will allow it to tolerate some broken CRLs.
- [Steve Henson]
-
- *) Initialize all non-automatic variables each time one of the openssl
- sub-programs is started (this is necessary as they may be started
- multiple times from the "OpenSSL>" prompt).
- [Lennart Bang, Bodo Moeller]
-
- *) Preliminary compilation option RSA_NULL which disables RSA crypto without
- removing all other RSA functionality (this is what NO_RSA does). This
- is so (for example) those in the US can disable those operations covered
- by the RSA patent while allowing storage and parsing of RSA keys and RSA
- key generation.
- [Steve Henson]
-
- *) Non-copying interface to BIO pairs.
- (still largely untested)
- [Bodo Moeller]
-
- *) New function ANS1_tag2str() to convert an ASN1 tag to a descriptive
- ASCII string. This was handled independently in various places before.
- [Steve Henson]
-
- *) New functions UTF8_getc() and UTF8_putc() that parse and generate
- UTF8 strings a character at a time.
- [Steve Henson]
-
- *) Use client_version from client hello to select the protocol
- (s23_srvr.c) and for RSA client key exchange verification
- (s3_srvr.c), as required by the SSL 3.0/TLS 1.0 specifications.
- [Bodo Moeller]
-
- *) Add various utility functions to handle SPKACs, these were previously
- handled by poking round in the structure internals. Added new function
- NETSCAPE_SPKI_print() to print out SPKAC and a new utility 'spkac' to
- print, verify and generate SPKACs. Based on an original idea from
- Massimiliano Pala <madwolf@comune.modena.it> but extensively modified.
- [Steve Henson]
-
- *) RIPEMD160 is operational on all platforms and is back in 'make test'.
- [Andy Polyakov]
-
- *) Allow the config file extension section to be overwritten on the
- command line. Based on an original idea from Massimiliano Pala
- <madwolf@comune.modena.it>. The new option is called -extensions
- and can be applied to ca, req and x509. Also -reqexts to override
- the request extensions in req and -crlexts to override the crl extensions
- in ca.
- [Steve Henson]
-
- *) Add new feature to the SPKAC handling in ca. Now you can include
- the same field multiple times by preceding it by "XXXX." for example:
- 1.OU="Unit name 1"
- 2.OU="Unit name 2"
- this is the same syntax as used in the req config file.
- [Steve Henson]
-
- *) Allow certificate extensions to be added to certificate requests. These
- are specified in a 'req_extensions' option of the req section of the
- config file. They can be printed out with the -text option to req but
- are otherwise ignored at present.
- [Steve Henson]
-
- *) Fix a horrible bug in enc_read() in crypto/evp/bio_enc.c: if the first
- data read consists of only the final block it would not decrypted because
- EVP_CipherUpdate() would correctly report zero bytes had been decrypted.
- A misplaced 'break' also meant the decrypted final block might not be
- copied until the next read.
- [Steve Henson]
-
- *) Initial support for DH_METHOD. Again based on RSA_METHOD. Also added
- a few extra parameters to the DH structure: these will be useful if
- for example we want the value of 'q' or implement X9.42 DH.
- [Steve Henson]
-
- *) Initial support for DSA_METHOD. This is based on the RSA_METHOD and
- provides hooks that allow the default DSA functions or functions on a
- "per key" basis to be replaced. This allows hardware acceleration and
- hardware key storage to be handled without major modification to the
- library. Also added low level modexp hooks and CRYPTO_EX structure and
- associated functions.
- [Steve Henson]
-
- *) Add a new flag to memory BIOs, BIO_FLAG_MEM_RDONLY. This marks the BIO
- as "read only": it can't be written to and the buffer it points to will
- not be freed. Reading from a read only BIO is much more efficient than
- a normal memory BIO. This was added because there are several times when
- an area of memory needs to be read from a BIO. The previous method was
- to create a memory BIO and write the data to it, this results in two
- copies of the data and an O(n^2) reading algorithm. There is a new
- function BIO_new_mem_buf() which creates a read only memory BIO from
- an area of memory. Also modified the PKCS#7 routines to use read only
- memory BIOs.
- [Steve Henson]
-
- *) Bugfix: ssl23_get_client_hello did not work properly when called in
- state SSL23_ST_SR_CLNT_HELLO_B, i.e. when the first 7 bytes of
- a SSLv2-compatible client hello for SSLv3 or TLSv1 could be read,
- but a retry condition occured while trying to read the rest.
- [Bodo Moeller]
-
- *) The PKCS7_ENC_CONTENT_new() function was setting the content type as
- NID_pkcs7_encrypted by default: this was wrong since this should almost
- always be NID_pkcs7_data. Also modified the PKCS7_set_type() to handle
- the encrypted data type: this is a more sensible place to put it and it
- allows the PKCS#12 code to be tidied up that duplicated this
- functionality.
- [Steve Henson]
-
- *) Changed obj_dat.pl script so it takes its input and output files on
- the command line. This should avoid shell escape redirection problems
- under Win32.
- [Steve Henson]
-
- *) Initial support for certificate extension requests, these are included
- in things like Xenroll certificate requests. Included functions to allow
- extensions to be obtained and added.
- [Steve Henson]
-
- *) -crlf option to s_client and s_server for sending newlines as
- CRLF (as required by many protocols).
- [Bodo Moeller]
-
- Changes between 0.9.3a and 0.9.4 [09 Aug 1999]
-
- *) Install libRSAglue.a when OpenSSL is built with RSAref.
- [Ralf S. Engelschall]
-
- *) A few more ``#ifndef NO_FP_API / #endif'' pairs for consistency.
- [Andrija Antonijevic <TheAntony2@bigfoot.com>]
-
- *) Fix -startdate and -enddate (which was missing) arguments to 'ca'
- program.
- [Steve Henson]
-
- *) New function DSA_dup_DH, which duplicates DSA parameters/keys as
- DH parameters/keys (q is lost during that conversion, but the resulting
- DH parameters contain its length).
-
- For 1024-bit p, DSA_generate_parameters followed by DSA_dup_DH is
- much faster than DH_generate_parameters (which creates parameters
- where p = 2*q + 1), and also the smaller q makes DH computations
- much more efficient (160-bit exponentiation instead of 1024-bit
- exponentiation); so this provides a convenient way to support DHE
- ciphersuites in SSL/TLS servers (see ssl/ssltest.c). It is of
- utter importance to use
- SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
- or
- SSL_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
- when such DH parameters are used, because otherwise small subgroup
- attacks may become possible!
- [Bodo Moeller]
-
- *) Avoid memory leak in i2d_DHparams.
- [Bodo Moeller]
-
- *) Allow the -k option to be used more than once in the enc program:
- this allows the same encrypted message to be read by multiple recipients.
- [Steve Henson]
-
- *) New function OBJ_obj2txt(buf, buf_len, a, no_name), this converts
- an ASN1_OBJECT to a text string. If the "no_name" parameter is set then
- it will always use the numerical form of the OID, even if it has a short
- or long name.
- [Steve Henson]
-
- *) Added an extra RSA flag: RSA_FLAG_EXT_PKEY. Previously the rsa_mod_exp
- method only got called if p,q,dmp1,dmq1,iqmp components were present,
- otherwise bn_mod_exp was called. In the case of hardware keys for example
- no private key components need be present and it might store extra data
- in the RSA structure, which cannot be accessed from bn_mod_exp.
- By setting RSA_FLAG_EXT_PKEY rsa_mod_exp will always be called for
- private key operations.
- [Steve Henson]
-
- *) Added support for SPARC Linux.
- [Andy Polyakov]
-
- *) pem_password_cb function type incompatibly changed from
- typedef int pem_password_cb(char *buf, int size, int rwflag);
- to
- ....(char *buf, int size, int rwflag, void *userdata);
- so that applications can pass data to their callbacks:
- The PEM[_ASN1]_{read,write}... functions and macros now take an
- additional void * argument, which is just handed through whenever
- the password callback is called.
- [Damien Miller <dmiller@ilogic.com.au>; tiny changes by Bodo Moeller]
-
- New function SSL_CTX_set_default_passwd_cb_userdata.
-
- Compatibility note: As many C implementations push function arguments
- onto the stack in reverse order, the new library version is likely to
- interoperate with programs that have been compiled with the old
- pem_password_cb definition (PEM_whatever takes some data that
- happens to be on the stack as its last argument, and the callback
- just ignores this garbage); but there is no guarantee whatsoever that
- this will work.
-
- *) The -DPLATFORM="\"$(PLATFORM)\"" definition and the similar -DCFLAGS=...
- (both in crypto/Makefile.ssl for use by crypto/cversion.c) caused
- problems not only on Windows, but also on some Unix platforms.
- To avoid problematic command lines, these definitions are now in an
- auto-generated file crypto/buildinf.h (created by crypto/Makefile.ssl
- for standard "make" builds, by util/mk1mf.pl for "mk1mf" builds).
- [Bodo Moeller]
-
- *) MIPS III/IV assembler module is reimplemented.
- [Andy Polyakov]
-
- *) More DES library cleanups: remove references to srand/rand and
- delete an unused file.
- [Ulf Möller]
-
- *) Add support for the the free Netwide assembler (NASM) under Win32,
- since not many people have MASM (ml) and it can be hard to obtain.
- This is currently experimental but it seems to work OK and pass all
- the tests. Check out INSTALL.W32 for info.
- [Steve Henson]
-
- *) Fix memory leaks in s3_clnt.c: All non-anonymous SSL3/TLS1 connections
- without temporary keys kept an extra copy of the server key,
- and connections with temporary keys did not free everything in case
- of an error.
- [Bodo Moeller]
-
- *) New function RSA_check_key and new openssl rsa option -check
- for verifying the consistency of RSA keys.
- [Ulf Moeller, Bodo Moeller]
-
- *) Various changes to make Win32 compile work:
- 1. Casts to avoid "loss of data" warnings in p5_crpt2.c
- 2. Change unsigned int to int in b_dump.c to avoid "signed/unsigned
- comparison" warnings.
- 3. Add sk_<TYPE>_sort to DEF file generator and do make update.
- [Steve Henson]
-
- *) Add a debugging option to PKCS#5 v2 key generation function: when
- you #define DEBUG_PKCS5V2 passwords, salts, iteration counts and
- derived keys are printed to stderr.
- [Steve Henson]
-
- *) Copy the flags in ASN1_STRING_dup().
- [Roman E. Pavlov <pre@mo.msk.ru>]
-
- *) The x509 application mishandled signing requests containing DSA
- keys when the signing key was also DSA and the parameters didn't match.
-
- It was supposed to omit the parameters when they matched the signing key:
- the verifying software was then supposed to automatically use the CA's
- parameters if they were absent from the end user certificate.
-
- Omitting parameters is no longer recommended. The test was also
- the wrong way round! This was probably due to unusual behaviour in
- EVP_cmp_parameters() which returns 1 if the parameters match.
- This meant that parameters were omitted when they *didn't* match and
- the certificate was useless. Certificates signed with 'ca' didn't have
- this bug.
- [Steve Henson, reported by Doug Erickson <Doug.Erickson@Part.NET>]
-
- *) Memory leak checking (-DCRYPTO_MDEBUG) had some problems.
- The interface is as follows:
- Applications can use
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) aka MemCheck_start(),
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) aka MemCheck_stop();
- "off" is now the default.
- The library internally uses
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) aka MemCheck_off(),
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) aka MemCheck_on()
- to disable memory-checking temporarily.
-
- Some inconsistent states that previously were possible (and were
- even the default) are now avoided.
-
- -DCRYPTO_MDEBUG_TIME is new and additionally stores the current time
- with each memory chunk allocated; this is occasionally more helpful
- than just having a counter.
-
- -DCRYPTO_MDEBUG_THREAD is also new and adds the thread ID.
-
- -DCRYPTO_MDEBUG_ALL enables all of the above, plus any future
- extensions.
- [Bodo Moeller]
-
- *) Introduce "mode" for SSL structures (with defaults in SSL_CTX),
- which largely parallels "options", but is for changing API behaviour,
- whereas "options" are about protocol behaviour.
- Initial "mode" flags are:
-
- SSL_MODE_ENABLE_PARTIAL_WRITE Allow SSL_write to report success when
- a single record has been written.
- SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER Don't insist that SSL_write
- retries use the same buffer location.
- (But all of the contents must be
- copied!)
- [Bodo Moeller]
-
- *) Bugfix: SSL_set_options ignored its parameter, only SSL_CTX_set_options
- worked.
-
- *) Fix problems with no-hmac etc.
- [Ulf Möller, pointed out by Brian Wellington <bwelling@tislabs.com>]
-
- *) New functions RSA_get_default_method(), RSA_set_method() and
- RSA_get_method(). These allows replacement of RSA_METHODs without having
- to mess around with the internals of an RSA structure.
- [Steve Henson]
-
- *) Fix memory leaks in DSA_do_sign and DSA_is_prime.
- Also really enable memory leak checks in openssl.c and in some
- test programs.
- [Chad C. Mulligan, Bodo Moeller]
-
- *) Fix a bug in d2i_ASN1_INTEGER() and i2d_ASN1_INTEGER() which can mess
- up the length of negative integers. This has now been simplified to just
- store the length when it is first determined and use it later, rather
- than trying to keep track of where data is copied and updating it to
- point to the end.
- [Steve Henson, reported by Brien Wheeler
- <bwheeler@authentica-security.com>]
-
- *) Add a new function PKCS7_signatureVerify. This allows the verification
- of a PKCS#7 signature but with the signing certificate passed to the
- function itself. This contrasts with PKCS7_dataVerify which assumes the
- certificate is present in the PKCS#7 structure. This isn't always the
- case: certificates can be omitted from a PKCS#7 structure and be
- distributed by "out of band" means (such as a certificate database).
- [Steve Henson]
-
- *) Complete the PEM_* macros with DECLARE_PEM versions to replace the
- function prototypes in pem.h, also change util/mkdef.pl to add the
- necessary function names.
- [Steve Henson]
-
- *) mk1mf.pl (used by Windows builds) did not properly read the
- options set by Configure in the top level Makefile, and Configure
- was not even able to write more than one option correctly.
- Fixed, now "no-idea no-rc5 -DCRYPTO_MDEBUG" etc. works as intended.
- [Bodo Moeller]
-
- *) New functions CONF_load_bio() and CONF_load_fp() to allow a config
- file to be loaded from a BIO or FILE pointer. The BIO version will
- for example allow memory BIOs to contain config info.
- [Steve Henson]
-
- *) New function "CRYPTO_num_locks" that returns CRYPTO_NUM_LOCKS.
- Whoever hopes to achieve shared-library compatibility across versions
- must use this, not the compile-time macro.
- (Exercise 0.9.4: Which is the minimum library version required by
- such programs?)
- Note: All this applies only to multi-threaded programs, others don't
- need locks.
- [Bodo Moeller]
-
- *) Add missing case to s3_clnt.c state machine -- one of the new SSL tests
- through a BIO pair triggered the default case, i.e.
- SSLerr(...,SSL_R_UNKNOWN_STATE).
- [Bodo Moeller]
-
- *) New "BIO pair" concept (crypto/bio/bss_bio.c) so that applications
- can use the SSL library even if none of the specific BIOs is
- appropriate.
- [Bodo Moeller]
-
- *) Fix a bug in i2d_DSAPublicKey() which meant it returned the wrong value
- for the encoded length.
- [Jeon KyoungHo <khjeon@sds.samsung.co.kr>]
-
- *) Add initial documentation of the X509V3 functions.
- [Steve Henson]
-
- *) Add a new pair of functions PEM_write_PKCS8PrivateKey() and
- PEM_write_bio_PKCS8PrivateKey() that are equivalent to
- PEM_write_PrivateKey() and PEM_write_bio_PrivateKey() but use the more
- secure PKCS#8 private key format with a high iteration count.
- [Steve Henson]
-
- *) Fix determination of Perl interpreter: A perl or perl5
- _directory_ in $PATH was also accepted as the interpreter.
- [Ralf S. Engelschall]
-
- *) Fix demos/sign/sign.c: well there wasn't anything strictly speaking
- wrong with it but it was very old and did things like calling
- PEM_ASN1_read() directly and used MD5 for the hash not to mention some
- unusual formatting.
- [Steve Henson]
-
- *) Fix demos/selfsign.c: it used obsolete and deleted functions, changed
- to use the new extension code.
- [Steve Henson]
-
- *) Implement the PEM_read/PEM_write functions in crypto/pem/pem_all.c
- with macros. This should make it easier to change their form, add extra
- arguments etc. Fix a few PEM prototypes which didn't have cipher as a
- constant.
- [Steve Henson]
-
- *) Add to configuration table a new entry that can specify an alternative
- name for unistd.h (for pre-POSIX systems); we need this for NeXTstep,
- according to Mark Crispin <MRC@Panda.COM>.
- [Bodo Moeller]
-
-#if 0
- *) DES CBC did not update the IV. Weird.
- [Ben Laurie]
-#else
- des_cbc_encrypt does not update the IV, but des_ncbc_encrypt does.
- Changing the behaviour of the former might break existing programs --
- where IV updating is needed, des_ncbc_encrypt can be used.
-#endif
-
- *) When bntest is run from "make test" it drives bc to check its
- calculations, as well as internally checking them. If an internal check
- fails, it needs to cause bc to give a non-zero result or make test carries
- on without noticing the failure. Fixed.
- [Ben Laurie]
-
- *) DES library cleanups.
- [Ulf Möller]
-
- *) Add support for PKCS#5 v2.0 PBE algorithms. This will permit PKCS#8 to be
- used with any cipher unlike PKCS#5 v1.5 which can at most handle 64 bit
- ciphers. NOTE: although the key derivation function has been verified
- against some published test vectors it has not been extensively tested
- yet. Added a -v2 "cipher" option to pkcs8 application to allow the use
- of v2.0.
- [Steve Henson]
-
- *) Instead of "mkdir -p", which is not fully portable, use new
- Perl script "util/mkdir-p.pl".
- [Bodo Moeller]
-
- *) Rewrite the way password based encryption (PBE) is handled. It used to
- assume that the ASN1 AlgorithmIdentifier parameter was a PBEParameter
- structure. This was true for the PKCS#5 v1.5 and PKCS#12 PBE algorithms
- but doesn't apply to PKCS#5 v2.0 where it can be something else. Now
- the 'parameter' field of the AlgorithmIdentifier is passed to the
- underlying key generation function so it must do its own ASN1 parsing.
- This has also changed the EVP_PBE_CipherInit() function which now has a
- 'parameter' argument instead of literal salt and iteration count values
- and the function EVP_PBE_ALGOR_CipherInit() has been deleted.
- [Steve Henson]
-
- *) Support for PKCS#5 v1.5 compatible password based encryption algorithms
- and PKCS#8 functionality. New 'pkcs8' application linked to openssl.
- Needed to change the PEM_STRING_EVP_PKEY value which was just "PRIVATE
- KEY" because this clashed with PKCS#8 unencrypted string. Since this
- value was just used as a "magic string" and not used directly its
- value doesn't matter.
- [Steve Henson]
-
- *) Introduce some semblance of const correctness to BN. Shame C doesn't
- support mutable.
- [Ben Laurie]
-
- *) "linux-sparc64" configuration (ultrapenguin).
- [Ray Miller <ray.miller@oucs.ox.ac.uk>]
- "linux-sparc" configuration.
- [Christian Forster <fo@hawo.stw.uni-erlangen.de>]
-
- *) config now generates no-xxx options for missing ciphers.
- [Ulf Möller]
-
- *) Support the EBCDIC character set (work in progress).
- File ebcdic.c not yet included because it has a different license.
- [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
-
- *) Support BS2000/OSD-POSIX.
- [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
-
- *) Make callbacks for key generation use void * instead of char *.
- [Ben Laurie]
-
- *) Make S/MIME samples compile (not yet tested).
- [Ben Laurie]
-
- *) Additional typesafe stacks.
- [Ben Laurie]
-
- *) New configuration variants "bsdi-elf-gcc" (BSD/OS 4.x).
- [Bodo Moeller]
-
-
- Changes between 0.9.3 and 0.9.3a [29 May 1999]
-
- *) New configuration variant "sco5-gcc".
-
- *) Updated some demos.
- [Sean O Riordain, Wade Scholine]
-
- *) Add missing BIO_free at exit of pkcs12 application.
- [Wu Zhigang]
-
- *) Fix memory leak in conf.c.
- [Steve Henson]
-
- *) Updates for Win32 to assembler version of MD5.
- [Steve Henson]
-
- *) Set #! path to perl in apps/der_chop to where we found it
- instead of using a fixed path.
- [Bodo Moeller]
-
- *) SHA library changes for irix64-mips4-cc.
- [Andy Polyakov]
-
- *) Improvements for VMS support.
- [Richard Levitte]
-
-
- Changes between 0.9.2b and 0.9.3 [24 May 1999]
-
- *) Bignum library bug fix. IRIX 6 passes "make test" now!
- This also avoids the problems with SC4.2 and unpatched SC5.
- [Andy Polyakov <appro@fy.chalmers.se>]
-
- *) New functions sk_num, sk_value and sk_set to replace the previous macros.
- These are required because of the typesafe stack would otherwise break
- existing code. If old code used a structure member which used to be STACK
- and is now STACK_OF (for example cert in a PKCS7_SIGNED structure) with
- sk_num or sk_value it would produce an error because the num, data members
- are not present in STACK_OF. Now it just produces a warning. sk_set
- replaces the old method of assigning a value to sk_value
- (e.g. sk_value(x, i) = y) which the library used in a few cases. Any code
- that does this will no longer work (and should use sk_set instead) but
- this could be regarded as a "questionable" behaviour anyway.
- [Steve Henson]
-
- *) Fix most of the other PKCS#7 bugs. The "experimental" code can now
- correctly handle encrypted S/MIME data.
- [Steve Henson]
-
- *) Change type of various DES function arguments from des_cblock
- (which means, in function argument declarations, pointer to char)
- to des_cblock * (meaning pointer to array with 8 char elements),
- which allows the compiler to do more typechecking; it was like
- that back in SSLeay, but with lots of ugly casts.
-
- Introduce new type const_des_cblock.
- [Bodo Moeller]
-
- *) Reorganise the PKCS#7 library and get rid of some of the more obvious
- problems: find RecipientInfo structure that matches recipient certificate
- and initialise the ASN1 structures properly based on passed cipher.
- [Steve Henson]
-
- *) Belatedly make the BN tests actually check the results.
- [Ben Laurie]
-
- *) Fix the encoding and decoding of negative ASN1 INTEGERS and conversion
- to and from BNs: it was completely broken. New compilation option
- NEG_PUBKEY_BUG to allow for some broken certificates that encode public
- key elements as negative integers.
- [Steve Henson]
-
- *) Reorganize and speed up MD5.
- [Andy Polyakov <appro@fy.chalmers.se>]
-
- *) VMS support.
- [Richard Levitte <richard@levitte.org>]
-
- *) New option -out to asn1parse to allow the parsed structure to be
- output to a file. This is most useful when combined with the -strparse
- option to examine the output of things like OCTET STRINGS.
- [Steve Henson]
-
- *) Make SSL library a little more fool-proof by not requiring any longer
- that SSL_set_{accept,connect}_state be called before
- SSL_{accept,connect} may be used (SSL_set_..._state is omitted
- in many applications because usually everything *appeared* to work as
- intended anyway -- now it really works as intended).
- [Bodo Moeller]
-
- *) Move openssl.cnf out of lib/.
- [Ulf Möller]
-
- *) Fix various things to let OpenSSL even pass ``egcc -pipe -O2 -Wall
- -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes
- -Wmissing-declarations -Wnested-externs -Winline'' with EGCS 1.1.2+
- [Ralf S. Engelschall]
-
- *) Various fixes to the EVP and PKCS#7 code. It may now be able to
- handle PKCS#7 enveloped data properly.
- [Sebastian Akerman <sak@parallelconsulting.com>, modified by Steve]
-
- *) Create a duplicate of the SSL_CTX's CERT in SSL_new instead of
- copying pointers. The cert_st handling is changed by this in
- various ways (and thus what used to be known as ctx->default_cert
- is now called ctx->cert, since we don't resort to s->ctx->[default_]cert
- any longer when s->cert does not give us what we need).
- ssl_cert_instantiate becomes obsolete by this change.
- As soon as we've got the new code right (possibly it already is?),
- we have solved a couple of bugs of the earlier code where s->cert
- was used as if it could not have been shared with other SSL structures.
-
- Note that using the SSL API in certain dirty ways now will result
- in different behaviour than observed with earlier library versions:
- Changing settings for an SSL_CTX *ctx after having done s = SSL_new(ctx)
- does not influence s as it used to.
-
- In order to clean up things more thoroughly, inside SSL_SESSION
- we don't use CERT any longer, but a new structure SESS_CERT
- that holds per-session data (if available); currently, this is
- the peer's certificate chain and, for clients, the server's certificate
- and temporary key. CERT holds only those values that can have
- meaningful defaults in an SSL_CTX.
- [Bodo Moeller]
-
- *) New function X509V3_EXT_i2d() to create an X509_EXTENSION structure
- from the internal representation. Various PKCS#7 fixes: remove some
- evil casts and set the enc_dig_alg field properly based on the signing
- key type.
- [Steve Henson]
-
- *) Allow PKCS#12 password to be set from the command line or the
- environment. Let 'ca' get its config file name from the environment
- variables "OPENSSL_CONF" or "SSLEAY_CONF" (for consistency with 'req'
- and 'x509').
- [Steve Henson]
-
- *) Allow certificate policies extension to use an IA5STRING for the
- organization field. This is contrary to the PKIX definition but
- VeriSign uses it and IE5 only recognises this form. Document 'x509'
- extension option.
- [Steve Henson]
-
- *) Add PEDANTIC compiler flag to allow compilation with gcc -pedantic,
- without disallowing inline assembler and the like for non-pedantic builds.
- [Ben Laurie]
-
- *) Support Borland C++ builder.
- [Janez Jere <jj@void.si>, modified by Ulf Möller]
-
- *) Support Mingw32.
- [Ulf Möller]
-
- *) SHA-1 cleanups and performance enhancements.
- [Andy Polyakov <appro@fy.chalmers.se>]
-
- *) Sparc v8plus assembler for the bignum library.
- [Andy Polyakov <appro@fy.chalmers.se>]
-
- *) Accept any -xxx and +xxx compiler options in Configure.
- [Ulf Möller]
-
- *) Update HPUX configuration.
- [Anonymous]
-
- *) Add missing sk_<type>_unshift() function to safestack.h
- [Ralf S. Engelschall]
-
- *) New function SSL_CTX_use_certificate_chain_file that sets the
- "extra_cert"s in addition to the certificate. (This makes sense
- only for "PEM" format files, as chains as a whole are not
- DER-encoded.)
- [Bodo Moeller]
-
- *) Support verify_depth from the SSL API.
- x509_vfy.c had what can be considered an off-by-one-error:
- Its depth (which was not part of the external interface)
- was actually counting the number of certificates in a chain;
- now it really counts the depth.
- [Bodo Moeller]
-
- *) Bugfix in crypto/x509/x509_cmp.c: The SSLerr macro was used
- instead of X509err, which often resulted in confusing error
- messages since the error codes are not globally unique
- (e.g. an alleged error in ssl3_accept when a certificate
- didn't match the private key).
-
- *) New function SSL_CTX_set_session_id_context that allows to set a default
- value (so that you don't need SSL_set_session_id_context for each
- connection using the SSL_CTX).
- [Bodo Moeller]
-
- *) OAEP decoding bug fix.
- [Ulf Möller]
-
- *) Support INSTALL_PREFIX for package builders, as proposed by
- David Harris.
- [Bodo Moeller]
-
- *) New Configure options "threads" and "no-threads". For systems
- where the proper compiler options are known (currently Solaris
- and Linux), "threads" is the default.
- [Bodo Moeller]
-
- *) New script util/mklink.pl as a faster substitute for util/mklink.sh.
- [Bodo Moeller]
-
- *) Install various scripts to $(OPENSSLDIR)/misc, not to
- $(INSTALLTOP)/bin -- they shouldn't clutter directories
- such as /usr/local/bin.
- [Bodo Moeller]
-
- *) "make linux-shared" to build shared libraries.
- [Niels Poppe <niels@netbox.org>]
-
- *) New Configure option no-<cipher> (rsa, idea, rc5, ...).
- [Ulf Möller]
-
- *) Add the PKCS#12 API documentation to openssl.txt. Preliminary support for
- extension adding in x509 utility.
- [Steve Henson]
-
- *) Remove NOPROTO sections and error code comments.
- [Ulf Möller]
-
- *) Partial rewrite of the DEF file generator to now parse the ANSI
- prototypes.
- [Steve Henson]
-
- *) New Configure options --prefix=DIR and --openssldir=DIR.
- [Ulf Möller]
-
- *) Complete rewrite of the error code script(s). It is all now handled
- by one script at the top level which handles error code gathering,
- header rewriting and C source file generation. It should be much better
- than the old method: it now uses a modified version of Ulf's parser to
- read the ANSI prototypes in all header files (thus the old K&R definitions
- aren't needed for error creation any more) and do a better job of
- translating function codes into names. The old 'ASN1 error code imbedded
- in a comment' is no longer necessary and it doesn't use .err files which
- have now been deleted. Also the error code call doesn't have to appear all
- on one line (which resulted in some large lines...).
- [Steve Henson]
-
- *) Change #include filenames from <foo.h> to <openssl/foo.h>.
- [Bodo Moeller]
-
- *) Change behaviour of ssl2_read when facing length-0 packets: Don't return
- 0 (which usually indicates a closed connection), but continue reading.
- [Bodo Moeller]
-
- *) Fix some race conditions.
- [Bodo Moeller]
-
- *) Add support for CRL distribution points extension. Add Certificate
- Policies and CRL distribution points documentation.
- [Steve Henson]
-
- *) Move the autogenerated header file parts to crypto/opensslconf.h.
- [Ulf Möller]
-
- *) Fix new 56-bit DES export ciphersuites: they were using 7 bytes instead of
- 8 of keying material. Merlin has also confirmed interop with this fix
- between OpenSSL and Baltimore C/SSL 2.0 and J/SSL 2.0.
- [Merlin Hughes <merlin@baltimore.ie>]
-
- *) Fix lots of warnings.
- [Richard Levitte <levitte@stacken.kth.se>]
-
- *) In add_cert_dir() in crypto/x509/by_dir.c, break out of the loop if
- the directory spec didn't end with a LIST_SEPARATOR_CHAR.
- [Richard Levitte <levitte@stacken.kth.se>]
-
- *) Fix problems with sizeof(long) == 8.
- [Andy Polyakov <appro@fy.chalmers.se>]
-
- *) Change functions to ANSI C.
- [Ulf Möller]
-
- *) Fix typos in error codes.
- [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>, Ulf Möller]
-
- *) Remove defunct assembler files from Configure.
- [Ulf Möller]
-
- *) SPARC v8 assembler BIGNUM implementation.
- [Andy Polyakov <appro@fy.chalmers.se>]
-
- *) Support for Certificate Policies extension: both print and set.
- Various additions to support the r2i method this uses.
- [Steve Henson]
-
- *) A lot of constification, and fix a bug in X509_NAME_oneline() that could
- return a const string when you are expecting an allocated buffer.
- [Ben Laurie]
-
- *) Add support for ASN1 types UTF8String and VISIBLESTRING, also the CHOICE
- types DirectoryString and DisplayText.
- [Steve Henson]
-
- *) Add code to allow r2i extensions to access the configuration database,
- add an LHASH database driver and add several ctx helper functions.
- [Steve Henson]
-
- *) Fix an evil bug in bn_expand2() which caused various BN functions to
- fail when they extended the size of a BIGNUM.
- [Steve Henson]
-
- *) Various utility functions to handle SXNet extension. Modify mkdef.pl to
- support typesafe stack.
- [Steve Henson]
-
- *) Fix typo in SSL_[gs]et_options().
- [Nils Frostberg <nils@medcom.se>]
-
- *) Delete various functions and files that belonged to the (now obsolete)
- old X509V3 handling code.
- [Steve Henson]
-
- *) New Configure option "rsaref".
- [Ulf Möller]
-
- *) Don't auto-generate pem.h.
- [Bodo Moeller]
-
- *) Introduce type-safe ASN.1 SETs.
- [Ben Laurie]
-
- *) Convert various additional casted stacks to type-safe STACK_OF() variants.
- [Ben Laurie, Ralf S. Engelschall, Steve Henson]
-
- *) Introduce type-safe STACKs. This will almost certainly break lots of code
- that links with OpenSSL (well at least cause lots of warnings), but fear
- not: the conversion is trivial, and it eliminates loads of evil casts. A
- few STACKed things have been converted already. Feel free to convert more.
- In the fullness of time, I'll do away with the STACK type altogether.
- [Ben Laurie]
-
- *) Add `openssl ca -revoke <certfile>' facility which revokes a certificate
- specified in <certfile> by updating the entry in the index.txt file.
- This way one no longer has to edit the index.txt file manually for
- revoking a certificate. The -revoke option does the gory details now.
- [Massimiliano Pala <madwolf@openca.org>, Ralf S. Engelschall]
-
- *) Fix `openssl crl -noout -text' combination where `-noout' killed the
- `-text' option at all and this way the `-noout -text' combination was
- inconsistent in `openssl crl' with the friends in `openssl x509|rsa|dsa'.
- [Ralf S. Engelschall]
-
- *) Make sure a corresponding plain text error message exists for the
- X509_V_ERR_CERT_REVOKED/23 error number which can occur when a
- verify callback function determined that a certificate was revoked.
- [Ralf S. Engelschall]
-
- *) Bugfix: In test/testenc, don't test "openssl <cipher>" for
- ciphers that were excluded, e.g. by -DNO_IDEA. Also, test
- all available cipers including rc5, which was forgotten until now.
- In order to let the testing shell script know which algorithms
- are available, a new (up to now undocumented) command
- "openssl list-cipher-commands" is used.
- [Bodo Moeller]
-
- *) Bugfix: s_client occasionally would sleep in select() when
- it should have checked SSL_pending() first.
- [Bodo Moeller]
-
- *) New functions DSA_do_sign and DSA_do_verify to provide access to
- the raw DSA values prior to ASN.1 encoding.
- [Ulf Möller]
-
- *) Tweaks to Configure
- [Niels Poppe <niels@netbox.org>]
-
- *) Add support for PKCS#5 v2.0 ASN1 PBES2 structures. No other support,
- yet...
- [Steve Henson]
-
- *) New variables $(RANLIB) and $(PERL) in the Makefiles.
- [Ulf Möller]
-
- *) New config option to avoid instructions that are illegal on the 80386.
- The default code is faster, but requires at least a 486.
- [Ulf Möller]
-
- *) Got rid of old SSL2_CLIENT_VERSION (inconsistently used) and
- SSL2_SERVER_VERSION (not used at all) macros, which are now the
- same as SSL2_VERSION anyway.
- [Bodo Moeller]
-
- *) New "-showcerts" option for s_client.
- [Bodo Moeller]
-
- *) Still more PKCS#12 integration. Add pkcs12 application to openssl
- application. Various cleanups and fixes.
- [Steve Henson]
-
- *) More PKCS#12 integration. Add new pkcs12 directory with Makefile.ssl and
- modify error routines to work internally. Add error codes and PBE init
- to library startup routines.
- [Steve Henson]
-
- *) Further PKCS#12 integration. Added password based encryption, PKCS#8 and
- packing functions to asn1 and evp. Changed function names and error
- codes along the way.
- [Steve Henson]
-
- *) PKCS12 integration: and so it begins... First of several patches to
- slowly integrate PKCS#12 functionality into OpenSSL. Add PKCS#12
- objects to objects.h
- [Steve Henson]
-
- *) Add a new 'indent' option to some X509V3 extension code. Initial ASN1
- and display support for Thawte strong extranet extension.
- [Steve Henson]
-
- *) Add LinuxPPC support.
- [Jeff Dubrule <igor@pobox.org>]
-
- *) Get rid of redundant BN file bn_mulw.c, and rename bn_div64 to
- bn_div_words in alpha.s.
- [Hannes Reinecke <H.Reinecke@hw.ac.uk> and Ben Laurie]
-
- *) Make sure the RSA OAEP test is skipped under -DRSAref because
- OAEP isn't supported when OpenSSL is built with RSAref.
- [Ulf Moeller <ulf@fitug.de>]
-
- *) Move definitions of IS_SET/IS_SEQUENCE inside crypto/asn1/asn1.h
- so they no longer are missing under -DNOPROTO.
- [Soren S. Jorvang <soren@t.dk>]
-
-
- Changes between 0.9.1c and 0.9.2b [22 Mar 1999]
-
- *) Make SSL_get_peer_cert_chain() work in servers. Unfortunately, it still
- doesn't work when the session is reused. Coming soon!
- [Ben Laurie]
-
- *) Fix a security hole, that allows sessions to be reused in the wrong
- context thus bypassing client cert protection! All software that uses
- client certs and session caches in multiple contexts NEEDS PATCHING to
- allow session reuse! A fuller solution is in the works.
- [Ben Laurie, problem pointed out by Holger Reif, Bodo Moeller (and ???)]
-
- *) Some more source tree cleanups (removed obsolete files
- crypto/bf/asm/bf586.pl, test/test.txt and crypto/sha/asm/f.s; changed
- permission on "config" script to be executable) and a fix for the INSTALL
- document.
- [Ulf Moeller <ulf@fitug.de>]
-
- *) Remove some legacy and erroneous uses of malloc, free instead of
- Malloc, Free.
- [Lennart Bang <lob@netstream.se>, with minor changes by Steve]
-
- *) Make rsa_oaep_test return non-zero on error.
- [Ulf Moeller <ulf@fitug.de>]
-
- *) Add support for native Solaris shared libraries. Configure
- solaris-sparc-sc4-pic, make, then run shlib/solaris-sc4.sh. It'd be nice
- if someone would make that last step automatic.
- [Matthias Loepfe <Matthias.Loepfe@AdNovum.CH>]
-
- *) ctx_size was not built with the right compiler during "make links". Fixed.
- [Ben Laurie]
-
- *) Change the meaning of 'ALL' in the cipher list. It now means "everything
- except NULL ciphers". This means the default cipher list will no longer
- enable NULL ciphers. They need to be specifically enabled e.g. with
- the string "DEFAULT:eNULL".
- [Steve Henson]
-
- *) Fix to RSA private encryption routines: if p < q then it would
- occasionally produce an invalid result. This will only happen with
- externally generated keys because OpenSSL (and SSLeay) ensure p > q.
- [Steve Henson]
-
- *) Be less restrictive and allow also `perl util/perlpath.pl
- /path/to/bin/perl' in addition to `perl util/perlpath.pl /path/to/bin',
- because this way one can also use an interpreter named `perl5' (which is
- usually the name of Perl 5.xxx on platforms where an Perl 4.x is still
- installed as `perl').
- [Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
-
- *) Let util/clean-depend.pl work also with older Perl 5.00x versions.
- [Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
-
- *) Fix Makefile.org so CC,CFLAG etc are passed to 'make links' add
- advapi32.lib to Win32 build and change the pem test comparision
- to fc.exe (thanks to Ulrich Kroener <kroneru@yahoo.com> for the
- suggestion). Fix misplaced ASNI prototypes and declarations in evp.h
- and crypto/des/ede_cbcm_enc.c.
- [Steve Henson]
-
- *) DES quad checksum was broken on big-endian architectures. Fixed.
- [Ben Laurie]
-
- *) Comment out two functions in bio.h that aren't implemented. Fix up the
- Win32 test batch file so it (might) work again. The Win32 test batch file
- is horrible: I feel ill....
- [Steve Henson]
-
- *) Move various #ifdefs around so NO_SYSLOG, NO_DIRENT etc are now selected
- in e_os.h. Audit of header files to check ANSI and non ANSI
- sections: 10 functions were absent from non ANSI section and not exported
- from Windows DLLs. Fixed up libeay.num for new functions.
- [Steve Henson]
-
- *) Make `openssl version' output lines consistent.
- [Ralf S. Engelschall]
-
- *) Fix Win32 symbol export lists for BIO functions: Added
- BIO_get_ex_new_index, BIO_get_ex_num, BIO_get_ex_data and BIO_set_ex_data
- to ms/libeay{16,32}.def.
- [Ralf S. Engelschall]
-
- *) Second round of fixing the OpenSSL perl/ stuff. It now at least compiled
- fine under Unix and passes some trivial tests I've now added. But the
- whole stuff is horribly incomplete, so a README.1ST with a disclaimer was
- added to make sure no one expects that this stuff really works in the
- OpenSSL 0.9.2 release. Additionally I've started to clean the XS sources
- up and fixed a few little bugs and inconsistencies in OpenSSL.{pm,xs} and
- openssl_bio.xs.
- [Ralf S. Engelschall]
-
- *) Fix the generation of two part addresses in perl.
- [Kenji Miyake <kenji@miyake.org>, integrated by Ben Laurie]
-
- *) Add config entry for Linux on MIPS.
- [John Tobey <jtobey@channel1.com>]
-
- *) Make links whenever Configure is run, unless we are on Windoze.
- [Ben Laurie]
-
- *) Permit extensions to be added to CRLs using crl_section in openssl.cnf.
- Currently only issuerAltName and AuthorityKeyIdentifier make any sense
- in CRLs.
- [Steve Henson]
-
- *) Add a useful kludge to allow package maintainers to specify compiler and
- other platforms details on the command line without having to patch the
- Configure script everytime: One now can use ``perl Configure
- <id>:<details>'', i.e. platform ids are allowed to have details appended
- to them (seperated by colons). This is treated as there would be a static
- pre-configured entry in Configure's %table under key <id> with value
- <details> and ``perl Configure <id>'' is called. So, when you want to
- perform a quick test-compile under FreeBSD 3.1 with pgcc and without
- assembler stuff you can use ``perl Configure "FreeBSD-elf:pgcc:-O6:::"''
- now, which overrides the FreeBSD-elf entry on-the-fly.
- [Ralf S. Engelschall]
-
- *) Disable new TLS1 ciphersuites by default: they aren't official yet.
- [Ben Laurie]
-
- *) Allow DSO flags like -fpic, -fPIC, -KPIC etc. to be specified
- on the `perl Configure ...' command line. This way one can compile
- OpenSSL libraries with Position Independent Code (PIC) which is needed
- for linking it into DSOs.
- [Ralf S. Engelschall]
-
- *) Remarkably, export ciphers were totally broken and no-one had noticed!
- Fixed.
- [Ben Laurie]
-
- *) Cleaned up the LICENSE document: The official contact for any license
- questions now is the OpenSSL core team under openssl-core@openssl.org.
- And add a paragraph about the dual-license situation to make sure people
- recognize that _BOTH_ the OpenSSL license _AND_ the SSLeay license apply
- to the OpenSSL toolkit.
- [Ralf S. Engelschall]
-
- *) General source tree makefile cleanups: Made `making xxx in yyy...'
- display consistent in the source tree and replaced `/bin/rm' by `rm'.
- Additonally cleaned up the `make links' target: Remove unnecessary
- semicolons, subsequent redundant removes, inline point.sh into mklink.sh
- to speed processing and no longer clutter the display with confusing
- stuff. Instead only the actually done links are displayed.
- [Ralf S. Engelschall]
-
- *) Permit null encryption ciphersuites, used for authentication only. It used
- to be necessary to set the preprocessor define SSL_ALLOW_ENULL to do this.
- It is now necessary to set SSL_FORBID_ENULL to prevent the use of null
- encryption.
- [Ben Laurie]
-
- *) Add a bunch of fixes to the PKCS#7 stuff. It used to sometimes reorder
- signed attributes when verifying signatures (this would break them),
- the detached data encoding was wrong and public keys obtained using
- X509_get_pubkey() weren't freed.
- [Steve Henson]
-
- *) Add text documentation for the BUFFER functions. Also added a work around
- to a Win95 console bug. This was triggered by the password read stuff: the
- last character typed gets carried over to the next fread(). If you were
- generating a new cert request using 'req' for example then the last
- character of the passphrase would be CR which would then enter the first
- field as blank.
- [Steve Henson]
-
- *) Added the new `Includes OpenSSL Cryptography Software' button as
- doc/openssl_button.{gif,html} which is similar in style to the old SSLeay
- button and can be used by applications based on OpenSSL to show the
- relationship to the OpenSSL project.
- [Ralf S. Engelschall]
-
- *) Remove confusing variables in function signatures in files
- ssl/ssl_lib.c and ssl/ssl.h.
- [Lennart Bong <lob@kulthea.stacken.kth.se>]
-
- *) Don't install bss_file.c under PREFIX/include/
- [Lennart Bong <lob@kulthea.stacken.kth.se>]
-
- *) Get the Win32 compile working again. Modify mkdef.pl so it can handle
- functions that return function pointers and has support for NT specific
- stuff. Fix mk1mf.pl and VC-32.pl to support NT differences also. Various
- #ifdef WIN32 and WINNTs sprinkled about the place and some changes from
- unsigned to signed types: this was killing the Win32 compile.
- [Steve Henson]
-
- *) Add new certificate file to stack functions,
- SSL_add_dir_cert_subjects_to_stack() and
- SSL_add_file_cert_subjects_to_stack(). These largely supplant
- SSL_load_client_CA_file(), and can be used to add multiple certs easily
- to a stack (usually this is then handed to SSL_CTX_set_client_CA_list()).
- This means that Apache-SSL and similar packages don't have to mess around
- to add as many CAs as they want to the preferred list.
- [Ben Laurie]
-
- *) Experiment with doxygen documentation. Currently only partially applied to
- ssl/ssl_lib.c.
- See http://www.stack.nl/~dimitri/doxygen/index.html, and run doxygen with
- openssl.doxy as the configuration file.
- [Ben Laurie]
-
- *) Get rid of remaining C++-style comments which strict C compilers hate.
- [Ralf S. Engelschall, pointed out by Carlos Amengual]
-
- *) Changed BN_RECURSION in bn_mont.c to BN_RECURSION_MONT so it is not
- compiled in by default: it has problems with large keys.
- [Steve Henson]
-
- *) Add a bunch of SSL_xxx() functions for configuring the temporary RSA and
- DH private keys and/or callback functions which directly correspond to
- their SSL_CTX_xxx() counterparts but work on a per-connection basis. This
- is needed for applications which have to configure certificates on a
- per-connection basis (e.g. Apache+mod_ssl) instead of a per-context basis
- (e.g. s_server).
- For the RSA certificate situation is makes no difference, but
- for the DSA certificate situation this fixes the "no shared cipher"
- problem where the OpenSSL cipher selection procedure failed because the
- temporary keys were not overtaken from the context and the API provided
- no way to reconfigure them.
- The new functions now let applications reconfigure the stuff and they
- are in detail: SSL_need_tmp_RSA, SSL_set_tmp_rsa, SSL_set_tmp_dh,
- SSL_set_tmp_rsa_callback and SSL_set_tmp_dh_callback. Additionally a new
- non-public-API function ssl_cert_instantiate() is used as a helper
- function and also to reduce code redundancy inside ssl_rsa.c.
- [Ralf S. Engelschall]
-
- *) Move s_server -dcert and -dkey options out of the undocumented feature
- area because they are useful for the DSA situation and should be
- recognized by the users.
- [Ralf S. Engelschall]
-
- *) Fix the cipher decision scheme for export ciphers: the export bits are
- *not* within SSL_MKEY_MASK or SSL_AUTH_MASK, they are within
- SSL_EXP_MASK. So, the original variable has to be used instead of the
- already masked variable.
- [Richard Levitte <levitte@stacken.kth.se>]
-
- *) Fix 'port' variable from `int' to `unsigned int' in crypto/bio/b_sock.c
- [Richard Levitte <levitte@stacken.kth.se>]
-
- *) Change type of another md_len variable in pk7_doit.c:PKCS7_dataFinal()
- from `int' to `unsigned int' because it's a length and initialized by
- EVP_DigestFinal() which expects an `unsigned int *'.
- [Richard Levitte <levitte@stacken.kth.se>]
-
- *) Don't hard-code path to Perl interpreter on shebang line of Configure
- script. Instead use the usual Shell->Perl transition trick.
- [Ralf S. Engelschall]
-
- *) Make `openssl x509 -noout -modulus' functional also for DSA certificates
- (in addition to RSA certificates) to match the behaviour of `openssl dsa
- -noout -modulus' as it's already the case for `openssl rsa -noout
- -modulus'. For RSA the -modulus is the real "modulus" while for DSA
- currently the public key is printed (a decision which was already done by
- `openssl dsa -modulus' in the past) which serves a similar purpose.
- Additionally the NO_RSA no longer completely removes the whole -modulus
- option; it now only avoids using the RSA stuff. Same applies to NO_DSA
- now, too.
- [Ralf S. Engelschall]
-
- *) Add Arne Ansper's reliable BIO - this is an encrypted, block-digested
- BIO. See the source (crypto/evp/bio_ok.c) for more info.
- [Arne Ansper <arne@ats.cyber.ee>]
-
- *) Dump the old yucky req code that tried (and failed) to allow raw OIDs
- to be added. Now both 'req' and 'ca' can use new objects defined in the
- config file.
- [Steve Henson]
-
- *) Add cool BIO that does syslog (or event log on NT).
- [Arne Ansper <arne@ats.cyber.ee>, integrated by Ben Laurie]
-
- *) Add support for new TLS ciphersuites, TLS_RSA_EXPORT56_WITH_RC4_56_MD5,
- TLS_RSA_EXPORT56_WITH_RC2_CBC_56_MD5 and
- TLS_RSA_EXPORT56_WITH_DES_CBC_SHA, as specified in "56-bit Export Cipher
- Suites For TLS", draft-ietf-tls-56-bit-ciphersuites-00.txt.
- [Ben Laurie]
-
- *) Add preliminary config info for new extension code.
- [Steve Henson]
-
- *) Make RSA_NO_PADDING really use no padding.
- [Ulf Moeller <ulf@fitug.de>]
-
- *) Generate errors when private/public key check is done.
- [Ben Laurie]
-
- *) Overhaul for 'crl' utility. New function X509_CRL_print. Partial support
- for some CRL extensions and new objects added.
- [Steve Henson]
-
- *) Really fix the ASN1 IMPLICIT bug this time... Partial support for private
- key usage extension and fuller support for authority key id.
- [Steve Henson]
-
- *) Add OAEP encryption for the OpenSSL crypto library. OAEP is the improved
- padding method for RSA, which is recommended for new applications in PKCS
- #1 v2.0 (RFC 2437, October 1998).
- OAEP (Optimal Asymmetric Encryption Padding) has better theoretical
- foundations than the ad-hoc padding used in PKCS #1 v1.5. It is secure
- against Bleichbacher's attack on RSA.
- [Ulf Moeller <ulf@fitug.de>, reformatted, corrected and integrated by
- Ben Laurie]
-
- *) Updates to the new SSL compression code
- [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
-
- *) Fix so that the version number in the master secret, when passed
- via RSA, checks that if TLS was proposed, but we roll back to SSLv3
- (because the server will not accept higher), that the version number
- is 0x03,0x01, not 0x03,0x00
- [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
-
- *) Run extensive memory leak checks on SSL apps. Fixed *lots* of memory
- leaks in ssl/ relating to new X509_get_pubkey() behaviour. Also fixes
- in apps/ and an unrelated leak in crypto/dsa/dsa_vrf.c
- [Steve Henson]
-
- *) Support for RAW extensions where an arbitrary extension can be
- created by including its DER encoding. See apps/openssl.cnf for
- an example.
- [Steve Henson]
-
- *) Make sure latest Perl versions don't interpret some generated C array
- code as Perl array code in the crypto/err/err_genc.pl script.
- [Lars Weber <3weber@informatik.uni-hamburg.de>]
-
- *) Modify ms/do_ms.bat to not generate assembly language makefiles since
- not many people have the assembler. Various Win32 compilation fixes and
- update to the INSTALL.W32 file with (hopefully) more accurate Win32
- build instructions.
- [Steve Henson]
-
- *) Modify configure script 'Configure' to automatically create crypto/date.h
- file under Win32 and also build pem.h from pem.org. New script
- util/mkfiles.pl to create the MINFO file on environments that can't do a
- 'make files': perl util/mkfiles.pl >MINFO should work.
- [Steve Henson]
-
- *) Major rework of DES function declarations, in the pursuit of correctness
- and purity. As a result, many evil casts evaporated, and some weirdness,
- too. You may find this causes warnings in your code. Zapping your evil
- casts will probably fix them. Mostly.
- [Ben Laurie]
-
- *) Fix for a typo in asn1.h. Bug fix to object creation script
- obj_dat.pl. It considered a zero in an object definition to mean
- "end of object": none of the objects in objects.h have any zeros
- so it wasn't spotted.
- [Steve Henson, reported by Erwann ABALEA <eabalea@certplus.com>]
-
- *) Add support for Triple DES Cipher Block Chaining with Output Feedback
- Masking (CBCM). In the absence of test vectors, the best I have been able
- to do is check that the decrypt undoes the encrypt, so far. Send me test
- vectors if you have them.
- [Ben Laurie]
-
- *) Correct calculation of key length for export ciphers (too much space was
- allocated for null ciphers). This has not been tested!
- [Ben Laurie]
-
- *) Modifications to the mkdef.pl for Win32 DEF file creation. The usage
- message is now correct (it understands "crypto" and "ssl" on its
- command line). There is also now an "update" option. This will update
- the util/ssleay.num and util/libeay.num files with any new functions.
- If you do a:
- perl util/mkdef.pl crypto ssl update
- it will update them.
- [Steve Henson]
-
- *) Overhauled the Perl interface (perl/*):
- - ported BN stuff to OpenSSL's different BN library
- - made the perl/ source tree CVS-aware
- - renamed the package from SSLeay to OpenSSL (the files still contain
- their history because I've copied them in the repository)
- - removed obsolete files (the test scripts will be replaced
- by better Test::Harness variants in the future)
- [Ralf S. Engelschall]
-
- *) First cut for a very conservative source tree cleanup:
- 1. merge various obsolete readme texts into doc/ssleay.txt
- where we collect the old documents and readme texts.
- 2. remove the first part of files where I'm already sure that we no
- longer need them because of three reasons: either they are just temporary
- files which were left by Eric or they are preserved original files where
- I've verified that the diff is also available in the CVS via "cvs diff
- -rSSLeay_0_8_1b" or they were renamed (as it was definitely the case for
- the crypto/md/ stuff).
- [Ralf S. Engelschall]
-
- *) More extension code. Incomplete support for subject and issuer alt
- name, issuer and authority key id. Change the i2v function parameters
- and add an extra 'crl' parameter in the X509V3_CTX structure: guess
- what that's for :-) Fix to ASN1 macro which messed up
- IMPLICIT tag and add f_enum.c which adds a2i, i2a for ENUMERATED.
- [Steve Henson]
-
- *) Preliminary support for ENUMERATED type. This is largely copied from the
- INTEGER code.
- [Steve Henson]
-
- *) Add new function, EVP_MD_CTX_copy() to replace frequent use of memcpy.
- [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
-
- *) Make sure `make rehash' target really finds the `openssl' program.
- [Ralf S. Engelschall, Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
-
- *) Squeeze another 7% of speed out of MD5 assembler, at least on a P2. I'd
- like to hear about it if this slows down other processors.
- [Ben Laurie]
-
- *) Add CygWin32 platform information to Configure script.
- [Alan Batie <batie@aahz.jf.intel.com>]
-
- *) Fixed ms/32all.bat script: `no_asm' -> `no-asm'
- [Rainer W. Gerling <gerling@mpg-gv.mpg.de>]
-
- *) New program nseq to manipulate netscape certificate sequences
- [Steve Henson]
-
- *) Modify crl2pkcs7 so it supports multiple -certfile arguments. Fix a
- few typos.
- [Steve Henson]
-
- *) Fixes to BN code. Previously the default was to define BN_RECURSION
- but the BN code had some problems that would cause failures when
- doing certificate verification and some other functions.
- [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
-
- *) Add ASN1 and PEM code to support netscape certificate sequences.
- [Steve Henson]
-
- *) Add ASN1 and PEM code to support netscape certificate sequences.
- [Steve Henson]
-
- *) Add several PKIX and private extended key usage OIDs.
- [Steve Henson]
-
- *) Modify the 'ca' program to handle the new extension code. Modify
- openssl.cnf for new extension format, add comments.
- [Steve Henson]
-
- *) More X509 V3 changes. Fix typo in v3_bitstr.c. Add support to 'req'
- and add a sample to openssl.cnf so req -x509 now adds appropriate
- CA extensions.
- [Steve Henson]
-
- *) Continued X509 V3 changes. Add to other makefiles, integrate with the
- error code, add initial support to X509_print() and x509 application.
- [Steve Henson]
-
- *) Takes a deep breath and start addding X509 V3 extension support code. Add
- files in crypto/x509v3. Move original stuff to crypto/x509v3/old. All this
- stuff is currently isolated and isn't even compiled yet.
- [Steve Henson]
-
- *) Continuing patches for GeneralizedTime. Fix up certificate and CRL
- ASN1 to use ASN1_TIME and modify print routines to use ASN1_TIME_print.
- Removed the versions check from X509 routines when loading extensions:
- this allows certain broken certificates that don't set the version
- properly to be processed.
- [Steve Henson]
-
- *) Deal with irritating shit to do with dependencies, in YAAHW (Yet Another
- Ad Hoc Way) - Makefile.ssls now all contain local dependencies, which
- can still be regenerated with "make depend".
- [Ben Laurie]
-
- *) Spelling mistake in C version of CAST-128.
- [Ben Laurie, reported by Jeremy Hylton <jeremy@cnri.reston.va.us>]
-
- *) Changes to the error generation code. The perl script err-code.pl
- now reads in the old error codes and retains the old numbers, only
- adding new ones if necessary. It also only changes the .err files if new
- codes are added. The makefiles have been modified to only insert errors
- when needed (to avoid needlessly modifying header files). This is done
- by only inserting errors if the .err file is newer than the auto generated
- C file. To rebuild all the error codes from scratch (the old behaviour)
- either modify crypto/Makefile.ssl to pass the -regen flag to err_code.pl
- or delete all the .err files.
- [Steve Henson]
-
- *) CAST-128 was incorrectly implemented for short keys. The C version has
- been fixed, but is untested. The assembler versions are also fixed, but
- new assembler HAS NOT BEEN GENERATED FOR WIN32 - the Makefile needs fixing
- to regenerate it if needed.
- [Ben Laurie, reported (with fix for C version) by Jun-ichiro itojun
- Hagino <itojun@kame.net>]
-
- *) File was opened incorrectly in randfile.c.
- [Ulf Möller <ulf@fitug.de>]
-
- *) Beginning of support for GeneralizedTime. d2i, i2d, check and print
- functions. Also ASN1_TIME suite which is a CHOICE of UTCTime or
- GeneralizedTime. ASN1_TIME is the proper type used in certificates et
- al: it's just almost always a UTCTime. Note this patch adds new error
- codes so do a "make errors" if there are problems.
- [Steve Henson]
-
- *) Correct Linux 1 recognition in config.
- [Ulf Möller <ulf@fitug.de>]
-
- *) Remove pointless MD5 hash when using DSA keys in ca.
- [Anonymous <nobody@replay.com>]
-
- *) Generate an error if given an empty string as a cert directory. Also
- generate an error if handed NULL (previously returned 0 to indicate an
- error, but didn't set one).
- [Ben Laurie, reported by Anonymous <nobody@replay.com>]
-
- *) Add prototypes to SSL methods. Make SSL_write's buffer const, at last.
- [Ben Laurie]
-
- *) Fix the dummy function BN_ref_mod_exp() in rsaref.c to have the correct
- parameters. This was causing a warning which killed off the Win32 compile.
- [Steve Henson]
-
- *) Remove C++ style comments from crypto/bn/bn_local.h.
- [Neil Costigan <neil.costigan@celocom.com>]
-
- *) The function OBJ_txt2nid was broken. It was supposed to return a nid
- based on a text string, looking up short and long names and finally
- "dot" format. The "dot" format stuff didn't work. Added new function
- OBJ_txt2obj to do the same but return an ASN1_OBJECT and rewrote
- OBJ_txt2nid to use it. OBJ_txt2obj can also return objects even if the
- OID is not part of the table.
- [Steve Henson]
-
- *) Add prototypes to X509 lookup/verify methods, fixing a bug in
- X509_LOOKUP_by_alias().
- [Ben Laurie]
-
- *) Sort openssl functions by name.
- [Ben Laurie]
-
- *) Get the gendsa program working (hopefully) and add it to app list. Remove
- encryption from sample DSA keys (in case anyone is interested the password
- was "1234").
- [Steve Henson]
-
- *) Make _all_ *_free functions accept a NULL pointer.
- [Frans Heymans <fheymans@isaserver.be>]
-
- *) If a DH key is generated in s3_srvr.c, don't blow it by trying to use
- NULL pointers.
- [Anonymous <nobody@replay.com>]
-
- *) s_server should send the CAfile as acceptable CAs, not its own cert.
- [Bodo Moeller <3moeller@informatik.uni-hamburg.de>]
-
- *) Don't blow it for numeric -newkey arguments to apps/req.
- [Bodo Moeller <3moeller@informatik.uni-hamburg.de>]
-
- *) Temp key "for export" tests were wrong in s3_srvr.c.
- [Anonymous <nobody@replay.com>]
-
- *) Add prototype for temp key callback functions
- SSL_CTX_set_tmp_{rsa,dh}_callback().
- [Ben Laurie]
-
- *) Make DH_free() tolerate being passed a NULL pointer (like RSA_free() and
- DSA_free()). Make X509_PUBKEY_set() check for errors in d2i_PublicKey().
- [Steve Henson]
-
- *) X509_name_add_entry() freed the wrong thing after an error.
- [Arne Ansper <arne@ats.cyber.ee>]
-
- *) rsa_eay.c would attempt to free a NULL context.
- [Arne Ansper <arne@ats.cyber.ee>]
-
- *) BIO_s_socket() had a broken should_retry() on Windoze.
- [Arne Ansper <arne@ats.cyber.ee>]
-
- *) BIO_f_buffer() didn't pass on BIO_CTRL_FLUSH.
- [Arne Ansper <arne@ats.cyber.ee>]
-
- *) Make sure the already existing X509_STORE->depth variable is initialized
- in X509_STORE_new(), but document the fact that this variable is still
- unused in the certificate verification process.
- [Ralf S. Engelschall]
-
- *) Fix the various library and apps files to free up pkeys obtained from
- X509_PUBKEY_get() et al. Also allow x509.c to handle netscape extensions.
- [Steve Henson]
-
- *) Fix reference counting in X509_PUBKEY_get(). This makes
- demos/maurice/example2.c work, amongst others, probably.
- [Steve Henson and Ben Laurie]
-
- *) First cut of a cleanup for apps/. First the `ssleay' program is now named
- `openssl' and second, the shortcut symlinks for the `openssl <command>'
- are no longer created. This way we have a single and consistent command
- line interface `openssl <command>', similar to `cvs <command>'.
- [Ralf S. Engelschall, Paul Sutton and Ben Laurie]
-
- *) ca.c: move test for DSA keys inside #ifndef NO_DSA. Make pubkey
- BIT STRING wrapper always have zero unused bits.
- [Steve Henson]
-
- *) Add CA.pl, perl version of CA.sh, add extended key usage OID.
- [Steve Henson]
-
- *) Make the top-level INSTALL documentation easier to understand.
- [Paul Sutton]
-
- *) Makefiles updated to exit if an error occurs in a sub-directory
- make (including if user presses ^C) [Paul Sutton]
-
- *) Make Montgomery context stuff explicit in RSA data structure.
- [Ben Laurie]
-
- *) Fix build order of pem and err to allow for generated pem.h.
- [Ben Laurie]
-
- *) Fix renumbering bug in X509_NAME_delete_entry().
- [Ben Laurie]
-
- *) Enhanced the err-ins.pl script so it makes the error library number
- global and can add a library name. This is needed for external ASN1 and
- other error libraries.
- [Steve Henson]
-
- *) Fixed sk_insert which never worked properly.
- [Steve Henson]
-
- *) Fix ASN1 macros so they can handle indefinite length construted
- EXPLICIT tags. Some non standard certificates use these: they can now
- be read in.
- [Steve Henson]
-
- *) Merged the various old/obsolete SSLeay documentation files (doc/xxx.doc)
- into a single doc/ssleay.txt bundle. This way the information is still
- preserved but no longer messes up this directory. Now it's new room for
- the new set of documenation files.
- [Ralf S. Engelschall]
-
- *) SETs were incorrectly DER encoded. This was a major pain, because they
- shared code with SEQUENCEs, which aren't coded the same. This means that
- almost everything to do with SETs or SEQUENCEs has either changed name or
- number of arguments.
- [Ben Laurie, based on a partial fix by GP Jayan <gp@nsj.co.jp>]
-
- *) Fix test data to work with the above.
- [Ben Laurie]
-
- *) Fix the RSA header declarations that hid a bug I fixed in 0.9.0b but
- was already fixed by Eric for 0.9.1 it seems.
- [Ben Laurie - pointed out by Ulf Möller <ulf@fitug.de>]
-
- *) Autodetect FreeBSD3.
- [Ben Laurie]
-
- *) Fix various bugs in Configure. This affects the following platforms:
- nextstep
- ncr-scde
- unixware-2.0
- unixware-2.0-pentium
- sco5-cc.
- [Ben Laurie]
-
- *) Eliminate generated files from CVS. Reorder tests to regenerate files
- before they are needed.
- [Ben Laurie]
-
- *) Generate Makefile.ssl from Makefile.org (to keep CVS happy).
- [Ben Laurie]
-
-
- Changes between 0.9.1b and 0.9.1c [23-Dec-1998]
-
- *) Added OPENSSL_VERSION_NUMBER to crypto/crypto.h and
- changed SSLeay to OpenSSL in version strings.
- [Ralf S. Engelschall]
-
- *) Some fixups to the top-level documents.
- [Paul Sutton]
-
- *) Fixed the nasty bug where rsaref.h was not found under compile-time
- because the symlink to include/ was missing.
- [Ralf S. Engelschall]
-
- *) Incorporated the popular no-RSA/DSA-only patches
- which allow to compile a RSA-free SSLeay.
- [Andrew Cooke / Interrader Ldt., Ralf S. Engelschall]
-
- *) Fixed nasty rehash problem under `make -f Makefile.ssl links'
- when "ssleay" is still not found.
- [Ralf S. Engelschall]
-
- *) Added more platforms to Configure: Cray T3E, HPUX 11,
- [Ralf S. Engelschall, Beckmann <beckman@acl.lanl.gov>]
-
- *) Updated the README file.
- [Ralf S. Engelschall]
-
- *) Added various .cvsignore files in the CVS repository subdirs
- to make a "cvs update" really silent.
- [Ralf S. Engelschall]
-
- *) Recompiled the error-definition header files and added
- missing symbols to the Win32 linker tables.
- [Ralf S. Engelschall]
-
- *) Cleaned up the top-level documents;
- o new files: CHANGES and LICENSE
- o merged VERSION, HISTORY* and README* files a CHANGES.SSLeay
- o merged COPYRIGHT into LICENSE
- o removed obsolete TODO file
- o renamed MICROSOFT to INSTALL.W32
- [Ralf S. Engelschall]
-
- *) Removed dummy files from the 0.9.1b source tree:
- crypto/asn1/x crypto/bio/cd crypto/bio/fg crypto/bio/grep crypto/bio/vi
- crypto/bn/asm/......add.c crypto/bn/asm/a.out crypto/dsa/f crypto/md5/f
- crypto/pem/gmon.out crypto/perlasm/f crypto/pkcs7/build crypto/rsa/f
- crypto/sha/asm/f crypto/threads/f ms/zzz ssl/f ssl/f.mak test/f
- util/f.mak util/pl/f util/pl/f.mak crypto/bf/bf_locl.old apps/f
- [Ralf S. Engelschall]
-
- *) Added various platform portability fixes.
- [Mark J. Cox]
-
- *) The Genesis of the OpenSSL rpject:
- We start with the latest (unreleased) SSLeay version 0.9.1b which Eric A.
- Young and Tim J. Hudson created while they were working for C2Net until
- summer 1998.
- [The OpenSSL Project]
-
-
- Changes between 0.9.0b and 0.9.1b [not released]
-
- *) Updated a few CA certificates under certs/
- [Eric A. Young]
-
- *) Changed some BIGNUM api stuff.
- [Eric A. Young]
-
- *) Various platform ports: OpenBSD, Ultrix, IRIX 64bit, NetBSD,
- DGUX x86, Linux Alpha, etc.
- [Eric A. Young]
-
- *) New COMP library [crypto/comp/] for SSL Record Layer Compression:
- RLE (dummy implemented) and ZLIB (really implemented when ZLIB is
- available).
- [Eric A. Young]
-
- *) Add -strparse option to asn1pars program which parses nested
- binary structures
- [Dr Stephen Henson <shenson@bigfoot.com>]
-
- *) Added "oid_file" to ssleay.cnf for "ca" and "req" programs.
- [Eric A. Young]
-
- *) DSA fix for "ca" program.
- [Eric A. Young]
-
- *) Added "-genkey" option to "dsaparam" program.
- [Eric A. Young]
-
- *) Added RIPE MD160 (rmd160) message digest.
- [Eric A. Young]
-
- *) Added -a (all) option to "ssleay version" command.
- [Eric A. Young]
-
- *) Added PLATFORM define which is the id given to Configure.
- [Eric A. Young]
-
- *) Added MemCheck_XXXX functions to crypto/mem.c for memory checking.
- [Eric A. Young]
-
- *) Extended the ASN.1 parser routines.
- [Eric A. Young]
-
- *) Extended BIO routines to support REUSEADDR, seek, tell, etc.
- [Eric A. Young]
-
- *) Added a BN_CTX to the BN library.
- [Eric A. Young]
-
- *) Fixed the weak key values in DES library
- [Eric A. Young]
-
- *) Changed API in EVP library for cipher aliases.
- [Eric A. Young]
-
- *) Added support for RC2/64bit cipher.
- [Eric A. Young]
-
- *) Converted the lhash library to the crypto/mem.c functions.
- [Eric A. Young]
-
- *) Added more recognized ASN.1 object ids.
- [Eric A. Young]
-
- *) Added more RSA padding checks for SSL/TLS.
- [Eric A. Young]
-
- *) Added BIO proxy/filter functionality.
- [Eric A. Young]
-
- *) Added extra_certs to SSL_CTX which can be used
- send extra CA certificates to the client in the CA cert chain sending
- process. It can be configured with SSL_CTX_add_extra_chain_cert().
- [Eric A. Young]
-
- *) Now Fortezza is denied in the authentication phase because
- this is key exchange mechanism is not supported by SSLeay at all.
- [Eric A. Young]
-
- *) Additional PKCS1 checks.
- [Eric A. Young]
-
- *) Support the string "TLSv1" for all TLS v1 ciphers.
- [Eric A. Young]
-
- *) Added function SSL_get_ex_data_X509_STORE_CTX_idx() which gives the
- ex_data index of the SSL context in the X509_STORE_CTX ex_data.
- [Eric A. Young]
-
- *) Fixed a few memory leaks.
- [Eric A. Young]
-
- *) Fixed various code and comment typos.
- [Eric A. Young]
-
- *) A minor bug in ssl/s3_clnt.c where there would always be 4 0
- bytes sent in the client random.
- [Edward Bishop <ebishop@spyglass.com>]
-
+
+ OpenSSL CHANGES
+ _______________
+
+ Changes between 1.0.0c and 1.0.0d [8 Feb 2011]
+
+ *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014
+ [Neel Mehta, Adam Langley, Bodo Moeller (Google)]
+
+ *) Fix bug in string printing code: if *any* escaping is enabled we must
+ escape the escape character (backslash) or the resulting string is
+ ambiguous.
+ [Steve Henson]
+
+ Changes between 1.0.0b and 1.0.0c [2 Dec 2010]
+
+ *) Disable code workaround for ancient and obsolete Netscape browsers
+ and servers: an attacker can use it in a ciphersuite downgrade attack.
+ Thanks to Martin Rex for discovering this bug. CVE-2010-4180
+ [Steve Henson]
+
+ *) Fixed J-PAKE implementation error, originally discovered by
+ Sebastien Martini, further info and confirmation from Stefan
+ Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252
+ [Ben Laurie]
+
+ Changes between 1.0.0a and 1.0.0b [16 Nov 2010]
+
+ *) Fix extension code to avoid race conditions which can result in a buffer
+ overrun vulnerability: resumed sessions must not be modified as they can
+ be shared by multiple threads. CVE-2010-3864
+ [Steve Henson]
+
+ *) Fix WIN32 build system to correctly link an ENGINE directory into
+ a DLL.
+ [Steve Henson]
+
+ Changes between 1.0.0 and 1.0.0a [01 Jun 2010]
+
+ *) Check return value of int_rsa_verify in pkey_rsa_verifyrecover
+ (CVE-2010-1633)
+ [Steve Henson, Peter-Michael Hager <hager@dortmund.net>]
+
+ Changes between 0.9.8n and 1.0.0 [29 Mar 2010]
+
+ *) Add "missing" function EVP_CIPHER_CTX_copy(). This copies a cipher
+ context. The operation can be customised via the ctrl mechanism in
+ case ENGINEs want to include additional functionality.
+ [Steve Henson]
+
+ *) Tolerate yet another broken PKCS#8 key format: private key value negative.
+ [Steve Henson]
+
+ *) Add new -subject_hash_old and -issuer_hash_old options to x509 utility to
+ output hashes compatible with older versions of OpenSSL.
+ [Willy Weisz <weisz@vcpc.univie.ac.at>]
+
+ *) Fix compression algorithm handling: if resuming a session use the
+ compression algorithm of the resumed session instead of determining
+ it from client hello again. Don't allow server to change algorithm.
+ [Steve Henson]
+
+ *) Add load_crls() function to apps tidying load_certs() too. Add option
+ to verify utility to allow additional CRLs to be included.
+ [Steve Henson]
+
+ *) Update OCSP request code to permit adding custom headers to the request:
+ some responders need this.
+ [Steve Henson]
+
+ *) The function EVP_PKEY_sign() returns <=0 on error: check return code
+ correctly.
+ [Julia Lawall <julia@diku.dk>]
+
+ *) Update verify callback code in apps/s_cb.c and apps/verify.c, it
+ needlessly dereferenced structures, used obsolete functions and
+ didn't handle all updated verify codes correctly.
+ [Steve Henson]
+
+ *) Disable MD2 in the default configuration.
+ [Steve Henson]
+
+ *) In BIO_pop() and BIO_push() use the ctrl argument (which was NULL) to
+ indicate the initial BIO being pushed or popped. This makes it possible
+ to determine whether the BIO is the one explicitly called or as a result
+ of the ctrl being passed down the chain. Fix BIO_pop() and SSL BIOs so
+ it handles reference counts correctly and doesn't zero out the I/O bio
+ when it is not being explicitly popped. WARNING: applications which
+ included workarounds for the old buggy behaviour will need to be modified
+ or they could free up already freed BIOs.
+ [Steve Henson]
+
+ *) Extend the uni2asc/asc2uni => OPENSSL_uni2asc/OPENSSL_asc2uni
+ renaming to all platforms (within the 0.9.8 branch, this was
+ done conditionally on Netware platforms to avoid a name clash).
+ [Guenter <lists@gknw.net>]
+
+ *) Add ECDHE and PSK support to DTLS.
+ [Michael Tuexen <tuexen@fh-muenster.de>]
+
+ *) Add CHECKED_STACK_OF macro to safestack.h, otherwise safestack can't
+ be used on C++.
+ [Steve Henson]
+
+ *) Add "missing" function EVP_MD_flags() (without this the only way to
+ retrieve a digest flags is by accessing the structure directly. Update
+ EVP_MD_do_all*() and EVP_CIPHER_do_all*() to include the name a digest
+ or cipher is registered as in the "from" argument. Print out all
+ registered digests in the dgst usage message instead of manually
+ attempting to work them out.
+ [Steve Henson]
+
+ *) If no SSLv2 ciphers are used don't use an SSLv2 compatible client hello:
+ this allows the use of compression and extensions. Change default cipher
+ string to remove SSLv2 ciphersuites. This effectively avoids ancient SSLv2
+ by default unless an application cipher string requests it.
+ [Steve Henson]
+
+ *) Alter match criteria in PKCS12_parse(). It used to try to use local
+ key ids to find matching certificates and keys but some PKCS#12 files
+ don't follow the (somewhat unwritten) rules and this strategy fails.
+ Now just gather all certificates together and the first private key
+ then look for the first certificate that matches the key.
+ [Steve Henson]
+
+ *) Support use of registered digest and cipher names for dgst and cipher
+ commands instead of having to add each one as a special case. So now
+ you can do:
+
+ openssl sha256 foo
+
+ as well as:
+
+ openssl dgst -sha256 foo
+
+ and this works for ENGINE based algorithms too.
+
+ [Steve Henson]
+
+ *) Update Gost ENGINE to support parameter files.
+ [Victor B. Wagner <vitus@cryptocom.ru>]
+
+ *) Support GeneralizedTime in ca utility.
+ [Oliver Martin <oliver@volatilevoid.net>, Steve Henson]
+
+ *) Enhance the hash format used for certificate directory links. The new
+ form uses the canonical encoding (meaning equivalent names will work
+ even if they aren't identical) and uses SHA1 instead of MD5. This form
+ is incompatible with the older format and as a result c_rehash should
+ be used to rebuild symbolic links.
+ [Steve Henson]
+
+ *) Make PKCS#8 the default write format for private keys, replacing the
+ traditional format. This form is standardised, more secure and doesn't
+ include an implicit MD5 dependency.
+ [Steve Henson]
+
+ *) Add a $gcc_devteam_warn option to Configure. The idea is that any code
+ committed to OpenSSL should pass this lot as a minimum.
+ [Steve Henson]
+
+ *) Add session ticket override functionality for use by EAP-FAST.
+ [Jouni Malinen <j@w1.fi>]
+
+ *) Modify HMAC functions to return a value. Since these can be implemented
+ in an ENGINE errors can occur.
+ [Steve Henson]
+
+ *) Type-checked OBJ_bsearch_ex.
+ [Ben Laurie]
+
+ *) Type-checked OBJ_bsearch. Also some constification necessitated
+ by type-checking. Still to come: TXT_DB, bsearch(?),
+ OBJ_bsearch_ex, qsort, CRYPTO_EX_DATA, ASN1_VALUE, ASN1_STRING,
+ CONF_VALUE.
+ [Ben Laurie]
+
+ *) New function OPENSSL_gmtime_adj() to add a specific number of days and
+ seconds to a tm structure directly, instead of going through OS
+ specific date routines. This avoids any issues with OS routines such
+ as the year 2038 bug. New *_adj() functions for ASN1 time structures
+ and X509_time_adj_ex() to cover the extended range. The existing
+ X509_time_adj() is still usable and will no longer have any date issues.
+ [Steve Henson]
+
+ *) Delta CRL support. New use deltas option which will attempt to locate
+ and search any appropriate delta CRLs available.
+
+ This work was sponsored by Google.
+ [Steve Henson]
+
+ *) Support for CRLs partitioned by reason code. Reorganise CRL processing
+ code and add additional score elements. Validate alternate CRL paths
+ as part of the CRL checking and indicate a new error "CRL path validation
+ error" in this case. Applications wanting additional details can use
+ the verify callback and check the new "parent" field. If this is not
+ NULL CRL path validation is taking place. Existing applications wont
+ see this because it requires extended CRL support which is off by
+ default.
+
+ This work was sponsored by Google.
+ [Steve Henson]
+
+ *) Support for freshest CRL extension.
+
+ This work was sponsored by Google.
+ [Steve Henson]
+
+ *) Initial indirect CRL support. Currently only supported in the CRLs
+ passed directly and not via lookup. Process certificate issuer
+ CRL entry extension and lookup CRL entries by bother issuer name
+ and serial number. Check and process CRL issuer entry in IDP extension.
+
+ This work was sponsored by Google.
+ [Steve Henson]
+
+ *) Add support for distinct certificate and CRL paths. The CRL issuer
+ certificate is validated separately in this case. Only enabled if
+ an extended CRL support flag is set: this flag will enable additional
+ CRL functionality in future.
+
+ This work was sponsored by Google.
+ [Steve Henson]
+
+ *) Add support for policy mappings extension.
+
+ This work was sponsored by Google.
+ [Steve Henson]
+
+ *) Fixes to pathlength constraint, self issued certificate handling,
+ policy processing to align with RFC3280 and PKITS tests.
+
+ This work was sponsored by Google.
+ [Steve Henson]
+
+ *) Support for name constraints certificate extension. DN, email, DNS
+ and URI types are currently supported.
+
+ This work was sponsored by Google.
+ [Steve Henson]
+
+ *) To cater for systems that provide a pointer-based thread ID rather
+ than numeric, deprecate the current numeric thread ID mechanism and
+ replace it with a structure and associated callback type. This
+ mechanism allows a numeric "hash" to be extracted from a thread ID in
+ either case, and on platforms where pointers are larger than 'long',
+ mixing is done to help ensure the numeric 'hash' is usable even if it
+ can't be guaranteed unique. The default mechanism is to use "&errno"
+ as a pointer-based thread ID to distinguish between threads.
+
+ Applications that want to provide their own thread IDs should now use
+ CRYPTO_THREADID_set_callback() to register a callback that will call
+ either CRYPTO_THREADID_set_numeric() or CRYPTO_THREADID_set_pointer().
+
+ Note that ERR_remove_state() is now deprecated, because it is tied
+ to the assumption that thread IDs are numeric. ERR_remove_state(0)
+ to free the current thread's error state should be replaced by
+ ERR_remove_thread_state(NULL).
+
+ (This new approach replaces the functions CRYPTO_set_idptr_callback(),
+ CRYPTO_get_idptr_callback(), and CRYPTO_thread_idptr() that existed in
+ OpenSSL 0.9.9-dev between June 2006 and August 2008. Also, if an
+ application was previously providing a numeric thread callback that
+ was inappropriate for distinguishing threads, then uniqueness might
+ have been obtained with &errno that happened immediately in the
+ intermediate development versions of OpenSSL; this is no longer the
+ case, the numeric thread callback will now override the automatic use
+ of &errno.)
+ [Geoff Thorpe, with help from Bodo Moeller]
+
+ *) Initial support for different CRL issuing certificates. This covers a
+ simple case where the self issued certificates in the chain exist and
+ the real CRL issuer is higher in the existing chain.
+
+ This work was sponsored by Google.
+ [Steve Henson]
+
+ *) Removed effectively defunct crypto/store from the build.
+ [Ben Laurie]
+
+ *) Revamp of STACK to provide stronger type-checking. Still to come:
+ TXT_DB, bsearch(?), OBJ_bsearch, qsort, CRYPTO_EX_DATA, ASN1_VALUE,
+ ASN1_STRING, CONF_VALUE.
+ [Ben Laurie]
+
+ *) Add a new SSL_MODE_RELEASE_BUFFERS mode flag to release unused buffer
+ RAM on SSL connections. This option can save about 34k per idle SSL.
+ [Nick Mathewson]
+
+ *) Revamp of LHASH to provide stronger type-checking. Still to come:
+ STACK, TXT_DB, bsearch, qsort.
+ [Ben Laurie]
+
+ *) Initial support for Cryptographic Message Syntax (aka CMS) based
+ on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility,
+ support for data, signedData, compressedData, digestedData and
+ encryptedData, envelopedData types included. Scripts to check against
+ RFC4134 examples draft and interop and consistency checks of many
+ content types and variants.
+ [Steve Henson]
+
+ *) Add options to enc utility to support use of zlib compression BIO.
+ [Steve Henson]
+
+ *) Extend mk1mf to support importing of options and assembly language
+ files from Configure script, currently only included in VC-WIN32.
+ The assembly language rules can now optionally generate the source
+ files from the associated perl scripts.
+ [Steve Henson]
+
+ *) Implement remaining functionality needed to support GOST ciphersuites.
+ Interop testing has been performed using CryptoPro implementations.
+ [Victor B. Wagner <vitus@cryptocom.ru>]
+
+ *) s390x assembler pack.
+ [Andy Polyakov]
+
+ *) ARMv4 assembler pack. ARMv4 refers to v4 and later ISA, not CPU
+ "family."
+ [Andy Polyakov]
+
+ *) Implement Opaque PRF Input TLS extension as specified in
+ draft-rescorla-tls-opaque-prf-input-00.txt. Since this is not an
+ official specification yet and no extension type assignment by
+ IANA exists, this extension (for now) will have to be explicitly
+ enabled when building OpenSSL by providing the extension number
+ to use. For example, specify an option
+
+ -DTLSEXT_TYPE_opaque_prf_input=0x9527
+
+ to the "config" or "Configure" script to enable the extension,
+ assuming extension number 0x9527 (which is a completely arbitrary
+ and unofficial assignment based on the MD5 hash of the Internet
+ Draft). Note that by doing so, you potentially lose
+ interoperability with other TLS implementations since these might
+ be using the same extension number for other purposes.
+
+ SSL_set_tlsext_opaque_prf_input(ssl, src, len) is used to set the
+ opaque PRF input value to use in the handshake. This will create
+ an interal copy of the length-'len' string at 'src', and will
+ return non-zero for success.
+
+ To get more control and flexibility, provide a callback function
+ by using
+
+ SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb)
+ SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg)
+
+ where
+
+ int (*cb)(SSL *, void *peerinput, size_t len, void *arg);
+ void *arg;
+
+ Callback function 'cb' will be called in handshakes, and is
+ expected to use SSL_set_tlsext_opaque_prf_input() as appropriate.
+ Argument 'arg' is for application purposes (the value as given to
+ SSL_CTX_set_tlsext_opaque_prf_input_callback_arg() will directly
+ be provided to the callback function). The callback function
+ has to return non-zero to report success: usually 1 to use opaque
+ PRF input just if possible, or 2 to enforce use of the opaque PRF
+ input. In the latter case, the library will abort the handshake
+ if opaque PRF input is not successfully negotiated.
+
+ Arguments 'peerinput' and 'len' given to the callback function
+ will always be NULL and 0 in the case of a client. A server will
+ see the client's opaque PRF input through these variables if
+ available (NULL and 0 otherwise). Note that if the server
+ provides an opaque PRF input, the length must be the same as the
+ length of the client's opaque PRF input.
+
+ Note that the callback function will only be called when creating
+ a new session (session resumption can resume whatever was
+ previously negotiated), and will not be called in SSL 2.0
+ handshakes; thus, SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) or
+ SSL_set_options(ssl, SSL_OP_NO_SSLv2) is especially recommended
+ for applications that need to enforce opaque PRF input.
+
+ [Bodo Moeller]
+
+ *) Update ssl code to support digests other than SHA1+MD5 for handshake
+ MAC.
+
+ [Victor B. Wagner <vitus@cryptocom.ru>]
+
+ *) Add RFC4507 support to OpenSSL. This includes the corrections in
+ RFC4507bis. The encrypted ticket format is an encrypted encoded
+ SSL_SESSION structure, that way new session features are automatically
+ supported.
+
+ If a client application caches session in an SSL_SESSION structure
+ support is transparent because tickets are now stored in the encoded
+ SSL_SESSION.
+
+ The SSL_CTX structure automatically generates keys for ticket
+ protection in servers so again support should be possible
+ with no application modification.
+
+ If a client or server wishes to disable RFC4507 support then the option
+ SSL_OP_NO_TICKET can be set.
+
+ Add a TLS extension debugging callback to allow the contents of any client
+ or server extensions to be examined.
+
+ This work was sponsored by Google.
+ [Steve Henson]
+
+ *) Final changes to avoid use of pointer pointer casts in OpenSSL.
+ OpenSSL should now compile cleanly on gcc 4.2
+ [Peter Hartley <pdh@utter.chaos.org.uk>, Steve Henson]
+
+ *) Update SSL library to use new EVP_PKEY MAC API. Include generic MAC
+ support including streaming MAC support: this is required for GOST
+ ciphersuite support.
+ [Victor B. Wagner <vitus@cryptocom.ru>, Steve Henson]
+
+ *) Add option -stream to use PKCS#7 streaming in smime utility. New
+ function i2d_PKCS7_bio_stream() and PEM_write_PKCS7_bio_stream()
+ to output in BER and PEM format.
+ [Steve Henson]
+
+ *) Experimental support for use of HMAC via EVP_PKEY interface. This
+ allows HMAC to be handled via the EVP_DigestSign*() interface. The
+ EVP_PKEY "key" in this case is the HMAC key, potentially allowing
+ ENGINE support for HMAC keys which are unextractable. New -mac and
+ -macopt options to dgst utility.
+ [Steve Henson]
+
+ *) New option -sigopt to dgst utility. Update dgst to use
+ EVP_Digest{Sign,Verify}*. These two changes make it possible to use
+ alternative signing paramaters such as X9.31 or PSS in the dgst
+ utility.
+ [Steve Henson]
+
+ *) Change ssl_cipher_apply_rule(), the internal function that does
+ the work each time a ciphersuite string requests enabling
+ ("foo+bar"), moving ("+foo+bar"), disabling ("-foo+bar", or
+ removing ("!foo+bar") a class of ciphersuites: Now it maintains
+ the order of disabled ciphersuites such that those ciphersuites
+ that most recently went from enabled to disabled not only stay
+ in order with respect to each other, but also have higher priority
+ than other disabled ciphersuites the next time ciphersuites are
+ enabled again.
+
+ This means that you can now say, e.g., "PSK:-PSK:HIGH" to enable
+ the same ciphersuites as with "HIGH" alone, but in a specific
+ order where the PSK ciphersuites come first (since they are the
+ most recently disabled ciphersuites when "HIGH" is parsed).
+
+ Also, change ssl_create_cipher_list() (using this new
+ funcionality) such that between otherwise identical
+ cihpersuites, ephemeral ECDH is preferred over ephemeral DH in
+ the default order.
+ [Bodo Moeller]
+
+ *) Change ssl_create_cipher_list() so that it automatically
+ arranges the ciphersuites in reasonable order before starting
+ to process the rule string. Thus, the definition for "DEFAULT"
+ (SSL_DEFAULT_CIPHER_LIST) now is just "ALL:!aNULL:!eNULL", but
+ remains equivalent to "AES:ALL:!aNULL:!eNULL:+aECDH:+kRSA:+RC4:@STRENGTH".
+ This makes it much easier to arrive at a reasonable default order
+ in applications for which anonymous ciphers are OK (meaning
+ that you can't actually use DEFAULT).
+ [Bodo Moeller; suggested by Victor Duchovni]
+
+ *) Split the SSL/TLS algorithm mask (as used for ciphersuite string
+ processing) into multiple integers instead of setting
+ "SSL_MKEY_MASK" bits, "SSL_AUTH_MASK" bits, "SSL_ENC_MASK",
+ "SSL_MAC_MASK", and "SSL_SSL_MASK" bits all in a single integer.
+ (These masks as well as the individual bit definitions are hidden
+ away into the non-exported interface ssl/ssl_locl.h, so this
+ change to the definition of the SSL_CIPHER structure shouldn't
+ affect applications.) This give us more bits for each of these
+ categories, so there is no longer a need to coagulate AES128 and
+ AES256 into a single algorithm bit, and to coagulate Camellia128
+ and Camellia256 into a single algorithm bit, which has led to all
+ kinds of kludges.
+
+ Thus, among other things, the kludge introduced in 0.9.7m and
+ 0.9.8e for masking out AES256 independently of AES128 or masking
+ out Camellia256 independently of AES256 is not needed here in 0.9.9.
+
+ With the change, we also introduce new ciphersuite aliases that
+ so far were missing: "AES128", "AES256", "CAMELLIA128", and
+ "CAMELLIA256".
+ [Bodo Moeller]
+
+ *) Add support for dsa-with-SHA224 and dsa-with-SHA256.
+ Use the leftmost N bytes of the signature input if the input is
+ larger than the prime q (with N being the size in bytes of q).
+ [Nils Larsch]
+
+ *) Very *very* experimental PKCS#7 streaming encoder support. Nothing uses
+ it yet and it is largely untested.
+ [Steve Henson]
+
+ *) Add support for the ecdsa-with-SHA224/256/384/512 signature types.
+ [Nils Larsch]
+
+ *) Initial incomplete changes to avoid need for function casts in OpenSSL
+ some compilers (gcc 4.2 and later) reject their use. Safestack is
+ reimplemented. Update ASN1 to avoid use of legacy functions.
+ [Steve Henson]
+
+ *) Win32/64 targets are linked with Winsock2.
+ [Andy Polyakov]
+
+ *) Add an X509_CRL_METHOD structure to allow CRL processing to be redirected
+ to external functions. This can be used to increase CRL handling
+ efficiency especially when CRLs are very large by (for example) storing
+ the CRL revoked certificates in a database.
+ [Steve Henson]
+
+ *) Overhaul of by_dir code. Add support for dynamic loading of CRLs so
+ new CRLs added to a directory can be used. New command line option
+ -verify_return_error to s_client and s_server. This causes real errors
+ to be returned by the verify callback instead of carrying on no matter
+ what. This reflects the way a "real world" verify callback would behave.
+ [Steve Henson]
+
+ *) GOST engine, supporting several GOST algorithms and public key formats.
+ Kindly donated by Cryptocom.
+ [Cryptocom]
+
+ *) Partial support for Issuing Distribution Point CRL extension. CRLs
+ partitioned by DP are handled but no indirect CRL or reason partitioning
+ (yet). Complete overhaul of CRL handling: now the most suitable CRL is
+ selected via a scoring technique which handles IDP and AKID in CRLs.
+ [Steve Henson]
+
+ *) New X509_STORE_CTX callbacks lookup_crls() and lookup_certs() which
+ will ultimately be used for all verify operations: this will remove the
+ X509_STORE dependency on certificate verification and allow alternative
+ lookup methods. X509_STORE based implementations of these two callbacks.
+ [Steve Henson]
+
+ *) Allow multiple CRLs to exist in an X509_STORE with matching issuer names.
+ Modify get_crl() to find a valid (unexpired) CRL if possible.
+ [Steve Henson]
+
+ *) New function X509_CRL_match() to check if two CRLs are identical. Normally
+ this would be called X509_CRL_cmp() but that name is already used by
+ a function that just compares CRL issuer names. Cache several CRL
+ extensions in X509_CRL structure and cache CRLDP in X509.
+ [Steve Henson]
+
+ *) Store a "canonical" representation of X509_NAME structure (ASN1 Name)
+ this maps equivalent X509_NAME structures into a consistent structure.
+ Name comparison can then be performed rapidly using memcmp().
+ [Steve Henson]
+
+ *) Non-blocking OCSP request processing. Add -timeout option to ocsp
+ utility.
+ [Steve Henson]
+
+ *) Allow digests to supply their own micalg string for S/MIME type using
+ the ctrl EVP_MD_CTRL_MICALG.
+ [Steve Henson]
+
+ *) During PKCS7 signing pass the PKCS7 SignerInfo structure to the
+ EVP_PKEY_METHOD before and after signing via the EVP_PKEY_CTRL_PKCS7_SIGN
+ ctrl. It can then customise the structure before and/or after signing
+ if necessary.
+ [Steve Henson]
+
+ *) New function OBJ_add_sigid() to allow application defined signature OIDs
+ to be added to OpenSSLs internal tables. New function OBJ_sigid_free()
+ to free up any added signature OIDs.
+ [Steve Henson]
+
+ *) New functions EVP_CIPHER_do_all(), EVP_CIPHER_do_all_sorted(),
+ EVP_MD_do_all() and EVP_MD_do_all_sorted() to enumerate internal
+ digest and cipher tables. New options added to openssl utility:
+ list-message-digest-algorithms and list-cipher-algorithms.
+ [Steve Henson]
+
+ *) Change the array representation of binary polynomials: the list
+ of degrees of non-zero coefficients is now terminated with -1.
+ Previously it was terminated with 0, which was also part of the
+ value; thus, the array representation was not applicable to
+ polynomials where t^0 has coefficient zero. This change makes
+ the array representation useful in a more general context.
+ [Douglas Stebila]
+
+ *) Various modifications and fixes to SSL/TLS cipher string
+ handling. For ECC, the code now distinguishes between fixed ECDH
+ with RSA certificates on the one hand and with ECDSA certificates
+ on the other hand, since these are separate ciphersuites. The
+ unused code for Fortezza ciphersuites has been removed.
+
+ For consistency with EDH, ephemeral ECDH is now called "EECDH"
+ (not "ECDHE"). For consistency with the code for DH
+ certificates, use of ECDH certificates is now considered ECDH
+ authentication, not RSA or ECDSA authentication (the latter is
+ merely the CA's signing algorithm and not actively used in the
+ protocol).
+
+ The temporary ciphersuite alias "ECCdraft" is no longer
+ available, and ECC ciphersuites are no longer excluded from "ALL"
+ and "DEFAULT". The following aliases now exist for RFC 4492
+ ciphersuites, most of these by analogy with the DH case:
+
+ kECDHr - ECDH cert, signed with RSA
+ kECDHe - ECDH cert, signed with ECDSA
+ kECDH - ECDH cert (signed with either RSA or ECDSA)
+ kEECDH - ephemeral ECDH
+ ECDH - ECDH cert or ephemeral ECDH
+
+ aECDH - ECDH cert
+ aECDSA - ECDSA cert
+ ECDSA - ECDSA cert
+
+ AECDH - anonymous ECDH
+ EECDH - non-anonymous ephemeral ECDH (equivalent to "kEECDH:-AECDH")
+
+ [Bodo Moeller]
+
+ *) Add additional S/MIME capabilities for AES and GOST ciphers if supported.
+ Use correct micalg parameters depending on digest(s) in signed message.
+ [Steve Henson]
+
+ *) Add engine support for EVP_PKEY_ASN1_METHOD. Add functions to process
+ an ENGINE asn1 method. Support ENGINE lookups in the ASN1 code.
+ [Steve Henson]
+
+ *) Initial engine support for EVP_PKEY_METHOD. New functions to permit
+ an engine to register a method. Add ENGINE lookups for methods and
+ functional reference processing.
+ [Steve Henson]
+
+ *) New functions EVP_Digest{Sign,Verify)*. These are enchance versions of
+ EVP_{Sign,Verify}* which allow an application to customise the signature
+ process.
+ [Steve Henson]
+
+ *) New -resign option to smime utility. This adds one or more signers
+ to an existing PKCS#7 signedData structure. Also -md option to use an
+ alternative message digest algorithm for signing.
+ [Steve Henson]
+
+ *) Tidy up PKCS#7 routines and add new functions to make it easier to
+ create PKCS7 structures containing multiple signers. Update smime
+ application to support multiple signers.
+ [Steve Henson]
+
+ *) New -macalg option to pkcs12 utility to allow setting of an alternative
+ digest MAC.
+ [Steve Henson]
+
+ *) Initial support for PKCS#5 v2.0 PRFs other than default SHA1 HMAC.
+ Reorganize PBE internals to lookup from a static table using NIDs,
+ add support for HMAC PBE OID translation. Add a EVP_CIPHER ctrl:
+ EVP_CTRL_PBE_PRF_NID this allows a cipher to specify an alternative
+ PRF which will be automatically used with PBES2.
+ [Steve Henson]
+
+ *) Replace the algorithm specific calls to generate keys in "req" with the
+ new API.
+ [Steve Henson]
+
+ *) Update PKCS#7 enveloped data routines to use new API. This is now
+ supported by any public key method supporting the encrypt operation. A
+ ctrl is added to allow the public key algorithm to examine or modify
+ the PKCS#7 RecipientInfo structure if it needs to: for RSA this is
+ a no op.
+ [Steve Henson]
+
+ *) Add a ctrl to asn1 method to allow a public key algorithm to express
+ a default digest type to use. In most cases this will be SHA1 but some
+ algorithms (such as GOST) need to specify an alternative digest. The
+ return value indicates how strong the prefernce is 1 means optional and
+ 2 is mandatory (that is it is the only supported type). Modify
+ ASN1_item_sign() to accept a NULL digest argument to indicate it should
+ use the default md. Update openssl utilities to use the default digest
+ type for signing if it is not explicitly indicated.
+ [Steve Henson]
+
+ *) Use OID cross reference table in ASN1_sign() and ASN1_verify(). New
+ EVP_MD flag EVP_MD_FLAG_PKEY_METHOD_SIGNATURE. This uses the relevant
+ signing method from the key type. This effectively removes the link
+ between digests and public key types.
+ [Steve Henson]
+
+ *) Add an OID cross reference table and utility functions. Its purpose is to
+ translate between signature OIDs such as SHA1WithrsaEncryption and SHA1,
+ rsaEncryption. This will allow some of the algorithm specific hackery
+ needed to use the correct OID to be removed.
+ [Steve Henson]
+
+ *) Remove algorithm specific dependencies when setting PKCS7_SIGNER_INFO
+ structures for PKCS7_sign(). They are now set up by the relevant public
+ key ASN1 method.
+ [Steve Henson]
+
+ *) Add provisional EC pkey method with support for ECDSA and ECDH.
+ [Steve Henson]
+
+ *) Add support for key derivation (agreement) in the API, DH method and
+ pkeyutl.
+ [Steve Henson]
+
+ *) Add DSA pkey method and DH pkey methods, extend DH ASN1 method to support
+ public and private key formats. As a side effect these add additional
+ command line functionality not previously available: DSA signatures can be
+ generated and verified using pkeyutl and DH key support and generation in
+ pkey, genpkey.
+ [Steve Henson]
+
+ *) BeOS support.
+ [Oliver Tappe <zooey@hirschkaefer.de>]
+
+ *) New make target "install_html_docs" installs HTML renditions of the
+ manual pages.
+ [Oliver Tappe <zooey@hirschkaefer.de>]
+
+ *) New utility "genpkey" this is analagous to "genrsa" etc except it can
+ generate keys for any algorithm. Extend and update EVP_PKEY_METHOD to
+ support key and parameter generation and add initial key generation
+ functionality for RSA.
+ [Steve Henson]
+
+ *) Add functions for main EVP_PKEY_method operations. The undocumented
+ functions EVP_PKEY_{encrypt,decrypt} have been renamed to
+ EVP_PKEY_{encrypt,decrypt}_old.
+ [Steve Henson]
+
+ *) Initial definitions for EVP_PKEY_METHOD. This will be a high level public
+ key API, doesn't do much yet.
+ [Steve Henson]
+
+ *) New function EVP_PKEY_asn1_get0_info() to retrieve information about
+ public key algorithms. New option to openssl utility:
+ "list-public-key-algorithms" to print out info.
+ [Steve Henson]
+
+ *) Implement the Supported Elliptic Curves Extension for
+ ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
+ [Douglas Stebila]
+
+ *) Don't free up OIDs in OBJ_cleanup() if they are in use by EVP_MD or
+ EVP_CIPHER structures to avoid later problems in EVP_cleanup().
+ [Steve Henson]
+
+ *) New utilities pkey and pkeyparam. These are similar to algorithm specific
+ utilities such as rsa, dsa, dsaparam etc except they process any key
+ type.
+ [Steve Henson]
+
+ *) Transfer public key printing routines to EVP_PKEY_ASN1_METHOD. New
+ functions EVP_PKEY_print_public(), EVP_PKEY_print_private(),
+ EVP_PKEY_print_param() to print public key data from an EVP_PKEY
+ structure.
+ [Steve Henson]
+
+ *) Initial support for pluggable public key ASN1.
+ De-spaghettify the public key ASN1 handling. Move public and private
+ key ASN1 handling to a new EVP_PKEY_ASN1_METHOD structure. Relocate
+ algorithm specific handling to a single module within the relevant
+ algorithm directory. Add functions to allow (near) opaque processing
+ of public and private key structures.
+ [Steve Henson]
+
+ *) Implement the Supported Point Formats Extension for
+ ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
+ [Douglas Stebila]
+
+ *) Add initial support for RFC 4279 PSK TLS ciphersuites. Add members
+ for the psk identity [hint] and the psk callback functions to the
+ SSL_SESSION, SSL and SSL_CTX structure.
+
+ New ciphersuites:
+ PSK-RC4-SHA, PSK-3DES-EDE-CBC-SHA, PSK-AES128-CBC-SHA,
+ PSK-AES256-CBC-SHA
+
+ New functions:
+ SSL_CTX_use_psk_identity_hint
+ SSL_get_psk_identity_hint
+ SSL_get_psk_identity
+ SSL_use_psk_identity_hint
+
+ [Mika Kousa and Pasi Eronen of Nokia Corporation]
+
+ *) Add RFC 3161 compliant time stamp request creation, response generation
+ and response verification functionality.
+ [Zoltán Glózik <zglozik@opentsa.org>, The OpenTSA Project]
+
+ *) Add initial support for TLS extensions, specifically for the server_name
+ extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now
+ have new members for a host name. The SSL data structure has an
+ additional member SSL_CTX *initial_ctx so that new sessions can be
+ stored in that context to allow for session resumption, even after the
+ SSL has been switched to a new SSL_CTX in reaction to a client's
+ server_name extension.
+
+ New functions (subject to change):
+
+ SSL_get_servername()
+ SSL_get_servername_type()
+ SSL_set_SSL_CTX()
+
+ New CTRL codes and macros (subject to change):
+
+ SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
+ - SSL_CTX_set_tlsext_servername_callback()
+ SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
+ - SSL_CTX_set_tlsext_servername_arg()
+ SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name()
+
+ openssl s_client has a new '-servername ...' option.
+
+ openssl s_server has new options '-servername_host ...', '-cert2 ...',
+ '-key2 ...', '-servername_fatal' (subject to change). This allows
+ testing the HostName extension for a specific single host name ('-cert'
+ and '-key' remain fallbacks for handshakes without HostName
+ negotiation). If the unrecogninzed_name alert has to be sent, this by
+ default is a warning; it becomes fatal with the '-servername_fatal'
+ option.
+
+ [Peter Sylvester, Remy Allais, Christophe Renou]
+
+ *) Whirlpool hash implementation is added.
+ [Andy Polyakov]
+
+ *) BIGNUM code on 64-bit SPARCv9 targets is switched from bn(64,64) to
+ bn(64,32). Because of instruction set limitations it doesn't have
+ any negative impact on performance. This was done mostly in order
+ to make it possible to share assembler modules, such as bn_mul_mont
+ implementations, between 32- and 64-bit builds without hassle.
+ [Andy Polyakov]
+
+ *) Move code previously exiled into file crypto/ec/ec2_smpt.c
+ to ec2_smpl.c, and no longer require the OPENSSL_EC_BIN_PT_COMP
+ macro.
+ [Bodo Moeller]
+
+ *) New candidate for BIGNUM assembler implementation, bn_mul_mont,
+ dedicated Montgomery multiplication procedure, is introduced.
+ BN_MONT_CTX is modified to allow bn_mul_mont to reach for higher
+ "64-bit" performance on certain 32-bit targets.
+ [Andy Polyakov]
+
+ *) New option SSL_OP_NO_COMP to disable use of compression selectively
+ in SSL structures. New SSL ctrl to set maximum send fragment size.
+ Save memory by seeting the I/O buffer sizes dynamically instead of
+ using the maximum available value.
+ [Steve Henson]
+
+ *) New option -V for 'openssl ciphers'. This prints the ciphersuite code
+ in addition to the text details.
+ [Bodo Moeller]
+
+ *) Very, very preliminary EXPERIMENTAL support for printing of general
+ ASN1 structures. This currently produces rather ugly output and doesn't
+ handle several customised structures at all.
+ [Steve Henson]
+
+ *) Integrated support for PVK file format and some related formats such
+ as MS PUBLICKEYBLOB and PRIVATEKEYBLOB. Command line switches to support
+ these in the 'rsa' and 'dsa' utilities.
+ [Steve Henson]
+
+ *) Support for PKCS#1 RSAPublicKey format on rsa utility command line.
+ [Steve Henson]
+
+ *) Remove the ancient ASN1_METHOD code. This was only ever used in one
+ place for the (very old) "NETSCAPE" format certificates which are now
+ handled using new ASN1 code equivalents.
+ [Steve Henson]
+
+ *) Let the TLSv1_method() etc. functions return a 'const' SSL_METHOD
+ pointer and make the SSL_METHOD parameter in SSL_CTX_new,
+ SSL_CTX_set_ssl_version and SSL_set_ssl_method 'const'.
+ [Nils Larsch]
+
+ *) Modify CRL distribution points extension code to print out previously
+ unsupported fields. Enhance extension setting code to allow setting of
+ all fields.
+ [Steve Henson]
+
+ *) Add print and set support for Issuing Distribution Point CRL extension.
+ [Steve Henson]
+
+ *) Change 'Configure' script to enable Camellia by default.
+ [NTT]
+
+ Changes between 0.9.8q and 0.9.8r [8 Feb 2011]
+
+ *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014
+ [Neel Mehta, Adam Langley, Bodo Moeller (Google)]
+
+ *) Fix bug in string printing code: if *any* escaping is enabled we must
+ escape the escape character (backslash) or the resulting string is
+ ambiguous.
+ [Steve Henson]
+
+ Changes between 0.9.8p and 0.9.8q [2 Dec 2010]
+
+ *) Disable code workaround for ancient and obsolete Netscape browsers
+ and servers: an attacker can use it in a ciphersuite downgrade attack.
+ Thanks to Martin Rex for discovering this bug. CVE-2010-4180
+ [Steve Henson]
+
+ *) Fixed J-PAKE implementation error, originally discovered by
+ Sebastien Martini, further info and confirmation from Stefan
+ Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252
+ [Ben Laurie]
+
+ Changes between 0.9.8o and 0.9.8p [16 Nov 2010]
+
+ *) Fix extension code to avoid race conditions which can result in a buffer
+ overrun vulnerability: resumed sessions must not be modified as they can
+ be shared by multiple threads. CVE-2010-3864
+ [Steve Henson]
+
+ *) Fix for double free bug in ssl/s3_clnt.c CVE-2010-2939
+ [Steve Henson]
+
+ *) Don't reencode certificate when calculating signature: cache and use
+ the original encoding instead. This makes signature verification of
+ some broken encodings work correctly.
+ [Steve Henson]
+
+ *) ec2_GF2m_simple_mul bugfix: compute correct result if the output EC_POINT
+ is also one of the inputs.
+ [Emilia Käsper <emilia.kasper@esat.kuleuven.be> (Google)]
+
+ *) Don't repeatedly append PBE algorithms to table if they already exist.
+ Sort table on each new add. This effectively makes the table read only
+ after all algorithms are added and subsequent calls to PKCS12_pbe_add
+ etc are non-op.
+ [Steve Henson]
+
+ Changes between 0.9.8n and 0.9.8o [01 Jun 2010]
+
+ [NB: OpenSSL 0.9.8o and later 0.9.8 patch levels were released after
+ OpenSSL 1.0.0.]
+
+ *) Correct a typo in the CMS ASN1 module which can result in invalid memory
+ access or freeing data twice (CVE-2010-0742)
+ [Steve Henson, Ronald Moesbergen <intercommit@gmail.com>]
+
+ *) Add SHA2 algorithms to SSL_library_init(). SHA2 is becoming far more
+ common in certificates and some applications which only call
+ SSL_library_init and not OpenSSL_add_all_algorithms() will fail.
+ [Steve Henson]
+
+ *) VMS fixes:
+ Reduce copying into .apps and .test in makevms.com
+ Don't try to use blank CA certificate in CA.com
+ Allow use of C files from original directories in maketests.com
+ [Steven M. Schweda" <sms@antinode.info>]
+
+ Changes between 0.9.8m and 0.9.8n [24 Mar 2010]
+
+ *) When rejecting SSL/TLS records due to an incorrect version number, never
+ update s->server with a new major version number. As of
+ - OpenSSL 0.9.8m if 'short' is a 16-bit type,
+ - OpenSSL 0.9.8f if 'short' is longer than 16 bits,
+ the previous behavior could result in a read attempt at NULL when
+ receiving specific incorrect SSL/TLS records once record payload
+ protection is active. (CVE-2010-0740)
+ [Bodo Moeller, Adam Langley <agl@chromium.org>]
+
+ *) Fix for CVE-2010-0433 where some kerberos enabled versions of OpenSSL
+ could be crashed if the relevant tables were not present (e.g. chrooted).
+ [Tomas Hoger <thoger@redhat.com>]
+
+ Changes between 0.9.8l and 0.9.8m [25 Feb 2010]
+
+ *) Always check bn_wexpend() return values for failure. (CVE-2009-3245)
+ [Martin Olsson, Neel Mehta]
+
+ *) Fix X509_STORE locking: Every 'objs' access requires a lock (to
+ accommodate for stack sorting, always a write lock!).
+ [Bodo Moeller]
+
+ *) On some versions of WIN32 Heap32Next is very slow. This can cause
+ excessive delays in the RAND_poll(): over a minute. As a workaround
+ include a time check in the inner Heap32Next loop too.
+ [Steve Henson]
+
+ *) The code that handled flushing of data in SSL/TLS originally used the
+ BIO_CTRL_INFO ctrl to see if any data was pending first. This caused
+ the problem outlined in PR#1949. The fix suggested there however can
+ trigger problems with buggy BIO_CTRL_WPENDING (e.g. some versions
+ of Apache). So instead simplify the code to flush unconditionally.
+ This should be fine since flushing with no data to flush is a no op.
+ [Steve Henson]
+
+ *) Handle TLS versions 2.0 and later properly and correctly use the
+ highest version of TLS/SSL supported. Although TLS >= 2.0 is some way
+ off ancient servers have a habit of sticking around for a while...
+ [Steve Henson]
+
+ *) Modify compression code so it frees up structures without using the
+ ex_data callbacks. This works around a problem where some applications
+ call CRYPTO_cleanup_all_ex_data() before application exit (e.g. when
+ restarting) then use compression (e.g. SSL with compression) later.
+ This results in significant per-connection memory leaks and
+ has caused some security issues including CVE-2008-1678 and
+ CVE-2009-4355.
+ [Steve Henson]
+
+ *) Constify crypto/cast (i.e., <openssl/cast.h>): a CAST_KEY doesn't
+ change when encrypting or decrypting.
+ [Bodo Moeller]
+
+ *) Add option SSL_OP_LEGACY_SERVER_CONNECT which will allow clients to
+ connect and renegotiate with servers which do not support RI.
+ Until RI is more widely deployed this option is enabled by default.
+ [Steve Henson]
+
+ *) Add "missing" ssl ctrls to clear options and mode.
+ [Steve Henson]
+
+ *) If client attempts to renegotiate and doesn't support RI respond with
+ a no_renegotiation alert as required by RFC5746. Some renegotiating
+ TLS clients will continue a connection gracefully when they receive
+ the alert. Unfortunately OpenSSL mishandled this alert and would hang
+ waiting for a server hello which it will never receive. Now we treat a
+ received no_renegotiation alert as a fatal error. This is because
+ applications requesting a renegotiation might well expect it to succeed
+ and would have no code in place to handle the server denying it so the
+ only safe thing to do is to terminate the connection.
+ [Steve Henson]
+
+ *) Add ctrl macro SSL_get_secure_renegotiation_support() which returns 1 if
+ peer supports secure renegotiation and 0 otherwise. Print out peer
+ renegotiation support in s_client/s_server.
+ [Steve Henson]
+
+ *) Replace the highly broken and deprecated SPKAC certification method with
+ the updated NID creation version. This should correctly handle UTF8.
+ [Steve Henson]
+
+ *) Implement RFC5746. Re-enable renegotiation but require the extension
+ as needed. Unfortunately, SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
+ turns out to be a bad idea. It has been replaced by
+ SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with
+ SSL_CTX_set_options(). This is really not recommended unless you
+ know what you are doing.
+ [Eric Rescorla <ekr@networkresonance.com>, Ben Laurie, Steve Henson]
+
+ *) Fixes to stateless session resumption handling. Use initial_ctx when
+ issuing and attempting to decrypt tickets in case it has changed during
+ servername handling. Use a non-zero length session ID when attempting
+ stateless session resumption: this makes it possible to determine if
+ a resumption has occurred immediately after receiving server hello
+ (several places in OpenSSL subtly assume this) instead of later in
+ the handshake.
+ [Steve Henson]
+
+ *) The functions ENGINE_ctrl(), OPENSSL_isservice(),
+ CMS_get1_RecipientRequest() and RAND_bytes() can return <=0 on error
+ fixes for a few places where the return code is not checked
+ correctly.
+ [Julia Lawall <julia@diku.dk>]
+
+ *) Add --strict-warnings option to Configure script to include devteam
+ warnings in other configurations.
+ [Steve Henson]
+
+ *) Add support for --libdir option and LIBDIR variable in makefiles. This
+ makes it possible to install openssl libraries in locations which
+ have names other than "lib", for example "/usr/lib64" which some
+ systems need.
+ [Steve Henson, based on patch from Jeremy Utley]
+
+ *) Don't allow the use of leading 0x80 in OIDs. This is a violation of
+ X690 8.9.12 and can produce some misleading textual output of OIDs.
+ [Steve Henson, reported by Dan Kaminsky]
+
+ *) Delete MD2 from algorithm tables. This follows the recommendation in
+ several standards that it is not used in new applications due to
+ several cryptographic weaknesses. For binary compatibility reasons
+ the MD2 API is still compiled in by default.
+ [Steve Henson]
+
+ *) Add compression id to {d2i,i2d}_SSL_SESSION so it is correctly saved
+ and restored.
+ [Steve Henson]
+
+ *) Rename uni2asc and asc2uni functions to OPENSSL_uni2asc and
+ OPENSSL_asc2uni conditionally on Netware platforms to avoid a name
+ clash.
+ [Guenter <lists@gknw.net>]
+
+ *) Fix the server certificate chain building code to use X509_verify_cert(),
+ it used to have an ad-hoc builder which was unable to cope with anything
+ other than a simple chain.
+ [David Woodhouse <dwmw2@infradead.org>, Steve Henson]
+
+ *) Don't check self signed certificate signatures in X509_verify_cert()
+ by default (a flag can override this): it just wastes time without
+ adding any security. As a useful side effect self signed root CAs
+ with non-FIPS digests are now usable in FIPS mode.
+ [Steve Henson]
+
+ *) In dtls1_process_out_of_seq_message() the check if the current message
+ is already buffered was missing. For every new message was memory
+ allocated, allowing an attacker to perform an denial of service attack
+ with sending out of seq handshake messages until there is no memory
+ left. Additionally every future messege was buffered, even if the
+ sequence number made no sense and would be part of another handshake.
+ So only messages with sequence numbers less than 10 in advance will be
+ buffered. (CVE-2009-1378)
+ [Robin Seggelmann, discovered by Daniel Mentz]
+
+ *) Records are buffered if they arrive with a future epoch to be
+ processed after finishing the corresponding handshake. There is
+ currently no limitation to this buffer allowing an attacker to perform
+ a DOS attack with sending records with future epochs until there is no
+ memory left. This patch adds the pqueue_size() function to detemine
+ the size of a buffer and limits the record buffer to 100 entries.
+ (CVE-2009-1377)
+ [Robin Seggelmann, discovered by Daniel Mentz]
+
+ *) Keep a copy of frag->msg_header.frag_len so it can be used after the
+ parent structure is freed. (CVE-2009-1379)
+ [Daniel Mentz]
+
+ *) Handle non-blocking I/O properly in SSL_shutdown() call.
+ [Darryl Miles <darryl-mailinglists@netbauds.net>]
+
+ *) Add 2.5.4.* OIDs
+ [Ilya O. <vrghost@gmail.com>]
+
+ Changes between 0.9.8k and 0.9.8l [5 Nov 2009]
+
+ *) Disable renegotiation completely - this fixes a severe security
+ problem (CVE-2009-3555) at the cost of breaking all
+ renegotiation. Renegotiation can be re-enabled by setting
+ SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION in s3->flags at
+ run-time. This is really not recommended unless you know what
+ you're doing.
+ [Ben Laurie]
+
+ Changes between 0.9.8j and 0.9.8k [25 Mar 2009]
+
+ *) Don't set val to NULL when freeing up structures, it is freed up by
+ underlying code. If sizeof(void *) > sizeof(long) this can result in
+ zeroing past the valid field. (CVE-2009-0789)
+ [Paolo Ganci <Paolo.Ganci@AdNovum.CH>]
+
+ *) Fix bug where return value of CMS_SignerInfo_verify_content() was not
+ checked correctly. This would allow some invalid signed attributes to
+ appear to verify correctly. (CVE-2009-0591)
+ [Ivan Nestlerode <inestlerode@us.ibm.com>]
+
+ *) Reject UniversalString and BMPString types with invalid lengths. This
+ prevents a crash in ASN1_STRING_print_ex() which assumes the strings have
+ a legal length. (CVE-2009-0590)
+ [Steve Henson]
+
+ *) Set S/MIME signing as the default purpose rather than setting it
+ unconditionally. This allows applications to override it at the store
+ level.
+ [Steve Henson]
+
+ *) Permit restricted recursion of ASN1 strings. This is needed in practice
+ to handle some structures.
+ [Steve Henson]
+
+ *) Improve efficiency of mem_gets: don't search whole buffer each time
+ for a '\n'
+ [Jeremy Shapiro <jnshapir@us.ibm.com>]
+
+ *) New -hex option for openssl rand.
+ [Matthieu Herrb]
+
+ *) Print out UTF8String and NumericString when parsing ASN1.
+ [Steve Henson]
+
+ *) Support NumericString type for name components.
+ [Steve Henson]
+
+ *) Allow CC in the environment to override the automatically chosen
+ compiler. Note that nothing is done to ensure flags work with the
+ chosen compiler.
+ [Ben Laurie]
+
+ Changes between 0.9.8i and 0.9.8j [07 Jan 2009]
+
+ *) Properly check EVP_VerifyFinal() and similar return values
+ (CVE-2008-5077).
+ [Ben Laurie, Bodo Moeller, Google Security Team]
+
+ *) Enable TLS extensions by default.
+ [Ben Laurie]
+
+ *) Allow the CHIL engine to be loaded, whether the application is
+ multithreaded or not. (This does not release the developer from the
+ obligation to set up the dynamic locking callbacks.)
+ [Sander Temme <sander@temme.net>]
+
+ *) Use correct exit code if there is an error in dgst command.
+ [Steve Henson; problem pointed out by Roland Dirlewanger]
+
+ *) Tweak Configure so that you need to say "experimental-jpake" to enable
+ JPAKE, and need to use -DOPENSSL_EXPERIMENTAL_JPAKE in applications.
+ [Bodo Moeller]
+
+ *) Add experimental JPAKE support, including demo authentication in
+ s_client and s_server.
+ [Ben Laurie]
+
+ *) Set the comparison function in v3_addr_canonize().
+ [Rob Austein <sra@hactrn.net>]
+
+ *) Add support for XMPP STARTTLS in s_client.
+ [Philip Paeps <philip@freebsd.org>]
+
+ *) Change the server-side SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG behavior
+ to ensure that even with this option, only ciphersuites in the
+ server's preference list will be accepted. (Note that the option
+ applies only when resuming a session, so the earlier behavior was
+ just about the algorithm choice for symmetric cryptography.)
+ [Bodo Moeller]
+
+ Changes between 0.9.8h and 0.9.8i [15 Sep 2008]
+
+ *) Fix NULL pointer dereference if a DTLS server received
+ ChangeCipherSpec as first record (CVE-2009-1386).
+ [PR #1679]
+
+ *) Fix a state transitition in s3_srvr.c and d1_srvr.c
+ (was using SSL3_ST_CW_CLNT_HELLO_B, should be ..._ST_SW_SRVR_...).
+ [Nagendra Modadugu]
+
+ *) The fix in 0.9.8c that supposedly got rid of unsafe
+ double-checked locking was incomplete for RSA blinding,
+ addressing just one layer of what turns out to have been
+ doubly unsafe triple-checked locking.
+
+ So now fix this for real by retiring the MONT_HELPER macro
+ in crypto/rsa/rsa_eay.c.
+
+ [Bodo Moeller; problem pointed out by Marius Schilder]
+
+ *) Various precautionary measures:
+
+ - Avoid size_t integer overflow in HASH_UPDATE (md32_common.h).
+
+ - Avoid a buffer overflow in d2i_SSL_SESSION() (ssl_asn1.c).
+ (NB: This would require knowledge of the secret session ticket key
+ to exploit, in which case you'd be SOL either way.)
+
+ - Change bn_nist.c so that it will properly handle input BIGNUMs
+ outside the expected range.
+
+ - Enforce the 'num' check in BN_div() (bn_div.c) for non-BN_DEBUG
+ builds.
+
+ [Neel Mehta, Bodo Moeller]
+
+ *) Allow engines to be "soft loaded" - i.e. optionally don't die if
+ the load fails. Useful for distros.
+ [Ben Laurie and the FreeBSD team]
+
+ *) Add support for Local Machine Keyset attribute in PKCS#12 files.
+ [Steve Henson]
+
+ *) Fix BN_GF2m_mod_arr() top-bit cleanup code.
+ [Huang Ying]
+
+ *) Expand ENGINE to support engine supplied SSL client certificate functions.
+
+ This work was sponsored by Logica.
+ [Steve Henson]
+
+ *) Add CryptoAPI ENGINE to support use of RSA and DSA keys held in Windows
+ keystores. Support for SSL/TLS client authentication too.
+ Not compiled unless enable-capieng specified to Configure.
+
+ This work was sponsored by Logica.
+ [Steve Henson]
+
+ *) Fix bug in X509_ATTRIBUTE creation: dont set attribute using
+ ASN1_TYPE_set1 if MBSTRING flag set. This bug would crash certain
+ attribute creation routines such as certifcate requests and PKCS#12
+ files.
+ [Steve Henson]
+
+ Changes between 0.9.8g and 0.9.8h [28 May 2008]
+
+ *) Fix flaw if 'Server Key exchange message' is omitted from a TLS
+ handshake which could lead to a cilent crash as found using the
+ Codenomicon TLS test suite (CVE-2008-1672)
+ [Steve Henson, Mark Cox]
+
+ *) Fix double free in TLS server name extensions which could lead to
+ a remote crash found by Codenomicon TLS test suite (CVE-2008-0891)
+ [Joe Orton]
+
+ *) Clear error queue in SSL_CTX_use_certificate_chain_file()
+
+ Clear the error queue to ensure that error entries left from
+ older function calls do not interfere with the correct operation.
+ [Lutz Jaenicke, Erik de Castro Lopo]
+
+ *) Remove root CA certificates of commercial CAs:
+
+ The OpenSSL project does not recommend any specific CA and does not
+ have any policy with respect to including or excluding any CA.
+ Therefore it does not make any sense to ship an arbitrary selection
+ of root CA certificates with the OpenSSL software.
+ [Lutz Jaenicke]
+
+ *) RSA OAEP patches to fix two separate invalid memory reads.
+ The first one involves inputs when 'lzero' is greater than
+ 'SHA_DIGEST_LENGTH' (it would read about SHA_DIGEST_LENGTH bytes
+ before the beginning of from). The second one involves inputs where
+ the 'db' section contains nothing but zeroes (there is a one-byte
+ invalid read after the end of 'db').
+ [Ivan Nestlerode <inestlerode@us.ibm.com>]
+
+ *) Partial backport from 0.9.9-dev:
+
+ Introduce bn_mul_mont (dedicated Montgomery multiplication
+ procedure) as a candidate for BIGNUM assembler implementation.
+ While 0.9.9-dev uses assembler for various architectures, only
+ x86_64 is available by default here in the 0.9.8 branch, and
+ 32-bit x86 is available through a compile-time setting.
+
+ To try the 32-bit x86 assembler implementation, use Configure
+ option "enable-montasm" (which exists only for this backport).
+
+ As "enable-montasm" for 32-bit x86 disclaims code stability
+ anyway, in this constellation we activate additional code
+ backported from 0.9.9-dev for further performance improvements,
+ namely BN_from_montgomery_word. (To enable this otherwise,
+ e.g. x86_64, try "-DMONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD".)
+
+ [Andy Polyakov (backport partially by Bodo Moeller)]
+
+ *) Add TLS session ticket callback. This allows an application to set
+ TLS ticket cipher and HMAC keys rather than relying on hardcoded fixed
+ values. This is useful for key rollover for example where several key
+ sets may exist with different names.
+ [Steve Henson]
+
+ *) Reverse ENGINE-internal logic for caching default ENGINE handles.
+ This was broken until now in 0.9.8 releases, such that the only way
+ a registered ENGINE could be used (assuming it initialises
+ successfully on the host) was to explicitly set it as the default
+ for the relevant algorithms. This is in contradiction with 0.9.7
+ behaviour and the documentation. With this fix, when an ENGINE is
+ registered into a given algorithm's table of implementations, the
+ 'uptodate' flag is reset so that auto-discovery will be used next
+ time a new context for that algorithm attempts to select an
+ implementation.
+ [Ian Lister (tweaked by Geoff Thorpe)]
+
+ *) Backport of CMS code to OpenSSL 0.9.8. This differs from the 0.9.9
+ implemention in the following ways:
+
+ Lack of EVP_PKEY_ASN1_METHOD means algorithm parameters have to be
+ hard coded.
+
+ Lack of BER streaming support means one pass streaming processing is
+ only supported if data is detached: setting the streaming flag is
+ ignored for embedded content.
+
+ CMS support is disabled by default and must be explicitly enabled
+ with the enable-cms configuration option.
+ [Steve Henson]
+
+ *) Update the GMP engine glue to do direct copies between BIGNUM and
+ mpz_t when openssl and GMP use the same limb size. Otherwise the
+ existing "conversion via a text string export" trick is still used.
+ [Paul Sheer <paulsheer@gmail.com>]
+
+ *) Zlib compression BIO. This is a filter BIO which compressed and
+ uncompresses any data passed through it.
+ [Steve Henson]
+
+ *) Add AES_wrap_key() and AES_unwrap_key() functions to implement
+ RFC3394 compatible AES key wrapping.
+ [Steve Henson]
+
+ *) Add utility functions to handle ASN1 structures. ASN1_STRING_set0():
+ sets string data without copying. X509_ALGOR_set0() and
+ X509_ALGOR_get0(): set and retrieve X509_ALGOR (AlgorithmIdentifier)
+ data. Attribute function X509at_get0_data_by_OBJ(): retrieves data
+ from an X509_ATTRIBUTE structure optionally checking it occurs only
+ once. ASN1_TYPE_set1(): set and ASN1_TYPE structure copying supplied
+ data.
+ [Steve Henson]
+
+ *) Fix BN flag handling in RSA_eay_mod_exp() and BN_MONT_CTX_set()
+ to get the expected BN_FLG_CONSTTIME behavior.
+ [Bodo Moeller (Google)]
+
+ *) Netware support:
+
+ - fixed wrong usage of ioctlsocket() when build for LIBC BSD sockets
+ - fixed do_tests.pl to run the test suite with CLIB builds too (CLIB_OPT)
+ - added some more tests to do_tests.pl
+ - fixed RunningProcess usage so that it works with newer LIBC NDKs too
+ - removed usage of BN_LLONG for CLIB builds to avoid runtime dependency
+ - added new Configure targets netware-clib-bsdsock, netware-clib-gcc,
+ netware-clib-bsdsock-gcc, netware-libc-bsdsock-gcc
+ - various changes to netware.pl to enable gcc-cross builds on Win32
+ platform
+ - changed crypto/bio/b_sock.c to work with macro functions (CLIB BSD)
+ - various changes to fix missing prototype warnings
+ - fixed x86nasm.pl to create correct asm files for NASM COFF output
+ - added AES, WHIRLPOOL and CPUID assembler code to build files
+ - added missing AES assembler make rules to mk1mf.pl
+ - fixed order of includes in apps/ocsp.c so that e_os.h settings apply
+ [Guenter Knauf <eflash@gmx.net>]
+
+ *) Implement certificate status request TLS extension defined in RFC3546.
+ A client can set the appropriate parameters and receive the encoded
+ OCSP response via a callback. A server can query the supplied parameters
+ and set the encoded OCSP response in the callback. Add simplified examples
+ to s_client and s_server.
+ [Steve Henson]
+
+ Changes between 0.9.8f and 0.9.8g [19 Oct 2007]
+
+ *) Fix various bugs:
+ + Binary incompatibility of ssl_ctx_st structure
+ + DTLS interoperation with non-compliant servers
+ + Don't call get_session_cb() without proposed session
+ + Fix ia64 assembler code
+ [Andy Polyakov, Steve Henson]
+
+ Changes between 0.9.8e and 0.9.8f [11 Oct 2007]
+
+ *) DTLS Handshake overhaul. There were longstanding issues with
+ OpenSSL DTLS implementation, which were making it impossible for
+ RFC 4347 compliant client to communicate with OpenSSL server.
+ Unfortunately just fixing these incompatibilities would "cut off"
+ pre-0.9.8f clients. To allow for hassle free upgrade post-0.9.8e
+ server keeps tolerating non RFC compliant syntax. The opposite is
+ not true, 0.9.8f client can not communicate with earlier server.
+ This update even addresses CVE-2007-4995.
+ [Andy Polyakov]
+
+ *) Changes to avoid need for function casts in OpenSSL: some compilers
+ (gcc 4.2 and later) reject their use.
+ [Kurt Roeckx <kurt@roeckx.be>, Peter Hartley <pdh@utter.chaos.org.uk>,
+ Steve Henson]
+
+ *) Add RFC4507 support to OpenSSL. This includes the corrections in
+ RFC4507bis. The encrypted ticket format is an encrypted encoded
+ SSL_SESSION structure, that way new session features are automatically
+ supported.
+
+ If a client application caches session in an SSL_SESSION structure
+ support is transparent because tickets are now stored in the encoded
+ SSL_SESSION.
+
+ The SSL_CTX structure automatically generates keys for ticket
+ protection in servers so again support should be possible
+ with no application modification.
+
+ If a client or server wishes to disable RFC4507 support then the option
+ SSL_OP_NO_TICKET can be set.
+
+ Add a TLS extension debugging callback to allow the contents of any client
+ or server extensions to be examined.
+
+ This work was sponsored by Google.
+ [Steve Henson]
+
+ *) Add initial support for TLS extensions, specifically for the server_name
+ extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now
+ have new members for a host name. The SSL data structure has an
+ additional member SSL_CTX *initial_ctx so that new sessions can be
+ stored in that context to allow for session resumption, even after the
+ SSL has been switched to a new SSL_CTX in reaction to a client's
+ server_name extension.
+
+ New functions (subject to change):
+
+ SSL_get_servername()
+ SSL_get_servername_type()
+ SSL_set_SSL_CTX()
+
+ New CTRL codes and macros (subject to change):
+
+ SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
+ - SSL_CTX_set_tlsext_servername_callback()
+ SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
+ - SSL_CTX_set_tlsext_servername_arg()
+ SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name()
+
+ openssl s_client has a new '-servername ...' option.
+
+ openssl s_server has new options '-servername_host ...', '-cert2 ...',
+ '-key2 ...', '-servername_fatal' (subject to change). This allows
+ testing the HostName extension for a specific single host name ('-cert'
+ and '-key' remain fallbacks for handshakes without HostName
+ negotiation). If the unrecogninzed_name alert has to be sent, this by
+ default is a warning; it becomes fatal with the '-servername_fatal'
+ option.
+
+ [Peter Sylvester, Remy Allais, Christophe Renou, Steve Henson]
+
+ *) Add AES and SSE2 assembly language support to VC++ build.
+ [Steve Henson]
+
+ *) Mitigate attack on final subtraction in Montgomery reduction.
+ [Andy Polyakov]
+
+ *) Fix crypto/ec/ec_mult.c to work properly with scalars of value 0
+ (which previously caused an internal error).
+ [Bodo Moeller]
+
+ *) Squeeze another 10% out of IGE mode when in != out.
+ [Ben Laurie]
+
+ *) AES IGE mode speedup.
+ [Dean Gaudet (Google)]
+
+ *) Add the Korean symmetric 128-bit cipher SEED (see
+ http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp) and
+ add SEED ciphersuites from RFC 4162:
+
+ TLS_RSA_WITH_SEED_CBC_SHA = "SEED-SHA"
+ TLS_DHE_DSS_WITH_SEED_CBC_SHA = "DHE-DSS-SEED-SHA"
+ TLS_DHE_RSA_WITH_SEED_CBC_SHA = "DHE-RSA-SEED-SHA"
+ TLS_DH_anon_WITH_SEED_CBC_SHA = "ADH-SEED-SHA"
+
+ To minimize changes between patchlevels in the OpenSSL 0.9.8
+ series, SEED remains excluded from compilation unless OpenSSL
+ is configured with 'enable-seed'.
+ [KISA, Bodo Moeller]
+
+ *) Mitigate branch prediction attacks, which can be practical if a
+ single processor is shared, allowing a spy process to extract
+ information. For detailed background information, see
+ http://eprint.iacr.org/2007/039 (O. Aciicmez, S. Gueron,
+ J.-P. Seifert, "New Branch Prediction Vulnerabilities in OpenSSL
+ and Necessary Software Countermeasures"). The core of the change
+ are new versions BN_div_no_branch() and
+ BN_mod_inverse_no_branch() of BN_div() and BN_mod_inverse(),
+ respectively, which are slower, but avoid the security-relevant
+ conditional branches. These are automatically called by BN_div()
+ and BN_mod_inverse() if the flag BN_FLG_CONSTTIME is set for one
+ of the input BIGNUMs. Also, BN_is_bit_set() has been changed to
+ remove a conditional branch.
+
+ BN_FLG_CONSTTIME is the new name for the previous
+ BN_FLG_EXP_CONSTTIME flag, since it now affects more than just
+ modular exponentiation. (Since OpenSSL 0.9.7h, setting this flag
+ in the exponent causes BN_mod_exp_mont() to use the alternative
+ implementation in BN_mod_exp_mont_consttime().) The old name
+ remains as a deprecated alias.
+
+ Similary, RSA_FLAG_NO_EXP_CONSTTIME is replaced by a more general
+ RSA_FLAG_NO_CONSTTIME flag since the RSA implementation now uses
+ constant-time implementations for more than just exponentiation.
+ Here too the old name is kept as a deprecated alias.
+
+ BN_BLINDING_new() will now use BN_dup() for the modulus so that
+ the BN_BLINDING structure gets an independent copy of the
+ modulus. This means that the previous "BIGNUM *m" argument to
+ BN_BLINDING_new() and to BN_BLINDING_create_param() now
+ essentially becomes "const BIGNUM *m", although we can't actually
+ change this in the header file before 0.9.9. It allows
+ RSA_setup_blinding() to use BN_with_flags() on the modulus to
+ enable BN_FLG_CONSTTIME.
+
+ [Matthew D Wood (Intel Corp)]
+
+ *) In the SSL/TLS server implementation, be strict about session ID
+ context matching (which matters if an application uses a single
+ external cache for different purposes). Previously,
+ out-of-context reuse was forbidden only if SSL_VERIFY_PEER was
+ set. This did ensure strict client verification, but meant that,
+ with applications using a single external cache for quite
+ different requirements, clients could circumvent ciphersuite
+ restrictions for a given session ID context by starting a session
+ in a different context.
+ [Bodo Moeller]
+
+ *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
+ a ciphersuite string such as "DEFAULT:RSA" cannot enable
+ authentication-only ciphersuites.
+ [Bodo Moeller]
+
+ *) Update the SSL_get_shared_ciphers() fix CVE-2006-3738 which was
+ not complete and could lead to a possible single byte overflow
+ (CVE-2007-5135) [Ben Laurie]
+
+ Changes between 0.9.8d and 0.9.8e [23 Feb 2007]
+
+ *) Since AES128 and AES256 (and similarly Camellia128 and
+ Camellia256) share a single mask bit in the logic of
+ ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
+ kludge to work properly if AES128 is available and AES256 isn't
+ (or if Camellia128 is available and Camellia256 isn't).
+ [Victor Duchovni]
+
+ *) Fix the BIT STRING encoding generated by crypto/ec/ec_asn1.c
+ (within i2d_ECPrivateKey, i2d_ECPKParameters, i2d_ECParameters):
+ When a point or a seed is encoded in a BIT STRING, we need to
+ prevent the removal of trailing zero bits to get the proper DER
+ encoding. (By default, crypto/asn1/a_bitstr.c assumes the case
+ of a NamedBitList, for which trailing 0 bits need to be removed.)
+ [Bodo Moeller]
+
+ *) Have SSL/TLS server implementation tolerate "mismatched" record
+ protocol version while receiving ClientHello even if the
+ ClientHello is fragmented. (The server can't insist on the
+ particular protocol version it has chosen before the ServerHello
+ message has informed the client about his choice.)
+ [Bodo Moeller]
+
+ *) Add RFC 3779 support.
+ [Rob Austein for ARIN, Ben Laurie]
+
+ *) Load error codes if they are not already present instead of using a
+ static variable. This allows them to be cleanly unloaded and reloaded.
+ Improve header file function name parsing.
+ [Steve Henson]
+
+ *) extend SMTP and IMAP protocol emulation in s_client to use EHLO
+ or CAPABILITY handshake as required by RFCs.
+ [Goetz Babin-Ebell]
+
+ Changes between 0.9.8c and 0.9.8d [28 Sep 2006]
+
+ *) Introduce limits to prevent malicious keys being able to
+ cause a denial of service. (CVE-2006-2940)
+ [Steve Henson, Bodo Moeller]
+
+ *) Fix ASN.1 parsing of certain invalid structures that can result
+ in a denial of service. (CVE-2006-2937) [Steve Henson]
+
+ *) Fix buffer overflow in SSL_get_shared_ciphers() function.
+ (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team]
+
+ *) Fix SSL client code which could crash if connecting to a
+ malicious SSLv2 server. (CVE-2006-4343)
+ [Tavis Ormandy and Will Drewry, Google Security Team]
+
+ *) Since 0.9.8b, ciphersuite strings naming explicit ciphersuites
+ match only those. Before that, "AES256-SHA" would be interpreted
+ as a pattern and match "AES128-SHA" too (since AES128-SHA got
+ the same strength classification in 0.9.7h) as we currently only
+ have a single AES bit in the ciphersuite description bitmap.
+ That change, however, also applied to ciphersuite strings such as
+ "RC4-MD5" that intentionally matched multiple ciphersuites --
+ namely, SSL 2.0 ciphersuites in addition to the more common ones
+ from SSL 3.0/TLS 1.0.
+
+ So we change the selection algorithm again: Naming an explicit
+ ciphersuite selects this one ciphersuite, and any other similar
+ ciphersuite (same bitmap) from *other* protocol versions.
+ Thus, "RC4-MD5" again will properly select both the SSL 2.0
+ ciphersuite and the SSL 3.0/TLS 1.0 ciphersuite.
+
+ Since SSL 2.0 does not have any ciphersuites for which the
+ 128/256 bit distinction would be relevant, this works for now.
+ The proper fix will be to use different bits for AES128 and
+ AES256, which would have avoided the problems from the beginning;
+ however, bits are scarce, so we can only do this in a new release
+ (not just a patchlevel) when we can change the SSL_CIPHER
+ definition to split the single 'unsigned long mask' bitmap into
+ multiple values to extend the available space.
+
+ [Bodo Moeller]
+
+ Changes between 0.9.8b and 0.9.8c [05 Sep 2006]
+
+ *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher
+ (CVE-2006-4339) [Ben Laurie and Google Security Team]
+
+ *) Add AES IGE and biIGE modes.
+ [Ben Laurie]
+
+ *) Change the Unix randomness entropy gathering to use poll() when
+ possible instead of select(), since the latter has some
+ undesirable limitations.
+ [Darryl Miles via Richard Levitte and Bodo Moeller]
+
+ *) Disable "ECCdraft" ciphersuites more thoroughly. Now special
+ treatment in ssl/ssl_ciph.s makes sure that these ciphersuites
+ cannot be implicitly activated as part of, e.g., the "AES" alias.
+ However, please upgrade to OpenSSL 0.9.9[-dev] for
+ non-experimental use of the ECC ciphersuites to get TLS extension
+ support, which is required for curve and point format negotiation
+ to avoid potential handshake problems.
+ [Bodo Moeller]
+
+ *) Disable rogue ciphersuites:
+
+ - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5")
+ - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5")
+ - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5")
+
+ The latter two were purportedly from
+ draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really
+ appear there.
+
+ Also deactivate the remaining ciphersuites from
+ draft-ietf-tls-56-bit-ciphersuites-01.txt. These are just as
+ unofficial, and the ID has long expired.
+ [Bodo Moeller]
+
+ *) Fix RSA blinding Heisenbug (problems sometimes occured on
+ dual-core machines) and other potential thread-safety issues.
+ [Bodo Moeller]
+
+ *) Add the symmetric cipher Camellia (128-bit, 192-bit, 256-bit key
+ versions), which is now available for royalty-free use
+ (see http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html).
+ Also, add Camellia TLS ciphersuites from RFC 4132.
+
+ To minimize changes between patchlevels in the OpenSSL 0.9.8
+ series, Camellia remains excluded from compilation unless OpenSSL
+ is configured with 'enable-camellia'.
+ [NTT]
+
+ *) Disable the padding bug check when compression is in use. The padding
+ bug check assumes the first packet is of even length, this is not
+ necessarily true if compresssion is enabled and can result in false
+ positives causing handshake failure. The actual bug test is ancient
+ code so it is hoped that implementations will either have fixed it by
+ now or any which still have the bug do not support compression.
+ [Steve Henson]
+
+ Changes between 0.9.8a and 0.9.8b [04 May 2006]
+
+ *) When applying a cipher rule check to see if string match is an explicit
+ cipher suite and only match that one cipher suite if it is.
+ [Steve Henson]
+
+ *) Link in manifests for VC++ if needed.
+ [Austin Ziegler <halostatue@gmail.com>]
+
+ *) Update support for ECC-based TLS ciphersuites according to
+ draft-ietf-tls-ecc-12.txt with proposed changes (but without
+ TLS extensions, which are supported starting with the 0.9.9
+ branch, not in the OpenSSL 0.9.8 branch).
+ [Douglas Stebila]
+
+ *) New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free() to support
+ opaque EVP_CIPHER_CTX handling.
+ [Steve Henson]
+
+ *) Fixes and enhancements to zlib compression code. We now only use
+ "zlib1.dll" and use the default __cdecl calling convention on Win32
+ to conform with the standards mentioned here:
+ http://www.zlib.net/DLL_FAQ.txt
+ Static zlib linking now works on Windows and the new --with-zlib-include
+ --with-zlib-lib options to Configure can be used to supply the location
+ of the headers and library. Gracefully handle case where zlib library
+ can't be loaded.
+ [Steve Henson]
+
+ *) Several fixes and enhancements to the OID generation code. The old code
+ sometimes allowed invalid OIDs (1.X for X >= 40 for example), couldn't
+ handle numbers larger than ULONG_MAX, truncated printing and had a
+ non standard OBJ_obj2txt() behaviour.
+ [Steve Henson]
+
+ *) Add support for building of engines under engine/ as shared libraries
+ under VC++ build system.
+ [Steve Henson]
+
+ *) Corrected the numerous bugs in the Win32 path splitter in DSO.
+ Hopefully, we will not see any false combination of paths any more.
+ [Richard Levitte]
+
+ Changes between 0.9.8 and 0.9.8a [11 Oct 2005]
+
+ *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING
+ (part of SSL_OP_ALL). This option used to disable the
+ countermeasure against man-in-the-middle protocol-version
+ rollback in the SSL 2.0 server implementation, which is a bad
+ idea. (CVE-2005-2969)
+
+ [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center
+ for Information Security, National Institute of Advanced Industrial
+ Science and Technology [AIST], Japan)]
+
+ *) Add two function to clear and return the verify parameter flags.
+ [Steve Henson]
+
+ *) Keep cipherlists sorted in the source instead of sorting them at
+ runtime, thus removing the need for a lock.
+ [Nils Larsch]
+
+ *) Avoid some small subgroup attacks in Diffie-Hellman.
+ [Nick Mathewson and Ben Laurie]
+
+ *) Add functions for well-known primes.
+ [Nick Mathewson]
+
+ *) Extended Windows CE support.
+ [Satoshi Nakamura and Andy Polyakov]
+
+ *) Initialize SSL_METHOD structures at compile time instead of during
+ runtime, thus removing the need for a lock.
+ [Steve Henson]
+
+ *) Make PKCS7_decrypt() work even if no certificate is supplied by
+ attempting to decrypt each encrypted key in turn. Add support to
+ smime utility.
+ [Steve Henson]
+
+ Changes between 0.9.7h and 0.9.8 [05 Jul 2005]
+
+ [NB: OpenSSL 0.9.7i and later 0.9.7 patch levels were released after
+ OpenSSL 0.9.8.]
+
+ *) Add libcrypto.pc and libssl.pc for those who feel they need them.
+ [Richard Levitte]
+
+ *) Change CA.sh and CA.pl so they don't bundle the CSR and the private
+ key into the same file any more.
+ [Richard Levitte]
+
+ *) Add initial support for Win64, both IA64 and AMD64/x64 flavors.
+ [Andy Polyakov]
+
+ *) Add -utf8 command line and config file option to 'ca'.
+ [Stefan <stf@udoma.org]
+
+ *) Removed the macro des_crypt(), as it seems to conflict with some
+ libraries. Use DES_crypt().
+ [Richard Levitte]
+
+ *) Correct naming of the 'chil' and '4758cca' ENGINEs. This
+ involves renaming the source and generated shared-libs for
+ both. The engines will accept the corrected or legacy ids
+ ('ncipher' and '4758_cca' respectively) when binding. NB,
+ this only applies when building 'shared'.
+ [Corinna Vinschen <vinschen@redhat.com> and Geoff Thorpe]
+
+ *) Add attribute functions to EVP_PKEY structure. Modify
+ PKCS12_create() to recognize a CSP name attribute and
+ use it. Make -CSP option work again in pkcs12 utility.
+ [Steve Henson]
+
+ *) Add new functionality to the bn blinding code:
+ - automatic re-creation of the BN_BLINDING parameters after
+ a fixed number of uses (currently 32)
+ - add new function for parameter creation
+ - introduce flags to control the update behaviour of the
+ BN_BLINDING parameters
+ - hide BN_BLINDING structure
+ Add a second BN_BLINDING slot to the RSA structure to improve
+ performance when a single RSA object is shared among several
+ threads.
+ [Nils Larsch]
+
+ *) Add support for DTLS.
+ [Nagendra Modadugu <nagendra@cs.stanford.edu> and Ben Laurie]
+
+ *) Add support for DER encoded private keys (SSL_FILETYPE_ASN1)
+ to SSL_CTX_use_PrivateKey_file() and SSL_use_PrivateKey_file()
+ [Walter Goulet]
+
+ *) Remove buggy and incompletet DH cert support from
+ ssl/ssl_rsa.c and ssl/s3_both.c
+ [Nils Larsch]
+
+ *) Use SHA-1 instead of MD5 as the default digest algorithm for
+ the apps/openssl applications.
+ [Nils Larsch]
+
+ *) Compile clean with "-Wall -Wmissing-prototypes
+ -Wstrict-prototypes -Wmissing-declarations -Werror". Currently
+ DEBUG_SAFESTACK must also be set.
+ [Ben Laurie]
+
+ *) Change ./Configure so that certain algorithms can be disabled by default.
+ The new counterpiece to "no-xxx" is "enable-xxx".
+
+ The patented RC5 and MDC2 algorithms will now be disabled unless
+ "enable-rc5" and "enable-mdc2", respectively, are specified.
+
+ (IDEA remains enabled despite being patented. This is because IDEA
+ is frequently required for interoperability, and there is no license
+ fee for non-commercial use. As before, "no-idea" can be used to
+ avoid this algorithm.)
+
+ [Bodo Moeller]
+
+ *) Add processing of proxy certificates (see RFC 3820). This work was
+ sponsored by KTH (The Royal Institute of Technology in Stockholm) and
+ EGEE (Enabling Grids for E-science in Europe).
+ [Richard Levitte]
+
+ *) RC4 performance overhaul on modern architectures/implementations, such
+ as Intel P4, IA-64 and AMD64.
+ [Andy Polyakov]
+
+ *) New utility extract-section.pl. This can be used specify an alternative
+ section number in a pod file instead of having to treat each file as
+ a separate case in Makefile. This can be done by adding two lines to the
+ pod file:
+
+ =for comment openssl_section:XXX
+
+ The blank line is mandatory.
+
+ [Steve Henson]
+
+ *) New arguments -certform, -keyform and -pass for s_client and s_server
+ to allow alternative format key and certificate files and passphrase
+ sources.
+ [Steve Henson]
+
+ *) New structure X509_VERIFY_PARAM which combines current verify parameters,
+ update associated structures and add various utility functions.
+
+ Add new policy related verify parameters, include policy checking in
+ standard verify code. Enhance 'smime' application with extra parameters
+ to support policy checking and print out.
+ [Steve Henson]
+
+ *) Add a new engine to support VIA PadLock ACE extensions in the VIA C3
+ Nehemiah processors. These extensions support AES encryption in hardware
+ as well as RNG (though RNG support is currently disabled).
+ [Michal Ludvig <michal@logix.cz>, with help from Andy Polyakov]
+
+ *) Deprecate BN_[get|set]_params() functions (they were ignored internally).
+ [Geoff Thorpe]
+
+ *) New FIPS 180-2 algorithms, SHA-224/-256/-384/-512 are implemented.
+ [Andy Polyakov and a number of other people]
+
+ *) Improved PowerPC platform support. Most notably BIGNUM assembler
+ implementation contributed by IBM.
+ [Suresh Chari, Peter Waltenberg, Andy Polyakov]
+
+ *) The new 'RSA_generate_key_ex' function now takes a BIGNUM for the public
+ exponent rather than 'unsigned long'. There is a corresponding change to
+ the new 'rsa_keygen' element of the RSA_METHOD structure.
+ [Jelte Jansen, Geoff Thorpe]
+
+ *) Functionality for creating the initial serial number file is now
+ moved from CA.pl to the 'ca' utility with a new option -create_serial.
+
+ (Before OpenSSL 0.9.7e, CA.pl used to initialize the serial
+ number file to 1, which is bound to cause problems. To avoid
+ the problems while respecting compatibility between different 0.9.7
+ patchlevels, 0.9.7e employed 'openssl x509 -next_serial' in
+ CA.pl for serial number initialization. With the new release 0.9.8,
+ we can fix the problem directly in the 'ca' utility.)
+ [Steve Henson]
+
+ *) Reduced header interdepencies by declaring more opaque objects in
+ ossl_typ.h. As a consequence, including some headers (eg. engine.h) will
+ give fewer recursive includes, which could break lazy source code - so
+ this change is covered by the OPENSSL_NO_DEPRECATED symbol. As always,
+ developers should define this symbol when building and using openssl to
+ ensure they track the recommended behaviour, interfaces, [etc], but
+ backwards-compatible behaviour prevails when this isn't defined.
+ [Geoff Thorpe]
+
+ *) New function X509_POLICY_NODE_print() which prints out policy nodes.
+ [Steve Henson]
+
+ *) Add new EVP function EVP_CIPHER_CTX_rand_key and associated functionality.
+ This will generate a random key of the appropriate length based on the
+ cipher context. The EVP_CIPHER can provide its own random key generation
+ routine to support keys of a specific form. This is used in the des and
+ 3des routines to generate a key of the correct parity. Update S/MIME
+ code to use new functions and hence generate correct parity DES keys.
+ Add EVP_CHECK_DES_KEY #define to return an error if the key is not
+ valid (weak or incorrect parity).
+ [Steve Henson]
+
+ *) Add a local set of CRLs that can be used by X509_verify_cert() as well
+ as looking them up. This is useful when the verified structure may contain
+ CRLs, for example PKCS#7 signedData. Modify PKCS7_verify() to use any CRLs
+ present unless the new PKCS7_NO_CRL flag is asserted.
+ [Steve Henson]
+
+ *) Extend ASN1 oid configuration module. It now additionally accepts the
+ syntax:
+
+ shortName = some long name, 1.2.3.4
+ [Steve Henson]
+
+ *) Reimplemented the BN_CTX implementation. There is now no more static
+ limitation on the number of variables it can handle nor the depth of the
+ "stack" handling for BN_CTX_start()/BN_CTX_end() pairs. The stack
+ information can now expand as required, and rather than having a single
+ static array of bignums, BN_CTX now uses a linked-list of such arrays
+ allowing it to expand on demand whilst maintaining the usefulness of
+ BN_CTX's "bundling".
+ [Geoff Thorpe]
+
+ *) Add a missing BN_CTX parameter to the 'rsa_mod_exp' callback in RSA_METHOD
+ to allow all RSA operations to function using a single BN_CTX.
+ [Geoff Thorpe]
+
+ *) Preliminary support for certificate policy evaluation and checking. This
+ is initially intended to pass the tests outlined in "Conformance Testing
+ of Relying Party Client Certificate Path Processing Logic" v1.07.
+ [Steve Henson]
+
+ *) bn_dup_expand() has been deprecated, it was introduced in 0.9.7 and
+ remained unused and not that useful. A variety of other little bignum
+ tweaks and fixes have also been made continuing on from the audit (see
+ below).
+ [Geoff Thorpe]
+
+ *) Constify all or almost all d2i, c2i, s2i and r2i functions, along with
+ associated ASN1, EVP and SSL functions and old ASN1 macros.
+ [Richard Levitte]
+
+ *) BN_zero() only needs to set 'top' and 'neg' to zero for correct results,
+ and this should never fail. So the return value from the use of
+ BN_set_word() (which can fail due to needless expansion) is now deprecated;
+ if OPENSSL_NO_DEPRECATED is defined, BN_zero() is a void macro.
+ [Geoff Thorpe]
+
+ *) BN_CTX_get() should return zero-valued bignums, providing the same
+ initialised value as BN_new().
+ [Geoff Thorpe, suggested by Ulf Möller]
+
+ *) Support for inhibitAnyPolicy certificate extension.
+ [Steve Henson]
+
+ *) An audit of the BIGNUM code is underway, for which debugging code is
+ enabled when BN_DEBUG is defined. This makes stricter enforcements on what
+ is considered valid when processing BIGNUMs, and causes execution to
+ assert() when a problem is discovered. If BN_DEBUG_RAND is defined,
+ further steps are taken to deliberately pollute unused data in BIGNUM
+ structures to try and expose faulty code further on. For now, openssl will
+ (in its default mode of operation) continue to tolerate the inconsistent
+ forms that it has tolerated in the past, but authors and packagers should
+ consider trying openssl and their own applications when compiled with
+ these debugging symbols defined. It will help highlight potential bugs in
+ their own code, and will improve the test coverage for OpenSSL itself. At
+ some point, these tighter rules will become openssl's default to improve
+ maintainability, though the assert()s and other overheads will remain only
+ in debugging configurations. See bn.h for more details.
+ [Geoff Thorpe, Nils Larsch, Ulf Möller]
+
+ *) BN_CTX_init() has been deprecated, as BN_CTX is an opaque structure
+ that can only be obtained through BN_CTX_new() (which implicitly
+ initialises it). The presence of this function only made it possible
+ to overwrite an existing structure (and cause memory leaks).
+ [Geoff Thorpe]
+
+ *) Because of the callback-based approach for implementing LHASH as a
+ template type, lh_insert() adds opaque objects to hash-tables and
+ lh_doall() or lh_doall_arg() are typically used with a destructor callback
+ to clean up those corresponding objects before destroying the hash table
+ (and losing the object pointers). So some over-zealous constifications in
+ LHASH have been relaxed so that lh_insert() does not take (nor store) the
+ objects as "const" and the lh_doall[_arg] callback wrappers are not
+ prototyped to have "const" restrictions on the object pointers they are
+ given (and so aren't required to cast them away any more).
+ [Geoff Thorpe]
+
+ *) The tmdiff.h API was so ugly and minimal that our own timing utility
+ (speed) prefers to use its own implementation. The two implementations
+ haven't been consolidated as yet (volunteers?) but the tmdiff API has had
+ its object type properly exposed (MS_TM) instead of casting to/from "char
+ *". This may still change yet if someone realises MS_TM and "ms_time_***"
+ aren't necessarily the greatest nomenclatures - but this is what was used
+ internally to the implementation so I've used that for now.
+ [Geoff Thorpe]
+
+ *) Ensure that deprecated functions do not get compiled when
+ OPENSSL_NO_DEPRECATED is defined. Some "openssl" subcommands and a few of
+ the self-tests were still using deprecated key-generation functions so
+ these have been updated also.
+ [Geoff Thorpe]
+
+ *) Reorganise PKCS#7 code to separate the digest location functionality
+ into PKCS7_find_digest(), digest addtion into PKCS7_bio_add_digest().
+ New function PKCS7_set_digest() to set the digest type for PKCS#7
+ digestedData type. Add additional code to correctly generate the
+ digestedData type and add support for this type in PKCS7 initialization
+ functions.
+ [Steve Henson]
+
+ *) New function PKCS7_set0_type_other() this initializes a PKCS7
+ structure of type "other".
+ [Steve Henson]
+
+ *) Fix prime generation loop in crypto/bn/bn_prime.pl by making
+ sure the loop does correctly stop and breaking ("division by zero")
+ modulus operations are not performed. The (pre-generated) prime
+ table crypto/bn/bn_prime.h was already correct, but it could not be
+ re-generated on some platforms because of the "division by zero"
+ situation in the script.
+ [Ralf S. Engelschall]
+
+ *) Update support for ECC-based TLS ciphersuites according to
+ draft-ietf-tls-ecc-03.txt: the KDF1 key derivation function with
+ SHA-1 now is only used for "small" curves (where the
+ representation of a field element takes up to 24 bytes); for
+ larger curves, the field element resulting from ECDH is directly
+ used as premaster secret.
+ [Douglas Stebila (Sun Microsystems Laboratories)]
+
+ *) Add code for kP+lQ timings to crypto/ec/ectest.c, and add SEC2
+ curve secp160r1 to the tests.
+ [Douglas Stebila (Sun Microsystems Laboratories)]
+
+ *) Add the possibility to load symbols globally with DSO.
+ [Götz Babin-Ebell <babin-ebell@trustcenter.de> via Richard Levitte]
+
+ *) Add the functions ERR_set_mark() and ERR_pop_to_mark() for better
+ control of the error stack.
+ [Richard Levitte]
+
+ *) Add support for STORE in ENGINE.
+ [Richard Levitte]
+
+ *) Add the STORE type. The intention is to provide a common interface
+ to certificate and key stores, be they simple file-based stores, or
+ HSM-type store, or LDAP stores, or...
+ NOTE: The code is currently UNTESTED and isn't really used anywhere.
+ [Richard Levitte]
+
+ *) Add a generic structure called OPENSSL_ITEM. This can be used to
+ pass a list of arguments to any function as well as provide a way
+ for a function to pass data back to the caller.
+ [Richard Levitte]
+
+ *) Add the functions BUF_strndup() and BUF_memdup(). BUF_strndup()
+ works like BUF_strdup() but can be used to duplicate a portion of
+ a string. The copy gets NUL-terminated. BUF_memdup() duplicates
+ a memory area.
+ [Richard Levitte]
+
+ *) Add the function sk_find_ex() which works like sk_find(), but will
+ return an index to an element even if an exact match couldn't be
+ found. The index is guaranteed to point at the element where the
+ searched-for key would be inserted to preserve sorting order.
+ [Richard Levitte]
+
+ *) Add the function OBJ_bsearch_ex() which works like OBJ_bsearch() but
+ takes an extra flags argument for optional functionality. Currently,
+ the following flags are defined:
+
+ OBJ_BSEARCH_VALUE_ON_NOMATCH
+ This one gets OBJ_bsearch_ex() to return a pointer to the first
+ element where the comparing function returns a negative or zero
+ number.
+
+ OBJ_BSEARCH_FIRST_VALUE_ON_MATCH
+ This one gets OBJ_bsearch_ex() to return a pointer to the first
+ element where the comparing function returns zero. This is useful
+ if there are more than one element where the comparing function
+ returns zero.
+ [Richard Levitte]
+
+ *) Make it possible to create self-signed certificates with 'openssl ca'
+ in such a way that the self-signed certificate becomes part of the
+ CA database and uses the same mechanisms for serial number generation
+ as all other certificate signing. The new flag '-selfsign' enables
+ this functionality. Adapt CA.sh and CA.pl.in.
+ [Richard Levitte]
+
+ *) Add functionality to check the public key of a certificate request
+ against a given private. This is useful to check that a certificate
+ request can be signed by that key (self-signing).
+ [Richard Levitte]
+
+ *) Make it possible to have multiple active certificates with the same
+ subject in the CA index file. This is done only if the keyword
+ 'unique_subject' is set to 'no' in the main CA section (default
+ if 'CA_default') of the configuration file. The value is saved
+ with the database itself in a separate index attribute file,
+ named like the index file with '.attr' appended to the name.
+ [Richard Levitte]
+
+ *) Generate muti valued AVAs using '+' notation in config files for
+ req and dirName.
+ [Steve Henson]
+
+ *) Support for nameConstraints certificate extension.
+ [Steve Henson]
+
+ *) Support for policyConstraints certificate extension.
+ [Steve Henson]
+
+ *) Support for policyMappings certificate extension.
+ [Steve Henson]
+
+ *) Make sure the default DSA_METHOD implementation only uses its
+ dsa_mod_exp() and/or bn_mod_exp() handlers if they are non-NULL,
+ and change its own handlers to be NULL so as to remove unnecessary
+ indirection. This lets alternative implementations fallback to the
+ default implementation more easily.
+ [Geoff Thorpe]
+
+ *) Support for directoryName in GeneralName related extensions
+ in config files.
+ [Steve Henson]
+
+ *) Make it possible to link applications using Makefile.shared.
+ Make that possible even when linking against static libraries!
+ [Richard Levitte]
+
+ *) Support for single pass processing for S/MIME signing. This now
+ means that S/MIME signing can be done from a pipe, in addition
+ cleartext signing (multipart/signed type) is effectively streaming
+ and the signed data does not need to be all held in memory.
+
+ This is done with a new flag PKCS7_STREAM. When this flag is set
+ PKCS7_sign() only initializes the PKCS7 structure and the actual signing
+ is done after the data is output (and digests calculated) in
+ SMIME_write_PKCS7().
+ [Steve Henson]
+
+ *) Add full support for -rpath/-R, both in shared libraries and
+ applications, at least on the platforms where it's known how
+ to do it.
+ [Richard Levitte]
+
+ *) In crypto/ec/ec_mult.c, implement fast point multiplication with
+ precomputation, based on wNAF splitting: EC_GROUP_precompute_mult()
+ will now compute a table of multiples of the generator that
+ makes subsequent invocations of EC_POINTs_mul() or EC_POINT_mul()
+ faster (notably in the case of a single point multiplication,
+ scalar * generator).
+ [Nils Larsch, Bodo Moeller]
+
+ *) IPv6 support for certificate extensions. The various extensions
+ which use the IP:a.b.c.d can now take IPv6 addresses using the
+ formats of RFC1884 2.2 . IPv6 addresses are now also displayed
+ correctly.
+ [Steve Henson]
+
+ *) Added an ENGINE that implements RSA by performing private key
+ exponentiations with the GMP library. The conversions to and from
+ GMP's mpz_t format aren't optimised nor are any montgomery forms
+ cached, and on x86 it appears OpenSSL's own performance has caught up.
+ However there are likely to be other architectures where GMP could
+ provide a boost. This ENGINE is not built in by default, but it can be
+ specified at Configure time and should be accompanied by the necessary
+ linker additions, eg;
+ ./config -DOPENSSL_USE_GMP -lgmp
+ [Geoff Thorpe]
+
+ *) "openssl engine" will not display ENGINE/DSO load failure errors when
+ testing availability of engines with "-t" - the old behaviour is
+ produced by increasing the feature's verbosity with "-tt".
+ [Geoff Thorpe]
+
+ *) ECDSA routines: under certain error conditions uninitialized BN objects
+ could be freed. Solution: make sure initialization is performed early
+ enough. (Reported and fix supplied by Nils Larsch <nla@trustcenter.de>
+ via PR#459)
+ [Lutz Jaenicke]
+
+ *) Key-generation can now be implemented in RSA_METHOD, DSA_METHOD
+ and DH_METHOD (eg. by ENGINE implementations) to override the normal
+ software implementations. For DSA and DH, parameter generation can
+ also be overriden by providing the appropriate method callbacks.
+ [Geoff Thorpe]
+
+ *) Change the "progress" mechanism used in key-generation and
+ primality testing to functions that take a new BN_GENCB pointer in
+ place of callback/argument pairs. The new API functions have "_ex"
+ postfixes and the older functions are reimplemented as wrappers for
+ the new ones. The OPENSSL_NO_DEPRECATED symbol can be used to hide
+ declarations of the old functions to help (graceful) attempts to
+ migrate to the new functions. Also, the new key-generation API
+ functions operate on a caller-supplied key-structure and return
+ success/failure rather than returning a key or NULL - this is to
+ help make "keygen" another member function of RSA_METHOD etc.
+
+ Example for using the new callback interface:
+
+ int (*my_callback)(int a, int b, BN_GENCB *cb) = ...;
+ void *my_arg = ...;
+ BN_GENCB my_cb;
+
+ BN_GENCB_set(&my_cb, my_callback, my_arg);
+
+ return BN_is_prime_ex(some_bignum, BN_prime_checks, NULL, &cb);
+ /* For the meaning of a, b in calls to my_callback(), see the
+ * documentation of the function that calls the callback.
+ * cb will point to my_cb; my_arg can be retrieved as cb->arg.
+ * my_callback should return 1 if it wants BN_is_prime_ex()
+ * to continue, or 0 to stop.
+ */
+
+ [Geoff Thorpe]
+
+ *) Change the ZLIB compression method to be stateful, and make it
+ available to TLS with the number defined in
+ draft-ietf-tls-compression-04.txt.
+ [Richard Levitte]
+
+ *) Add the ASN.1 structures and functions for CertificatePair, which
+ is defined as follows (according to X.509_4thEditionDraftV6.pdf):
+
+ CertificatePair ::= SEQUENCE {
+ forward [0] Certificate OPTIONAL,
+ reverse [1] Certificate OPTIONAL,
+ -- at least one of the pair shall be present -- }
+
+ Also implement the PEM functions to read and write certificate
+ pairs, and defined the PEM tag as "CERTIFICATE PAIR".
+
+ This needed to be defined, mostly for the sake of the LDAP
+ attribute crossCertificatePair, but may prove useful elsewhere as
+ well.
+ [Richard Levitte]
+
+ *) Make it possible to inhibit symlinking of shared libraries in
+ Makefile.shared, for Cygwin's sake.
+ [Richard Levitte]
+
+ *) Extend the BIGNUM API by creating a function
+ void BN_set_negative(BIGNUM *a, int neg);
+ and a macro that behave like
+ int BN_is_negative(const BIGNUM *a);
+
+ to avoid the need to access 'a->neg' directly in applications.
+ [Nils Larsch]
+
+ *) Implement fast modular reduction for pseudo-Mersenne primes
+ used in NIST curves (crypto/bn/bn_nist.c, crypto/ec/ecp_nist.c).
+ EC_GROUP_new_curve_GFp() will now automatically use this
+ if applicable.
+ [Nils Larsch <nla@trustcenter.de>]
+
+ *) Add new lock type (CRYPTO_LOCK_BN).
+ [Bodo Moeller]
+
+ *) Change the ENGINE framework to automatically load engines
+ dynamically from specific directories unless they could be
+ found to already be built in or loaded. Move all the
+ current engines except for the cryptodev one to a new
+ directory engines/.
+ The engines in engines/ are built as shared libraries if
+ the "shared" options was given to ./Configure or ./config.
+ Otherwise, they are inserted in libcrypto.a.
+ /usr/local/ssl/engines is the default directory for dynamic
+ engines, but that can be overriden at configure time through
+ the usual use of --prefix and/or --openssldir, and at run
+ time with the environment variable OPENSSL_ENGINES.
+ [Geoff Thorpe and Richard Levitte]
+
+ *) Add Makefile.shared, a helper makefile to build shared
+ libraries. Addapt Makefile.org.
+ [Richard Levitte]
+
+ *) Add version info to Win32 DLLs.
+ [Peter 'Luna' Runestig" <peter@runestig.com>]
+
+ *) Add new 'medium level' PKCS#12 API. Certificates and keys
+ can be added using this API to created arbitrary PKCS#12
+ files while avoiding the low level API.
+
+ New options to PKCS12_create(), key or cert can be NULL and
+ will then be omitted from the output file. The encryption
+ algorithm NIDs can be set to -1 for no encryption, the mac
+ iteration count can be set to 0 to omit the mac.
+
+ Enhance pkcs12 utility by making the -nokeys and -nocerts
+ options work when creating a PKCS#12 file. New option -nomac
+ to omit the mac, NONE can be set for an encryption algorithm.
+ New code is modified to use the enhanced PKCS12_create()
+ instead of the low level API.
+ [Steve Henson]
+
+ *) Extend ASN1 encoder to support indefinite length constructed
+ encoding. This can output sequences tags and octet strings in
+ this form. Modify pk7_asn1.c to support indefinite length
+ encoding. This is experimental and needs additional code to
+ be useful, such as an ASN1 bio and some enhanced streaming
+ PKCS#7 code.
+
+ Extend template encode functionality so that tagging is passed
+ down to the template encoder.
+ [Steve Henson]
+
+ *) Let 'openssl req' fail if an argument to '-newkey' is not
+ recognized instead of using RSA as a default.
+ [Bodo Moeller]
+
+ *) Add support for ECC-based ciphersuites from draft-ietf-tls-ecc-01.txt.
+ As these are not official, they are not included in "ALL";
+ the "ECCdraft" ciphersuite group alias can be used to select them.
+ [Vipul Gupta and Sumit Gupta (Sun Microsystems Laboratories)]
+
+ *) Add ECDH engine support.
+ [Nils Gura and Douglas Stebila (Sun Microsystems Laboratories)]
+
+ *) Add ECDH in new directory crypto/ecdh/.
+ [Douglas Stebila (Sun Microsystems Laboratories)]
+
+ *) Let BN_rand_range() abort with an error after 100 iterations
+ without success (which indicates a broken PRNG).
+ [Bodo Moeller]
+
+ *) Change BN_mod_sqrt() so that it verifies that the input value
+ is really the square of the return value. (Previously,
+ BN_mod_sqrt would show GIGO behaviour.)
+ [Bodo Moeller]
+
+ *) Add named elliptic curves over binary fields from X9.62, SECG,
+ and WAP/WTLS; add OIDs that were still missing.
+
+ [Sheueling Chang Shantz and Douglas Stebila
+ (Sun Microsystems Laboratories)]
+
+ *) Extend the EC library for elliptic curves over binary fields
+ (new files ec2_smpl.c, ec2_smpt.c, ec2_mult.c in crypto/ec/).
+ New EC_METHOD:
+
+ EC_GF2m_simple_method
+
+ New API functions:
+
+ EC_GROUP_new_curve_GF2m
+ EC_GROUP_set_curve_GF2m
+ EC_GROUP_get_curve_GF2m
+ EC_POINT_set_affine_coordinates_GF2m
+ EC_POINT_get_affine_coordinates_GF2m
+ EC_POINT_set_compressed_coordinates_GF2m
+
+ Point compression for binary fields is disabled by default for
+ patent reasons (compile with OPENSSL_EC_BIN_PT_COMP defined to
+ enable it).
+
+ As binary polynomials are represented as BIGNUMs, various members
+ of the EC_GROUP and EC_POINT data structures can be shared
+ between the implementations for prime fields and binary fields;
+ the above ..._GF2m functions (except for EX_GROUP_new_curve_GF2m)
+ are essentially identical to their ..._GFp counterparts.
+ (For simplicity, the '..._GFp' prefix has been dropped from
+ various internal method names.)
+
+ An internal 'field_div' method (similar to 'field_mul' and
+ 'field_sqr') has been added; this is used only for binary fields.
+
+ [Sheueling Chang Shantz and Douglas Stebila
+ (Sun Microsystems Laboratories)]
+
+ *) Optionally dispatch EC_POINT_mul(), EC_POINT_precompute_mult()
+ through methods ('mul', 'precompute_mult').
+
+ The generic implementations (now internally called 'ec_wNAF_mul'
+ and 'ec_wNAF_precomputed_mult') remain the default if these
+ methods are undefined.
+
+ [Sheueling Chang Shantz and Douglas Stebila
+ (Sun Microsystems Laboratories)]
+
+ *) New function EC_GROUP_get_degree, which is defined through
+ EC_METHOD. For curves over prime fields, this returns the bit
+ length of the modulus.
+
+ [Sheueling Chang Shantz and Douglas Stebila
+ (Sun Microsystems Laboratories)]
+
+ *) New functions EC_GROUP_dup, EC_POINT_dup.
+ (These simply call ..._new and ..._copy).
+
+ [Sheueling Chang Shantz and Douglas Stebila
+ (Sun Microsystems Laboratories)]
+
+ *) Add binary polynomial arithmetic software in crypto/bn/bn_gf2m.c.
+ Polynomials are represented as BIGNUMs (where the sign bit is not
+ used) in the following functions [macros]:
+
+ BN_GF2m_add
+ BN_GF2m_sub [= BN_GF2m_add]
+ BN_GF2m_mod [wrapper for BN_GF2m_mod_arr]
+ BN_GF2m_mod_mul [wrapper for BN_GF2m_mod_mul_arr]
+ BN_GF2m_mod_sqr [wrapper for BN_GF2m_mod_sqr_arr]
+ BN_GF2m_mod_inv
+ BN_GF2m_mod_exp [wrapper for BN_GF2m_mod_exp_arr]
+ BN_GF2m_mod_sqrt [wrapper for BN_GF2m_mod_sqrt_arr]
+ BN_GF2m_mod_solve_quad [wrapper for BN_GF2m_mod_solve_quad_arr]
+ BN_GF2m_cmp [= BN_ucmp]
+
+ (Note that only the 'mod' functions are actually for fields GF(2^m).
+ BN_GF2m_add() is misnomer, but this is for the sake of consistency.)
+
+ For some functions, an the irreducible polynomial defining a
+ field can be given as an 'unsigned int[]' with strictly
+ decreasing elements giving the indices of those bits that are set;
+ i.e., p[] represents the polynomial
+ f(t) = t^p[0] + t^p[1] + ... + t^p[k]
+ where
+ p[0] > p[1] > ... > p[k] = 0.
+ This applies to the following functions:
+
+ BN_GF2m_mod_arr
+ BN_GF2m_mod_mul_arr
+ BN_GF2m_mod_sqr_arr
+ BN_GF2m_mod_inv_arr [wrapper for BN_GF2m_mod_inv]
+ BN_GF2m_mod_div_arr [wrapper for BN_GF2m_mod_div]
+ BN_GF2m_mod_exp_arr
+ BN_GF2m_mod_sqrt_arr
+ BN_GF2m_mod_solve_quad_arr
+ BN_GF2m_poly2arr
+ BN_GF2m_arr2poly
+
+ Conversion can be performed by the following functions:
+
+ BN_GF2m_poly2arr
+ BN_GF2m_arr2poly
+
+ bntest.c has additional tests for binary polynomial arithmetic.
+
+ Two implementations for BN_GF2m_mod_div() are available.
+ The default algorithm simply uses BN_GF2m_mod_inv() and
+ BN_GF2m_mod_mul(). The alternative algorithm is compiled in only
+ if OPENSSL_SUN_GF2M_DIV is defined (patent pending; read the
+ copyright notice in crypto/bn/bn_gf2m.c before enabling it).
+
+ [Sheueling Chang Shantz and Douglas Stebila
+ (Sun Microsystems Laboratories)]
+
+ *) Add new error code 'ERR_R_DISABLED' that can be used when some
+ functionality is disabled at compile-time.
+ [Douglas Stebila <douglas.stebila@sun.com>]
+
+ *) Change default behaviour of 'openssl asn1parse' so that more
+ information is visible when viewing, e.g., a certificate:
+
+ Modify asn1_parse2 (crypto/asn1/asn1_par.c) so that in non-'dump'
+ mode the content of non-printable OCTET STRINGs is output in a
+ style similar to INTEGERs, but with '[HEX DUMP]' prepended to
+ avoid the appearance of a printable string.
+ [Nils Larsch <nla@trustcenter.de>]
+
+ *) Add 'asn1_flag' and 'asn1_form' member to EC_GROUP with access
+ functions
+ EC_GROUP_set_asn1_flag()
+ EC_GROUP_get_asn1_flag()
+ EC_GROUP_set_point_conversion_form()
+ EC_GROUP_get_point_conversion_form()
+ These control ASN1 encoding details:
+ - Curves (i.e., groups) are encoded explicitly unless asn1_flag
+ has been set to OPENSSL_EC_NAMED_CURVE.
+ - Points are encoded in uncompressed form by default; options for
+ asn1_for are as for point2oct, namely
+ POINT_CONVERSION_COMPRESSED
+ POINT_CONVERSION_UNCOMPRESSED
+ POINT_CONVERSION_HYBRID
+
+ Also add 'seed' and 'seed_len' members to EC_GROUP with access
+ functions
+ EC_GROUP_set_seed()
+ EC_GROUP_get0_seed()
+ EC_GROUP_get_seed_len()
+ This is used only for ASN1 purposes (so far).
+ [Nils Larsch <nla@trustcenter.de>]
+
+ *) Add 'field_type' member to EC_METHOD, which holds the NID
+ of the appropriate field type OID. The new function
+ EC_METHOD_get_field_type() returns this value.
+ [Nils Larsch <nla@trustcenter.de>]
+
+ *) Add functions
+ EC_POINT_point2bn()
+ EC_POINT_bn2point()
+ EC_POINT_point2hex()
+ EC_POINT_hex2point()
+ providing useful interfaces to EC_POINT_point2oct() and
+ EC_POINT_oct2point().
+ [Nils Larsch <nla@trustcenter.de>]
+
+ *) Change internals of the EC library so that the functions
+ EC_GROUP_set_generator()
+ EC_GROUP_get_generator()
+ EC_GROUP_get_order()
+ EC_GROUP_get_cofactor()
+ are implemented directly in crypto/ec/ec_lib.c and not dispatched
+ to methods, which would lead to unnecessary code duplication when
+ adding different types of curves.
+ [Nils Larsch <nla@trustcenter.de> with input by Bodo Moeller]
+
+ *) Implement compute_wNAF (crypto/ec/ec_mult.c) without BIGNUM
+ arithmetic, and such that modified wNAFs are generated
+ (which avoid length expansion in many cases).
+ [Bodo Moeller]
+
+ *) Add a function EC_GROUP_check_discriminant() (defined via
+ EC_METHOD) that verifies that the curve discriminant is non-zero.
+
+ Add a function EC_GROUP_check() that makes some sanity tests
+ on a EC_GROUP, its generator and order. This includes
+ EC_GROUP_check_discriminant().
+ [Nils Larsch <nla@trustcenter.de>]
+
+ *) Add ECDSA in new directory crypto/ecdsa/.
+
+ Add applications 'openssl ecparam' and 'openssl ecdsa'
+ (these are based on 'openssl dsaparam' and 'openssl dsa').
+
+ ECDSA support is also included in various other files across the
+ library. Most notably,
+ - 'openssl req' now has a '-newkey ecdsa:file' option;
+ - EVP_PKCS82PKEY (crypto/evp/evp_pkey.c) now can handle ECDSA;
+ - X509_PUBKEY_get (crypto/asn1/x_pubkey.c) and
+ d2i_PublicKey (crypto/asn1/d2i_pu.c) have been modified to make
+ them suitable for ECDSA where domain parameters must be
+ extracted before the specific public key;
+ - ECDSA engine support has been added.
+ [Nils Larsch <nla@trustcenter.de>]
+
+ *) Include some named elliptic curves, and add OIDs from X9.62,
+ SECG, and WAP/WTLS. Each curve can be obtained from the new
+ function
+ EC_GROUP_new_by_curve_name(),
+ and the list of available named curves can be obtained with
+ EC_get_builtin_curves().
+ Also add a 'curve_name' member to EC_GROUP objects, which can be
+ accessed via
+ EC_GROUP_set_curve_name()
+ EC_GROUP_get_curve_name()
+ [Nils Larsch <larsch@trustcenter.de, Bodo Moeller]
+
+ *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there
+ was actually never needed) and in BN_mul(). The removal in BN_mul()
+ required a small change in bn_mul_part_recursive() and the addition
+ of the functions bn_cmp_part_words(), bn_sub_part_words() and
+ bn_add_part_words(), which do the same thing as bn_cmp_words(),
+ bn_sub_words() and bn_add_words() except they take arrays with
+ differing sizes.
+ [Richard Levitte]
+
+ Changes between 0.9.7l and 0.9.7m [23 Feb 2007]
+
+ *) Cleanse PEM buffers before freeing them since they may contain
+ sensitive data.
+ [Benjamin Bennett <ben@psc.edu>]
+
+ *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
+ a ciphersuite string such as "DEFAULT:RSA" cannot enable
+ authentication-only ciphersuites.
+ [Bodo Moeller]
+
+ *) Since AES128 and AES256 share a single mask bit in the logic of
+ ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
+ kludge to work properly if AES128 is available and AES256 isn't.
+ [Victor Duchovni]
+
+ *) Expand security boundary to match 1.1.1 module.
+ [Steve Henson]
+
+ *) Remove redundant features: hash file source, editing of test vectors
+ modify fipsld to use external fips_premain.c signature.
+ [Steve Henson]
+
+ *) New perl script mkfipsscr.pl to create shell scripts or batch files to
+ run algorithm test programs.
+ [Steve Henson]
+
+ *) Make algorithm test programs more tolerant of whitespace.
+ [Steve Henson]
+
+ *) Have SSL/TLS server implementation tolerate "mismatched" record
+ protocol version while receiving ClientHello even if the
+ ClientHello is fragmented. (The server can't insist on the
+ particular protocol version it has chosen before the ServerHello
+ message has informed the client about his choice.)
+ [Bodo Moeller]
+
+ *) Load error codes if they are not already present instead of using a
+ static variable. This allows them to be cleanly unloaded and reloaded.
+ [Steve Henson]
+
+ Changes between 0.9.7k and 0.9.7l [28 Sep 2006]
+
+ *) Introduce limits to prevent malicious keys being able to
+ cause a denial of service. (CVE-2006-2940)
+ [Steve Henson, Bodo Moeller]
+
+ *) Fix ASN.1 parsing of certain invalid structures that can result
+ in a denial of service. (CVE-2006-2937) [Steve Henson]
+
+ *) Fix buffer overflow in SSL_get_shared_ciphers() function.
+ (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team]
+
+ *) Fix SSL client code which could crash if connecting to a
+ malicious SSLv2 server. (CVE-2006-4343)
+ [Tavis Ormandy and Will Drewry, Google Security Team]
+
+ *) Change ciphersuite string processing so that an explicit
+ ciphersuite selects this one ciphersuite (so that "AES256-SHA"
+ will no longer include "AES128-SHA"), and any other similar
+ ciphersuite (same bitmap) from *other* protocol versions (so that
+ "RC4-MD5" will still include both the SSL 2.0 ciphersuite and the
+ SSL 3.0/TLS 1.0 ciphersuite). This is a backport combining
+ changes from 0.9.8b and 0.9.8d.
+ [Bodo Moeller]
+
+ Changes between 0.9.7j and 0.9.7k [05 Sep 2006]
+
+ *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher
+ (CVE-2006-4339) [Ben Laurie and Google Security Team]
+
+ *) Change the Unix randomness entropy gathering to use poll() when
+ possible instead of select(), since the latter has some
+ undesirable limitations.
+ [Darryl Miles via Richard Levitte and Bodo Moeller]
+
+ *) Disable rogue ciphersuites:
+
+ - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5")
+ - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5")
+ - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5")
+
+ The latter two were purportedly from
+ draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really
+ appear there.
+
+ Also deactive the remaining ciphersuites from
+ draft-ietf-tls-56-bit-ciphersuites-01.txt. These are just as
+ unofficial, and the ID has long expired.
+ [Bodo Moeller]
+
+ *) Fix RSA blinding Heisenbug (problems sometimes occured on
+ dual-core machines) and other potential thread-safety issues.
+ [Bodo Moeller]
+
+ Changes between 0.9.7i and 0.9.7j [04 May 2006]
+
+ *) Adapt fipsld and the build system to link against the validated FIPS
+ module in FIPS mode.
+ [Steve Henson]
+
+ *) Fixes for VC++ 2005 build under Windows.
+ [Steve Henson]
+
+ *) Add new Windows build target VC-32-GMAKE for VC++. This uses GNU make
+ from a Windows bash shell such as MSYS. It is autodetected from the
+ "config" script when run from a VC++ environment. Modify standard VC++
+ build to use fipscanister.o from the GNU make build.
+ [Steve Henson]
+
+ Changes between 0.9.7h and 0.9.7i [14 Oct 2005]
+
+ *) Wrapped the definition of EVP_MAX_MD_SIZE in a #ifdef OPENSSL_FIPS.
+ The value now differs depending on if you build for FIPS or not.
+ BEWARE! A program linked with a shared FIPSed libcrypto can't be
+ safely run with a non-FIPSed libcrypto, as it may crash because of
+ the difference induced by this change.
+ [Andy Polyakov]
+
+ Changes between 0.9.7g and 0.9.7h [11 Oct 2005]
+
+ *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING
+ (part of SSL_OP_ALL). This option used to disable the
+ countermeasure against man-in-the-middle protocol-version
+ rollback in the SSL 2.0 server implementation, which is a bad
+ idea. (CVE-2005-2969)
+
+ [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center
+ for Information Security, National Institute of Advanced Industrial
+ Science and Technology [AIST], Japan)]
+
+ *) Minimal support for X9.31 signatures and PSS padding modes. This is
+ mainly for FIPS compliance and not fully integrated at this stage.
+ [Steve Henson]
+
+ *) For DSA signing, unless DSA_FLAG_NO_EXP_CONSTTIME is set, perform
+ the exponentiation using a fixed-length exponent. (Otherwise,
+ the information leaked through timing could expose the secret key
+ after many signatures; cf. Bleichenbacher's attack on DSA with
+ biased k.)
+ [Bodo Moeller]
+
+ *) Make a new fixed-window mod_exp implementation the default for
+ RSA, DSA, and DH private-key operations so that the sequence of
+ squares and multiplies and the memory access pattern are
+ independent of the particular secret key. This will mitigate
+ cache-timing and potential related attacks.
+
+ BN_mod_exp_mont_consttime() is the new exponentiation implementation,
+ and this is automatically used by BN_mod_exp_mont() if the new flag
+ BN_FLG_EXP_CONSTTIME is set for the exponent. RSA, DSA, and DH
+ will use this BN flag for private exponents unless the flag
+ RSA_FLAG_NO_EXP_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME, or
+ DH_FLAG_NO_EXP_CONSTTIME, respectively, is set.
+
+ [Matthew D Wood (Intel Corp), with some changes by Bodo Moeller]
+
+ *) Change the client implementation for SSLv23_method() and
+ SSLv23_client_method() so that is uses the SSL 3.0/TLS 1.0
+ Client Hello message format if the SSL_OP_NO_SSLv2 option is set.
+ (Previously, the SSL 2.0 backwards compatible Client Hello
+ message format would be used even with SSL_OP_NO_SSLv2.)
+ [Bodo Moeller]
+
+ *) Add support for smime-type MIME parameter in S/MIME messages which some
+ clients need.
+ [Steve Henson]
+
+ *) New function BN_MONT_CTX_set_locked() to set montgomery parameters in
+ a threadsafe manner. Modify rsa code to use new function and add calls
+ to dsa and dh code (which had race conditions before).
+ [Steve Henson]
+
+ *) Include the fixed error library code in the C error file definitions
+ instead of fixing them up at runtime. This keeps the error code
+ structures constant.
+ [Steve Henson]
+
+ Changes between 0.9.7f and 0.9.7g [11 Apr 2005]
+
+ [NB: OpenSSL 0.9.7h and later 0.9.7 patch levels were released after
+ OpenSSL 0.9.8.]
+
+ *) Fixes for newer kerberos headers. NB: the casts are needed because
+ the 'length' field is signed on one version and unsigned on another
+ with no (?) obvious way to tell the difference, without these VC++
+ complains. Also the "definition" of FAR (blank) is no longer included
+ nor is the error ENOMEM. KRB5_PRIVATE has to be set to 1 to pick up
+ some needed definitions.
+ [Steve Henson]
+
+ *) Undo Cygwin change.
+ [Ulf Möller]
+
+ *) Added support for proxy certificates according to RFC 3820.
+ Because they may be a security thread to unaware applications,
+ they must be explicitely allowed in run-time. See
+ docs/HOWTO/proxy_certificates.txt for further information.
+ [Richard Levitte]
+
+ Changes between 0.9.7e and 0.9.7f [22 Mar 2005]
+
+ *) Use (SSL_RANDOM_VALUE - 4) bytes of pseudo random data when generating
+ server and client random values. Previously
+ (SSL_RANDOM_VALUE - sizeof(time_t)) would be used which would result in
+ less random data when sizeof(time_t) > 4 (some 64 bit platforms).
+
+ This change has negligible security impact because:
+
+ 1. Server and client random values still have 24 bytes of pseudo random
+ data.
+
+ 2. Server and client random values are sent in the clear in the initial
+ handshake.
+
+ 3. The master secret is derived using the premaster secret (48 bytes in
+ size for static RSA ciphersuites) as well as client server and random
+ values.
+
+ The OpenSSL team would like to thank the UK NISCC for bringing this issue
+ to our attention.
+
+ [Stephen Henson, reported by UK NISCC]
+
+ *) Use Windows randomness collection on Cygwin.
+ [Ulf Möller]
+
+ *) Fix hang in EGD/PRNGD query when communication socket is closed
+ prematurely by EGD/PRNGD.
+ [Darren Tucker <dtucker@zip.com.au> via Lutz Jänicke, resolves #1014]
+
+ *) Prompt for pass phrases when appropriate for PKCS12 input format.
+ [Steve Henson]
+
+ *) Back-port of selected performance improvements from development
+ branch, as well as improved support for PowerPC platforms.
+ [Andy Polyakov]
+
+ *) Add lots of checks for memory allocation failure, error codes to indicate
+ failure and freeing up memory if a failure occurs.
+ [Nauticus Networks SSL Team <openssl@nauticusnet.com>, Steve Henson]
+
+ *) Add new -passin argument to dgst.
+ [Steve Henson]
+
+ *) Perform some character comparisons of different types in X509_NAME_cmp:
+ this is needed for some certificates that reencode DNs into UTF8Strings
+ (in violation of RFC3280) and can't or wont issue name rollover
+ certificates.
+ [Steve Henson]
+
+ *) Make an explicit check during certificate validation to see that
+ the CA setting in each certificate on the chain is correct. As a
+ side effect always do the following basic checks on extensions,
+ not just when there's an associated purpose to the check:
+
+ - if there is an unhandled critical extension (unless the user
+ has chosen to ignore this fault)
+ - if the path length has been exceeded (if one is set at all)
+ - that certain extensions fit the associated purpose (if one has
+ been given)
+ [Richard Levitte]
+
+ Changes between 0.9.7d and 0.9.7e [25 Oct 2004]
+
+ *) Avoid a race condition when CRLs are checked in a multi threaded
+ environment. This would happen due to the reordering of the revoked
+ entries during signature checking and serial number lookup. Now the
+ encoding is cached and the serial number sort performed under a lock.
+ Add new STACK function sk_is_sorted().
+ [Steve Henson]
+
+ *) Add Delta CRL to the extension code.
+ [Steve Henson]
+
+ *) Various fixes to s3_pkt.c so alerts are sent properly.
+ [David Holmes <d.holmes@f5.com>]
+
+ *) Reduce the chances of duplicate issuer name and serial numbers (in
+ violation of RFC3280) using the OpenSSL certificate creation utilities.
+ This is done by creating a random 64 bit value for the initial serial
+ number when a serial number file is created or when a self signed
+ certificate is created using 'openssl req -x509'. The initial serial
+ number file is created using 'openssl x509 -next_serial' in CA.pl
+ rather than being initialized to 1.
+ [Steve Henson]
+
+ Changes between 0.9.7c and 0.9.7d [17 Mar 2004]
+
+ *) Fix null-pointer assignment in do_change_cipher_spec() revealed
+ by using the Codenomicon TLS Test Tool (CVE-2004-0079)
+ [Joe Orton, Steve Henson]
+
+ *) Fix flaw in SSL/TLS handshaking when using Kerberos ciphersuites
+ (CVE-2004-0112)
+ [Joe Orton, Steve Henson]
+
+ *) Make it possible to have multiple active certificates with the same
+ subject in the CA index file. This is done only if the keyword
+ 'unique_subject' is set to 'no' in the main CA section (default
+ if 'CA_default') of the configuration file. The value is saved
+ with the database itself in a separate index attribute file,
+ named like the index file with '.attr' appended to the name.
+ [Richard Levitte]
+
+ *) X509 verify fixes. Disable broken certificate workarounds when
+ X509_V_FLAGS_X509_STRICT is set. Check CRL issuer has cRLSign set if
+ keyUsage extension present. Don't accept CRLs with unhandled critical
+ extensions: since verify currently doesn't process CRL extensions this
+ rejects a CRL with *any* critical extensions. Add new verify error codes
+ for these cases.
+ [Steve Henson]
+
+ *) When creating an OCSP nonce use an OCTET STRING inside the extnValue.
+ A clarification of RFC2560 will require the use of OCTET STRINGs and
+ some implementations cannot handle the current raw format. Since OpenSSL
+ copies and compares OCSP nonces as opaque blobs without any attempt at
+ parsing them this should not create any compatibility issues.
+ [Steve Henson]
+
+ *) New md flag EVP_MD_CTX_FLAG_REUSE this allows md_data to be reused when
+ calling EVP_MD_CTX_copy_ex() to avoid calling OPENSSL_malloc(). Without
+ this HMAC (and other) operations are several times slower than OpenSSL
+ < 0.9.7.
+ [Steve Henson]
+
+ *) Print out GeneralizedTime and UTCTime in ASN1_STRING_print_ex().
+ [Peter Sylvester <Peter.Sylvester@EdelWeb.fr>]
+
+ *) Use the correct content when signing type "other".
+ [Steve Henson]
+
+ Changes between 0.9.7b and 0.9.7c [30 Sep 2003]
+
+ *) Fix various bugs revealed by running the NISCC test suite:
+
+ Stop out of bounds reads in the ASN1 code when presented with
+ invalid tags (CVE-2003-0543 and CVE-2003-0544).
+
+ Free up ASN1_TYPE correctly if ANY type is invalid (CVE-2003-0545).
+
+ If verify callback ignores invalid public key errors don't try to check
+ certificate signature with the NULL public key.
+
+ [Steve Henson]
+
+ *) New -ignore_err option in ocsp application to stop the server
+ exiting on the first error in a request.
+ [Steve Henson]
+
+ *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate
+ if the server requested one: as stated in TLS 1.0 and SSL 3.0
+ specifications.
+ [Steve Henson]
+
+ *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional
+ extra data after the compression methods not only for TLS 1.0
+ but also for SSL 3.0 (as required by the specification).
+ [Bodo Moeller; problem pointed out by Matthias Loepfe]
+
+ *) Change X509_certificate_type() to mark the key as exported/exportable
+ when it's 512 *bits* long, not 512 bytes.
+ [Richard Levitte]
+
+ *) Change AES_cbc_encrypt() so it outputs exact multiple of
+ blocks during encryption.
+ [Richard Levitte]
+
+ *) Various fixes to base64 BIO and non blocking I/O. On write
+ flushes were not handled properly if the BIO retried. On read
+ data was not being buffered properly and had various logic bugs.
+ This also affects blocking I/O when the data being decoded is a
+ certain size.
+ [Steve Henson]
+
+ *) Various S/MIME bugfixes and compatibility changes:
+ output correct application/pkcs7 MIME type if
+ PKCS7_NOOLDMIMETYPE is set. Tolerate some broken signatures.
+ Output CR+LF for EOL if PKCS7_CRLFEOL is set (this makes opening
+ of files as .eml work). Correctly handle very long lines in MIME
+ parser.
+ [Steve Henson]
+
+ Changes between 0.9.7a and 0.9.7b [10 Apr 2003]
+
+ *) Countermeasure against the Klima-Pokorny-Rosa extension of
+ Bleichbacher's attack on PKCS #1 v1.5 padding: treat
+ a protocol version number mismatch like a decryption error
+ in ssl3_get_client_key_exchange (ssl/s3_srvr.c).
+ [Bodo Moeller]
+
+ *) Turn on RSA blinding by default in the default implementation
+ to avoid a timing attack. Applications that don't want it can call
+ RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING.
+ They would be ill-advised to do so in most cases.
+ [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller]
+
+ *) Change RSA blinding code so that it works when the PRNG is not
+ seeded (in this case, the secret RSA exponent is abused as
+ an unpredictable seed -- if it is not unpredictable, there
+ is no point in blinding anyway). Make RSA blinding thread-safe
+ by remembering the creator's thread ID in rsa->blinding and
+ having all other threads use local one-time blinding factors
+ (this requires more computation than sharing rsa->blinding, but
+ avoids excessive locking; and if an RSA object is not shared
+ between threads, blinding will still be very fast).
+ [Bodo Moeller]
+
+ *) Fixed a typo bug that would cause ENGINE_set_default() to set an
+ ENGINE as defaults for all supported algorithms irrespective of
+ the 'flags' parameter. 'flags' is now honoured, so applications
+ should make sure they are passing it correctly.
+ [Geoff Thorpe]
+
+ *) Target "mingw" now allows native Windows code to be generated in
+ the Cygwin environment as well as with the MinGW compiler.
+ [Ulf Moeller]
+
+ Changes between 0.9.7 and 0.9.7a [19 Feb 2003]
+
+ *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked
+ via timing by performing a MAC computation even if incorrrect
+ block cipher padding has been found. This is a countermeasure
+ against active attacks where the attacker has to distinguish
+ between bad padding and a MAC verification error. (CVE-2003-0078)
+
+ [Bodo Moeller; problem pointed out by Brice Canvel (EPFL),
+ Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and
+ Martin Vuagnoux (EPFL, Ilion)]
+
+ *) Make the no-err option work as intended. The intention with no-err
+ is not to have the whole error stack handling routines removed from
+ libcrypto, it's only intended to remove all the function name and
+ reason texts, thereby removing some of the footprint that may not
+ be interesting if those errors aren't displayed anyway.
+
+ NOTE: it's still possible for any application or module to have it's
+ own set of error texts inserted. The routines are there, just not
+ used by default when no-err is given.
+ [Richard Levitte]
+
+ *) Add support for FreeBSD on IA64.
+ [dirk.meyer@dinoex.sub.org via Richard Levitte, resolves #454]
+
+ *) Adjust DES_cbc_cksum() so it returns the same value as the MIT
+ Kerberos function mit_des_cbc_cksum(). Before this change,
+ the value returned by DES_cbc_cksum() was like the one from
+ mit_des_cbc_cksum(), except the bytes were swapped.
+ [Kevin Greaney <Kevin.Greaney@hp.com> and Richard Levitte]
+
+ *) Allow an application to disable the automatic SSL chain building.
+ Before this a rather primitive chain build was always performed in
+ ssl3_output_cert_chain(): an application had no way to send the
+ correct chain if the automatic operation produced an incorrect result.
+
+ Now the chain builder is disabled if either:
+
+ 1. Extra certificates are added via SSL_CTX_add_extra_chain_cert().
+
+ 2. The mode flag SSL_MODE_NO_AUTO_CHAIN is set.
+
+ The reasoning behind this is that an application would not want the
+ auto chain building to take place if extra chain certificates are
+ present and it might also want a means of sending no additional
+ certificates (for example the chain has two certificates and the
+ root is omitted).
+ [Steve Henson]
+
+ *) Add the possibility to build without the ENGINE framework.
+ [Steven Reddie <smr@essemer.com.au> via Richard Levitte]
+
+ *) Under Win32 gmtime() can return NULL: check return value in
+ OPENSSL_gmtime(). Add error code for case where gmtime() fails.
+ [Steve Henson]
+
+ *) DSA routines: under certain error conditions uninitialized BN objects
+ could be freed. Solution: make sure initialization is performed early
+ enough. (Reported and fix supplied by Ivan D Nestlerode <nestler@MIT.EDU>,
+ Nils Larsch <nla@trustcenter.de> via PR#459)
+ [Lutz Jaenicke]
+
+ *) Another fix for SSLv2 session ID handling: the session ID was incorrectly
+ checked on reconnect on the client side, therefore session resumption
+ could still fail with a "ssl session id is different" error. This
+ behaviour is masked when SSL_OP_ALL is used due to
+ SSL_OP_MICROSOFT_SESS_ID_BUG being set.
+ Behaviour observed by Crispin Flowerday <crispin@flowerday.cx> as
+ followup to PR #377.
+ [Lutz Jaenicke]
+
+ *) IA-32 assembler support enhancements: unified ELF targets, support
+ for SCO/Caldera platforms, fix for Cygwin shared build.
+ [Andy Polyakov]
+
+ *) Add support for FreeBSD on sparc64. As a consequence, support for
+ FreeBSD on non-x86 processors is separate from x86 processors on
+ the config script, much like the NetBSD support.
+ [Richard Levitte & Kris Kennaway <kris@obsecurity.org>]
+
+ Changes between 0.9.6h and 0.9.7 [31 Dec 2002]
+
+ [NB: OpenSSL 0.9.6i and later 0.9.6 patch levels were released after
+ OpenSSL 0.9.7.]
+
+ *) Fix session ID handling in SSLv2 client code: the SERVER FINISHED
+ code (06) was taken as the first octet of the session ID and the last
+ octet was ignored consequently. As a result SSLv2 client side session
+ caching could not have worked due to the session ID mismatch between
+ client and server.
+ Behaviour observed by Crispin Flowerday <crispin@flowerday.cx> as
+ PR #377.
+ [Lutz Jaenicke]
+
+ *) Change the declaration of needed Kerberos libraries to use EX_LIBS
+ instead of the special (and badly supported) LIBKRB5. LIBKRB5 is
+ removed entirely.
+ [Richard Levitte]
+
+ *) The hw_ncipher.c engine requires dynamic locks. Unfortunately, it
+ seems that in spite of existing for more than a year, many application
+ author have done nothing to provide the necessary callbacks, which
+ means that this particular engine will not work properly anywhere.
+ This is a very unfortunate situation which forces us, in the name
+ of usability, to give the hw_ncipher.c a static lock, which is part
+ of libcrypto.
+ NOTE: This is for the 0.9.7 series ONLY. This hack will never
+ appear in 0.9.8 or later. We EXPECT application authors to have
+ dealt properly with this when 0.9.8 is released (unless we actually
+ make such changes in the libcrypto locking code that changes will
+ have to be made anyway).
+ [Richard Levitte]
+
+ *) In asn1_d2i_read_bio() repeatedly call BIO_read() until all content
+ octets have been read, EOF or an error occurs. Without this change
+ some truncated ASN1 structures will not produce an error.
+ [Steve Henson]
+
+ *) Disable Heimdal support, since it hasn't been fully implemented.
+ Still give the possibility to force the use of Heimdal, but with
+ warnings and a request that patches get sent to openssl-dev.
+ [Richard Levitte]
+
+ *) Add the VC-CE target, introduce the WINCE sysname, and add
+ INSTALL.WCE and appropriate conditionals to make it build.
+ [Steven Reddie <smr@essemer.com.au> via Richard Levitte]
+
+ *) Change the DLL names for Cygwin to cygcrypto-x.y.z.dll and
+ cygssl-x.y.z.dll, where x, y and z are the major, minor and
+ edit numbers of the version.
+ [Corinna Vinschen <vinschen@redhat.com> and Richard Levitte]
+
+ *) Introduce safe string copy and catenation functions
+ (BUF_strlcpy() and BUF_strlcat()).
+ [Ben Laurie (CHATS) and Richard Levitte]
+
+ *) Avoid using fixed-size buffers for one-line DNs.
+ [Ben Laurie (CHATS)]
+
+ *) Add BUF_MEM_grow_clean() to avoid information leakage when
+ resizing buffers containing secrets, and use where appropriate.
+ [Ben Laurie (CHATS)]
+
+ *) Avoid using fixed size buffers for configuration file location.
+ [Ben Laurie (CHATS)]
+
+ *) Avoid filename truncation for various CA files.
+ [Ben Laurie (CHATS)]
+
+ *) Use sizeof in preference to magic numbers.
+ [Ben Laurie (CHATS)]
+
+ *) Avoid filename truncation in cert requests.
+ [Ben Laurie (CHATS)]
+
+ *) Add assertions to check for (supposedly impossible) buffer
+ overflows.
+ [Ben Laurie (CHATS)]
+
+ *) Don't cache truncated DNS entries in the local cache (this could
+ potentially lead to a spoofing attack).
+ [Ben Laurie (CHATS)]
+
+ *) Fix various buffers to be large enough for hex/decimal
+ representations in a platform independent manner.
+ [Ben Laurie (CHATS)]
+
+ *) Add CRYPTO_realloc_clean() to avoid information leakage when
+ resizing buffers containing secrets, and use where appropriate.
+ [Ben Laurie (CHATS)]
+
+ *) Add BIO_indent() to avoid much slightly worrying code to do
+ indents.
+ [Ben Laurie (CHATS)]
+
+ *) Convert sprintf()/BIO_puts() to BIO_printf().
+ [Ben Laurie (CHATS)]
+
+ *) buffer_gets() could terminate with the buffer only half
+ full. Fixed.
+ [Ben Laurie (CHATS)]
+
+ *) Add assertions to prevent user-supplied crypto functions from
+ overflowing internal buffers by having large block sizes, etc.
+ [Ben Laurie (CHATS)]
+
+ *) New OPENSSL_assert() macro (similar to assert(), but enabled
+ unconditionally).
+ [Ben Laurie (CHATS)]
+
+ *) Eliminate unused copy of key in RC4.
+ [Ben Laurie (CHATS)]
+
+ *) Eliminate unused and incorrectly sized buffers for IV in pem.h.
+ [Ben Laurie (CHATS)]
+
+ *) Fix off-by-one error in EGD path.
+ [Ben Laurie (CHATS)]
+
+ *) If RANDFILE path is too long, ignore instead of truncating.
+ [Ben Laurie (CHATS)]
+
+ *) Eliminate unused and incorrectly sized X.509 structure
+ CBCParameter.
+ [Ben Laurie (CHATS)]
+
+ *) Eliminate unused and dangerous function knumber().
+ [Ben Laurie (CHATS)]
+
+ *) Eliminate unused and dangerous structure, KSSL_ERR.
+ [Ben Laurie (CHATS)]
+
+ *) Protect against overlong session ID context length in an encoded
+ session object. Since these are local, this does not appear to be
+ exploitable.
+ [Ben Laurie (CHATS)]
+
+ *) Change from security patch (see 0.9.6e below) that did not affect
+ the 0.9.6 release series:
+
+ Remote buffer overflow in SSL3 protocol - an attacker could
+ supply an oversized master key in Kerberos-enabled versions.
+ (CVE-2002-0657)
+ [Ben Laurie (CHATS)]
+
+ *) Change the SSL kerb5 codes to match RFC 2712.
+ [Richard Levitte]
+
+ *) Make -nameopt work fully for req and add -reqopt switch.
+ [Michael Bell <michael.bell@rz.hu-berlin.de>, Steve Henson]
+
+ *) The "block size" for block ciphers in CFB and OFB mode should be 1.
+ [Steve Henson, reported by Yngve Nysaeter Pettersen <yngve@opera.com>]
+
+ *) Make sure tests can be performed even if the corresponding algorithms
+ have been removed entirely. This was also the last step to make
+ OpenSSL compilable with DJGPP under all reasonable conditions.
+ [Richard Levitte, Doug Kaufman <dkaufman@rahul.net>]
+
+ *) Add cipher selection rules COMPLEMENTOFALL and COMPLEMENTOFDEFAULT
+ to allow version independent disabling of normally unselected ciphers,
+ which may be activated as a side-effect of selecting a single cipher.
+
+ (E.g., cipher list string "RSA" enables ciphersuites that are left
+ out of "ALL" because they do not provide symmetric encryption.
+ "RSA:!COMPLEMEMENTOFALL" avoids these unsafe ciphersuites.)
+ [Lutz Jaenicke, Bodo Moeller]
+
+ *) Add appropriate support for separate platform-dependent build
+ directories. The recommended way to make a platform-dependent
+ build directory is the following (tested on Linux), maybe with
+ some local tweaks:
+
+ # Place yourself outside of the OpenSSL source tree. In
+ # this example, the environment variable OPENSSL_SOURCE
+ # is assumed to contain the absolute OpenSSL source directory.
+ mkdir -p objtree/"`uname -s`-`uname -r`-`uname -m`"
+ cd objtree/"`uname -s`-`uname -r`-`uname -m`"
+ (cd $OPENSSL_SOURCE; find . -type f) | while read F; do
+ mkdir -p `dirname $F`
+ ln -s $OPENSSL_SOURCE/$F $F
+ done
+
+ To be absolutely sure not to disturb the source tree, a "make clean"
+ is a good thing. If it isn't successfull, don't worry about it,
+ it probably means the source directory is very clean.
+ [Richard Levitte]
+
+ *) Make sure any ENGINE control commands make local copies of string
+ pointers passed to them whenever necessary. Otherwise it is possible
+ the caller may have overwritten (or deallocated) the original string
+ data when a later ENGINE operation tries to use the stored values.
+ [Götz Babin-Ebell <babinebell@trustcenter.de>]
+
+ *) Improve diagnostics in file reading and command-line digests.
+ [Ben Laurie aided and abetted by Solar Designer <solar@openwall.com>]
+
+ *) Add AES modes CFB and OFB to the object database. Correct an
+ error in AES-CFB decryption.
+ [Richard Levitte]
+
+ *) Remove most calls to EVP_CIPHER_CTX_cleanup() in evp_enc.c, this
+ allows existing EVP_CIPHER_CTX structures to be reused after
+ calling EVP_*Final(). This behaviour is used by encryption
+ BIOs and some applications. This has the side effect that
+ applications must explicitly clean up cipher contexts with
+ EVP_CIPHER_CTX_cleanup() or they will leak memory.
+ [Steve Henson]
+
+ *) Check the values of dna and dnb in bn_mul_recursive before calling
+ bn_mul_comba (a non zero value means the a or b arrays do not contain
+ n2 elements) and fallback to bn_mul_normal if either is not zero.
+ [Steve Henson]
+
+ *) Fix escaping of non-ASCII characters when using the -subj option
+ of the "openssl req" command line tool. (Robert Joop <joop@fokus.gmd.de>)
+ [Lutz Jaenicke]
+
+ *) Make object definitions compliant to LDAP (RFC2256): SN is the short
+ form for "surname", serialNumber has no short form.
+ Use "mail" as the short name for "rfc822Mailbox" according to RFC2798;
+ therefore remove "mail" short name for "internet 7".
+ The OID for unique identifiers in X509 certificates is
+ x500UniqueIdentifier, not uniqueIdentifier.
+ Some more OID additions. (Michael Bell <michael.bell@rz.hu-berlin.de>)
+ [Lutz Jaenicke]
+
+ *) Add an "init" command to the ENGINE config module and auto initialize
+ ENGINEs. Without any "init" command the ENGINE will be initialized
+ after all ctrl commands have been executed on it. If init=1 the
+ ENGINE is initailized at that point (ctrls before that point are run
+ on the uninitialized ENGINE and after on the initialized one). If
+ init=0 then the ENGINE will not be iniatialized at all.
+ [Steve Henson]
+
+ *) Fix the 'app_verify_callback' interface so that the user-defined
+ argument is actually passed to the callback: In the
+ SSL_CTX_set_cert_verify_callback() prototype, the callback
+ declaration has been changed from
+ int (*cb)()
+ into
+ int (*cb)(X509_STORE_CTX *,void *);
+ in ssl_verify_cert_chain (ssl/ssl_cert.c), the call
+ i=s->ctx->app_verify_callback(&ctx)
+ has been changed into
+ i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg).
+
+ To update applications using SSL_CTX_set_cert_verify_callback(),
+ a dummy argument can be added to their callback functions.
+ [D. K. Smetters <smetters@parc.xerox.com>]
+
+ *) Added the '4758cca' ENGINE to support IBM 4758 cards.
+ [Maurice Gittens <maurice@gittens.nl>, touchups by Geoff Thorpe]
+
+ *) Add and OPENSSL_LOAD_CONF define which will cause
+ OpenSSL_add_all_algorithms() to load the openssl.cnf config file.
+ This allows older applications to transparently support certain
+ OpenSSL features: such as crypto acceleration and dynamic ENGINE loading.
+ Two new functions OPENSSL_add_all_algorithms_noconf() which will never
+ load the config file and OPENSSL_add_all_algorithms_conf() which will
+ always load it have also been added.
+ [Steve Henson]
+
+ *) Add the OFB, CFB and CTR (all with 128 bit feedback) to AES.
+ Adjust NIDs and EVP layer.
+ [Stephen Sprunk <stephen@sprunk.org> and Richard Levitte]
+
+ *) Config modules support in openssl utility.
+
+ Most commands now load modules from the config file,
+ though in a few (such as version) this isn't done
+ because it couldn't be used for anything.
+
+ In the case of ca and req the config file used is
+ the same as the utility itself: that is the -config
+ command line option can be used to specify an
+ alternative file.
+ [Steve Henson]
+
+ *) Move default behaviour from OPENSSL_config(). If appname is NULL
+ use "openssl_conf" if filename is NULL use default openssl config file.
+ [Steve Henson]
+
+ *) Add an argument to OPENSSL_config() to allow the use of an alternative
+ config section name. Add a new flag to tolerate a missing config file
+ and move code to CONF_modules_load_file().
+ [Steve Henson]
+
+ *) Support for crypto accelerator cards from Accelerated Encryption
+ Processing, www.aep.ie. (Use engine 'aep')
+ The support was copied from 0.9.6c [engine] and adapted/corrected
+ to work with the new engine framework.
+ [AEP Inc. and Richard Levitte]
+
+ *) Support for SureWare crypto accelerator cards from Baltimore
+ Technologies. (Use engine 'sureware')
+ The support was copied from 0.9.6c [engine] and adapted
+ to work with the new engine framework.
+ [Richard Levitte]
+
+ *) Have the CHIL engine fork-safe (as defined by nCipher) and actually
+ make the newer ENGINE framework commands for the CHIL engine work.
+ [Toomas Kiisk <vix@cyber.ee> and Richard Levitte]
+
+ *) Make it possible to produce shared libraries on ReliantUNIX.
+ [Robert Dahlem <Robert.Dahlem@ffm2.siemens.de> via Richard Levitte]
+
+ *) Add the configuration target debug-linux-ppro.
+ Make 'openssl rsa' use the general key loading routines
+ implemented in apps.c, and make those routines able to
+ handle the key format FORMAT_NETSCAPE and the variant
+ FORMAT_IISSGC.
+ [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
+
+ *) Fix a crashbug and a logic bug in hwcrhk_load_pubkey().
+ [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
+
+ *) Add -keyform to rsautl, and document -engine.
+ [Richard Levitte, inspired by Toomas Kiisk <vix@cyber.ee>]
+
+ *) Change BIO_new_file (crypto/bio/bss_file.c) to use new
+ BIO_R_NO_SUCH_FILE error code rather than the generic
+ ERR_R_SYS_LIB error code if fopen() fails with ENOENT.
+ [Ben Laurie]
+
+ *) Add new functions
+ ERR_peek_last_error
+ ERR_peek_last_error_line
+ ERR_peek_last_error_line_data.
+ These are similar to
+ ERR_peek_error
+ ERR_peek_error_line
+ ERR_peek_error_line_data,
+ but report on the latest error recorded rather than the first one
+ still in the error queue.
+ [Ben Laurie, Bodo Moeller]
+
+ *) default_algorithms option in ENGINE config module. This allows things
+ like:
+ default_algorithms = ALL
+ default_algorithms = RSA, DSA, RAND, CIPHERS, DIGESTS
+ [Steve Henson]
+
+ *) Prelminary ENGINE config module.
+ [Steve Henson]
+
+ *) New experimental application configuration code.
+ [Steve Henson]
+
+ *) Change the AES code to follow the same name structure as all other
+ symmetric ciphers, and behave the same way. Move everything to
+ the directory crypto/aes, thereby obsoleting crypto/rijndael.
+ [Stephen Sprunk <stephen@sprunk.org> and Richard Levitte]
+
+ *) SECURITY: remove unsafe setjmp/signal interaction from ui_openssl.c.
+ [Ben Laurie and Theo de Raadt]
+
+ *) Add option to output public keys in req command.
+ [Massimiliano Pala madwolf@openca.org]
+
+ *) Use wNAFs in EC_POINTs_mul() for improved efficiency
+ (up to about 10% better than before for P-192 and P-224).
+ [Bodo Moeller]
+
+ *) New functions/macros
+
+ SSL_CTX_set_msg_callback(ctx, cb)
+ SSL_CTX_set_msg_callback_arg(ctx, arg)
+ SSL_set_msg_callback(ssl, cb)
+ SSL_set_msg_callback_arg(ssl, arg)
+
+ to request calling a callback function
+
+ void cb(int write_p, int version, int content_type,
+ const void *buf, size_t len, SSL *ssl, void *arg)
+
+ whenever a protocol message has been completely received
+ (write_p == 0) or sent (write_p == 1). Here 'version' is the
+ protocol version according to which the SSL library interprets
+ the current protocol message (SSL2_VERSION, SSL3_VERSION, or
+ TLS1_VERSION). 'content_type' is 0 in the case of SSL 2.0, or
+ the content type as defined in the SSL 3.0/TLS 1.0 protocol
+ specification (change_cipher_spec(20), alert(21), handshake(22)).
+ 'buf' and 'len' point to the actual message, 'ssl' to the
+ SSL object, and 'arg' is the application-defined value set by
+ SSL[_CTX]_set_msg_callback_arg().
+
+ 'openssl s_client' and 'openssl s_server' have new '-msg' options
+ to enable a callback that displays all protocol messages.
+ [Bodo Moeller]
+
+ *) Change the shared library support so shared libraries are built as
+ soon as the corresponding static library is finished, and thereby get
+ openssl and the test programs linked against the shared library.
+ This still only happens when the keyword "shard" has been given to
+ the configuration scripts.
+
+ NOTE: shared library support is still an experimental thing, and
+ backward binary compatibility is still not guaranteed.
+ ["Maciej W. Rozycki" <macro@ds2.pg.gda.pl> and Richard Levitte]
+
+ *) Add support for Subject Information Access extension.
+ [Peter Sylvester <Peter.Sylvester@EdelWeb.fr>]
+
+ *) Make BUF_MEM_grow() behaviour more consistent: Initialise to zero
+ additional bytes when new memory had to be allocated, not just
+ when reusing an existing buffer.
+ [Bodo Moeller]
+
+ *) New command line and configuration option 'utf8' for the req command.
+ This allows field values to be specified as UTF8 strings.
+ [Steve Henson]
+
+ *) Add -multi and -mr options to "openssl speed" - giving multiple parallel
+ runs for the former and machine-readable output for the latter.
+ [Ben Laurie]
+
+ *) Add '-noemailDN' option to 'openssl ca'. This prevents inclusion
+ of the e-mail address in the DN (i.e., it will go into a certificate
+ extension only). The new configuration file option 'email_in_dn = no'
+ has the same effect.
+ [Massimiliano Pala madwolf@openca.org]
+
+ *) Change all functions with names starting with des_ to be starting
+ with DES_ instead. Add wrappers that are compatible with libdes,
+ but are named _ossl_old_des_*. Finally, add macros that map the
+ des_* symbols to the corresponding _ossl_old_des_* if libdes
+ compatibility is desired. If OpenSSL 0.9.6c compatibility is
+ desired, the des_* symbols will be mapped to DES_*, with one
+ exception.
+
+ Since we provide two compatibility mappings, the user needs to
+ define the macro OPENSSL_DES_LIBDES_COMPATIBILITY if libdes
+ compatibility is desired. The default (i.e., when that macro
+ isn't defined) is OpenSSL 0.9.6c compatibility.
+
+ There are also macros that enable and disable the support of old
+ des functions altogether. Those are OPENSSL_ENABLE_OLD_DES_SUPPORT
+ and OPENSSL_DISABLE_OLD_DES_SUPPORT. If none or both of those
+ are defined, the default will apply: to support the old des routines.
+
+ In either case, one must include openssl/des.h to get the correct
+ definitions. Do not try to just include openssl/des_old.h, that
+ won't work.
+
+ NOTE: This is a major break of an old API into a new one. Software
+ authors are encouraged to switch to the DES_ style functions. Some
+ time in the future, des_old.h and the libdes compatibility functions
+ will be disable (i.e. OPENSSL_DISABLE_OLD_DES_SUPPORT will be the
+ default), and then completely removed.
+ [Richard Levitte]
+
+ *) Test for certificates which contain unsupported critical extensions.
+ If such a certificate is found during a verify operation it is
+ rejected by default: this behaviour can be overridden by either
+ handling the new error X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION or
+ by setting the verify flag X509_V_FLAG_IGNORE_CRITICAL. A new function
+ X509_supported_extension() has also been added which returns 1 if a
+ particular extension is supported.
+ [Steve Henson]
+
+ *) Modify the behaviour of EVP cipher functions in similar way to digests
+ to retain compatibility with existing code.
+ [Steve Henson]
+
+ *) Modify the behaviour of EVP_DigestInit() and EVP_DigestFinal() to retain
+ compatibility with existing code. In particular the 'ctx' parameter does
+ not have to be to be initialized before the call to EVP_DigestInit() and
+ it is tidied up after a call to EVP_DigestFinal(). New function
+ EVP_DigestFinal_ex() which does not tidy up the ctx. Similarly function
+ EVP_MD_CTX_copy() changed to not require the destination to be
+ initialized valid and new function EVP_MD_CTX_copy_ex() added which
+ requires the destination to be valid.
+
+ Modify all the OpenSSL digest calls to use EVP_DigestInit_ex(),
+ EVP_DigestFinal_ex() and EVP_MD_CTX_copy_ex().
+ [Steve Henson]
+
+ *) Change ssl3_get_message (ssl/s3_both.c) and the functions using it
+ so that complete 'Handshake' protocol structures are kept in memory
+ instead of overwriting 'msg_type' and 'length' with 'body' data.
+ [Bodo Moeller]
+
+ *) Add an implementation of SSL_add_dir_cert_subjects_to_stack for Win32.
+ [Massimo Santin via Richard Levitte]
+
+ *) Major restructuring to the underlying ENGINE code. This includes
+ reduction of linker bloat, separation of pure "ENGINE" manipulation
+ (initialisation, etc) from functionality dealing with implementations
+ of specific crypto iterfaces. This change also introduces integrated
+ support for symmetric ciphers and digest implementations - so ENGINEs
+ can now accelerate these by providing EVP_CIPHER and EVP_MD
+ implementations of their own. This is detailed in crypto/engine/README
+ as it couldn't be adequately described here. However, there are a few
+ API changes worth noting - some RSA, DSA, DH, and RAND functions that
+ were changed in the original introduction of ENGINE code have now
+ reverted back - the hooking from this code to ENGINE is now a good
+ deal more passive and at run-time, operations deal directly with
+ RSA_METHODs, DSA_METHODs (etc) as they did before, rather than
+ dereferencing through an ENGINE pointer any more. Also, the ENGINE
+ functions dealing with BN_MOD_EXP[_CRT] handlers have been removed -
+ they were not being used by the framework as there is no concept of a
+ BIGNUM_METHOD and they could not be generalised to the new
+ 'ENGINE_TABLE' mechanism that underlies the new code. Similarly,
+ ENGINE_cpy() has been removed as it cannot be consistently defined in
+ the new code.
+ [Geoff Thorpe]
+
+ *) Change ASN1_GENERALIZEDTIME_check() to allow fractional seconds.
+ [Steve Henson]
+
+ *) Change mkdef.pl to sort symbols that get the same entry number,
+ and make sure the automatically generated functions ERR_load_*
+ become part of libeay.num as well.
+ [Richard Levitte]
+
+ *) New function SSL_renegotiate_pending(). This returns true once
+ renegotiation has been requested (either SSL_renegotiate() call
+ or HelloRequest/ClientHello receveived from the peer) and becomes
+ false once a handshake has been completed.
+ (For servers, SSL_renegotiate() followed by SSL_do_handshake()
+ sends a HelloRequest, but does not ensure that a handshake takes
+ place. SSL_renegotiate_pending() is useful for checking if the
+ client has followed the request.)
+ [Bodo Moeller]
+
+ *) New SSL option SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION.
+ By default, clients may request session resumption even during
+ renegotiation (if session ID contexts permit); with this option,
+ session resumption is possible only in the first handshake.
+
+ SSL_OP_ALL is now 0x00000FFFL instead of 0x000FFFFFL. This makes
+ more bits available for options that should not be part of
+ SSL_OP_ALL (such as SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION).
+ [Bodo Moeller]
+
+ *) Add some demos for certificate and certificate request creation.
+ [Steve Henson]
+
+ *) Make maximum certificate chain size accepted from the peer application
+ settable (SSL*_get/set_max_cert_list()), as proposed by
+ "Douglas E. Engert" <deengert@anl.gov>.
+ [Lutz Jaenicke]
+
+ *) Add support for shared libraries for Unixware-7
+ (Boyd Lynn Gerber <gerberb@zenez.com>).
+ [Lutz Jaenicke]
+
+ *) Add a "destroy" handler to ENGINEs that allows structural cleanup to
+ be done prior to destruction. Use this to unload error strings from
+ ENGINEs that load their own error strings. NB: This adds two new API
+ functions to "get" and "set" this destroy handler in an ENGINE.
+ [Geoff Thorpe]
+
+ *) Alter all existing ENGINE implementations (except "openssl" and
+ "openbsd") to dynamically instantiate their own error strings. This
+ makes them more flexible to be built both as statically-linked ENGINEs
+ and self-contained shared-libraries loadable via the "dynamic" ENGINE.
+ Also, add stub code to each that makes building them as self-contained
+ shared-libraries easier (see README.ENGINE).
+ [Geoff Thorpe]
+
+ *) Add a "dynamic" ENGINE that provides a mechanism for binding ENGINE
+ implementations into applications that are completely implemented in
+ self-contained shared-libraries. The "dynamic" ENGINE exposes control
+ commands that can be used to configure what shared-library to load and
+ to control aspects of the way it is handled. Also, made an update to
+ the README.ENGINE file that brings its information up-to-date and
+ provides some information and instructions on the "dynamic" ENGINE
+ (ie. how to use it, how to build "dynamic"-loadable ENGINEs, etc).
+ [Geoff Thorpe]
+
+ *) Make it possible to unload ranges of ERR strings with a new
+ "ERR_unload_strings" function.
+ [Geoff Thorpe]
+
+ *) Add a copy() function to EVP_MD.
+ [Ben Laurie]
+
+ *) Make EVP_MD routines take a context pointer instead of just the
+ md_data void pointer.
+ [Ben Laurie]
+
+ *) Add flags to EVP_MD and EVP_MD_CTX. EVP_MD_FLAG_ONESHOT indicates
+ that the digest can only process a single chunk of data
+ (typically because it is provided by a piece of
+ hardware). EVP_MD_CTX_FLAG_ONESHOT indicates that the application
+ is only going to provide a single chunk of data, and hence the
+ framework needn't accumulate the data for oneshot drivers.
+ [Ben Laurie]
+
+ *) As with "ERR", make it possible to replace the underlying "ex_data"
+ functions. This change also alters the storage and management of global
+ ex_data state - it's now all inside ex_data.c and all "class" code (eg.
+ RSA, BIO, SSL_CTX, etc) no longer stores its own STACKS and per-class
+ index counters. The API functions that use this state have been changed
+ to take a "class_index" rather than pointers to the class's local STACK
+ and counter, and there is now an API function to dynamically create new
+ classes. This centralisation allows us to (a) plug a lot of the
+ thread-safety problems that existed, and (b) makes it possible to clean
+ up all allocated state using "CRYPTO_cleanup_all_ex_data()". W.r.t. (b)
+ such data would previously have always leaked in application code and
+ workarounds were in place to make the memory debugging turn a blind eye
+ to it. Application code that doesn't use this new function will still
+ leak as before, but their memory debugging output will announce it now
+ rather than letting it slide.
+
+ Besides the addition of CRYPTO_cleanup_all_ex_data(), another API change
+ induced by the "ex_data" overhaul is that X509_STORE_CTX_init() now
+ has a return value to indicate success or failure.
+ [Geoff Thorpe]
+
+ *) Make it possible to replace the underlying "ERR" functions such that the
+ global state (2 LHASH tables and 2 locks) is only used by the "default"
+ implementation. This change also adds two functions to "get" and "set"
+ the implementation prior to it being automatically set the first time
+ any other ERR function takes place. Ie. an application can call "get",
+ pass the return value to a module it has just loaded, and that module
+ can call its own "set" function using that value. This means the
+ module's "ERR" operations will use (and modify) the error state in the
+ application and not in its own statically linked copy of OpenSSL code.
+ [Geoff Thorpe]
+
+ *) Give DH, DSA, and RSA types their own "**_up_ref()" function to increment
+ reference counts. This performs normal REF_PRINT/REF_CHECK macros on
+ the operation, and provides a more encapsulated way for external code
+ (crypto/evp/ and ssl/) to do this. Also changed the evp and ssl code
+ to use these functions rather than manually incrementing the counts.
+
+ Also rename "DSO_up()" function to more descriptive "DSO_up_ref()".
+ [Geoff Thorpe]
+
+ *) Add EVP test program.
+ [Ben Laurie]
+
+ *) Add symmetric cipher support to ENGINE. Expect the API to change!
+ [Ben Laurie]
+
+ *) New CRL functions: X509_CRL_set_version(), X509_CRL_set_issuer_name()
+ X509_CRL_set_lastUpdate(), X509_CRL_set_nextUpdate(), X509_CRL_sort(),
+ X509_REVOKED_set_serialNumber(), and X509_REVOKED_set_revocationDate().
+ These allow a CRL to be built without having to access X509_CRL fields
+ directly. Modify 'ca' application to use new functions.
+ [Steve Henson]
+
+ *) Move SSL_OP_TLS_ROLLBACK_BUG out of the SSL_OP_ALL list of recommended
+ bug workarounds. Rollback attack detection is a security feature.
+ The problem will only arise on OpenSSL servers when TLSv1 is not
+ available (sslv3_server_method() or SSL_OP_NO_TLSv1).
+ Software authors not wanting to support TLSv1 will have special reasons
+ for their choice and can explicitly enable this option.
+ [Bodo Moeller, Lutz Jaenicke]
+
+ *) Rationalise EVP so it can be extended: don't include a union of
+ cipher/digest structures, add init/cleanup functions for EVP_MD_CTX
+ (similar to those existing for EVP_CIPHER_CTX).
+ Usage example:
+
+ EVP_MD_CTX md;
+
+ EVP_MD_CTX_init(&md); /* new function call */
+ EVP_DigestInit(&md, EVP_sha1());
+ EVP_DigestUpdate(&md, in, len);
+ EVP_DigestFinal(&md, out, NULL);
+ EVP_MD_CTX_cleanup(&md); /* new function call */
+
+ [Ben Laurie]
+
+ *) Make DES key schedule conform to the usual scheme, as well as
+ correcting its structure. This means that calls to DES functions
+ now have to pass a pointer to a des_key_schedule instead of a
+ plain des_key_schedule (which was actually always a pointer
+ anyway): E.g.,
+
+ des_key_schedule ks;
+
+ des_set_key_checked(..., &ks);
+ des_ncbc_encrypt(..., &ks, ...);
+
+ (Note that a later change renames 'des_...' into 'DES_...'.)
+ [Ben Laurie]
+
+ *) Initial reduction of linker bloat: the use of some functions, such as
+ PEM causes large amounts of unused functions to be linked in due to
+ poor organisation. For example pem_all.c contains every PEM function
+ which has a knock on effect of linking in large amounts of (unused)
+ ASN1 code. Grouping together similar functions and splitting unrelated
+ functions prevents this.
+ [Steve Henson]
+
+ *) Cleanup of EVP macros.
+ [Ben Laurie]
+
+ *) Change historical references to {NID,SN,LN}_des_ede and ede3 to add the
+ correct _ecb suffix.
+ [Ben Laurie]
+
+ *) Add initial OCSP responder support to ocsp application. The
+ revocation information is handled using the text based index
+ use by the ca application. The responder can either handle
+ requests generated internally, supplied in files (for example
+ via a CGI script) or using an internal minimal server.
+ [Steve Henson]
+
+ *) Add configuration choices to get zlib compression for TLS.
+ [Richard Levitte]
+
+ *) Changes to Kerberos SSL for RFC 2712 compliance:
+ 1. Implemented real KerberosWrapper, instead of just using
+ KRB5 AP_REQ message. [Thanks to Simon Wilkinson <sxw@sxw.org.uk>]
+ 2. Implemented optional authenticator field of KerberosWrapper.
+
+ Added openssl-style ASN.1 macros for Kerberos ticket, ap_req,
+ and authenticator structs; see crypto/krb5/.
+
+ Generalized Kerberos calls to support multiple Kerberos libraries.
+ [Vern Staats <staatsvr@asc.hpc.mil>,
+ Jeffrey Altman <jaltman@columbia.edu>
+ via Richard Levitte]
+
+ *) Cause 'openssl speed' to use fully hard-coded DSA keys as it
+ already does with RSA. testdsa.h now has 'priv_key/pub_key'
+ values for each of the key sizes rather than having just
+ parameters (and 'speed' generating keys each time).
+ [Geoff Thorpe]
+
+ *) Speed up EVP routines.
+ Before:
+encrypt
+type 8 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
+des-cbc 4408.85k 5560.51k 5778.46k 5862.20k 5825.16k
+des-cbc 4389.55k 5571.17k 5792.23k 5846.91k 5832.11k
+des-cbc 4394.32k 5575.92k 5807.44k 5848.37k 5841.30k
+decrypt
+des-cbc 3482.66k 5069.49k 5496.39k 5614.16k 5639.28k
+des-cbc 3480.74k 5068.76k 5510.34k 5609.87k 5635.52k
+des-cbc 3483.72k 5067.62k 5504.60k 5708.01k 5724.80k
+ After:
+encrypt
+des-cbc 4660.16k 5650.19k 5807.19k 5827.13k 5783.32k
+decrypt
+des-cbc 3624.96k 5258.21k 5530.91k 5624.30k 5628.26k
+ [Ben Laurie]
+
+ *) Added the OS2-EMX target.
+ ["Brian Havard" <brianh@kheldar.apana.org.au> and Richard Levitte]
+
+ *) Rewrite apps to use NCONF routines instead of the old CONF. New functions
+ to support NCONF routines in extension code. New function CONF_set_nconf()
+ to allow functions which take an NCONF to also handle the old LHASH
+ structure: this means that the old CONF compatible routines can be
+ retained (in particular wrt extensions) without having to duplicate the
+ code. New function X509V3_add_ext_nconf_sk to add extensions to a stack.
+ [Steve Henson]
+
+ *) Enhance the general user interface with mechanisms for inner control
+ and with possibilities to have yes/no kind of prompts.
+ [Richard Levitte]
+
+ *) Change all calls to low level digest routines in the library and
+ applications to use EVP. Add missing calls to HMAC_cleanup() and
+ don't assume HMAC_CTX can be copied using memcpy().
+ [Verdon Walker <VWalker@novell.com>, Steve Henson]
+
+ *) Add the possibility to control engines through control names but with
+ arbitrary arguments instead of just a string.
+ Change the key loaders to take a UI_METHOD instead of a callback
+ function pointer. NOTE: this breaks binary compatibility with earlier
+ versions of OpenSSL [engine].
+ Adapt the nCipher code for these new conditions and add a card insertion
+ callback.
+ [Richard Levitte]
+
+ *) Enhance the general user interface with mechanisms to better support
+ dialog box interfaces, application-defined prompts, the possibility
+ to use defaults (for example default passwords from somewhere else)
+ and interrupts/cancellations.
+ [Richard Levitte]
+
+ *) Tidy up PKCS#12 attribute handling. Add support for the CSP name
+ attribute in PKCS#12 files, add new -CSP option to pkcs12 utility.
+ [Steve Henson]
+
+ *) Fix a memory leak in 'sk_dup()' in the case reallocation fails. (Also
+ tidy up some unnecessarily weird code in 'sk_new()').
+ [Geoff, reported by Diego Tartara <dtartara@novamens.com>]
+
+ *) Change the key loading routines for ENGINEs to use the same kind
+ callback (pem_password_cb) as all other routines that need this
+ kind of callback.
+ [Richard Levitte]
+
+ *) Increase ENTROPY_NEEDED to 32 bytes, as Rijndael can operate with
+ 256 bit (=32 byte) keys. Of course seeding with more entropy bytes
+ than this minimum value is recommended.
+ [Lutz Jaenicke]
+
+ *) New random seeder for OpenVMS, using the system process statistics
+ that are easily reachable.
+ [Richard Levitte]
+
+ *) Windows apparently can't transparently handle global
+ variables defined in DLLs. Initialisations such as:
+
+ const ASN1_ITEM *it = &ASN1_INTEGER_it;
+
+ wont compile. This is used by the any applications that need to
+ declare their own ASN1 modules. This was fixed by adding the option
+ EXPORT_VAR_AS_FN to all Win32 platforms, although this isn't strictly
+ needed for static libraries under Win32.
+ [Steve Henson]
+
+ *) New functions X509_PURPOSE_set() and X509_TRUST_set() to handle
+ setting of purpose and trust fields. New X509_STORE trust and
+ purpose functions and tidy up setting in other SSL functions.
+ [Steve Henson]
+
+ *) Add copies of X509_STORE_CTX fields and callbacks to X509_STORE
+ structure. These are inherited by X509_STORE_CTX when it is
+ initialised. This allows various defaults to be set in the
+ X509_STORE structure (such as flags for CRL checking and custom
+ purpose or trust settings) for functions which only use X509_STORE_CTX
+ internally such as S/MIME.
+
+ Modify X509_STORE_CTX_purpose_inherit() so it only sets purposes and
+ trust settings if they are not set in X509_STORE. This allows X509_STORE
+ purposes and trust (in S/MIME for example) to override any set by default.
+
+ Add command line options for CRL checking to smime, s_client and s_server
+ applications.
+ [Steve Henson]
+
+ *) Initial CRL based revocation checking. If the CRL checking flag(s)
+ are set then the CRL is looked up in the X509_STORE structure and
+ its validity and signature checked, then if the certificate is found
+ in the CRL the verify fails with a revoked error.
+
+ Various new CRL related callbacks added to X509_STORE_CTX structure.
+
+ Command line options added to 'verify' application to support this.
+
+ This needs some additional work, such as being able to handle multiple
+ CRLs with different times, extension based lookup (rather than just
+ by subject name) and ultimately more complete V2 CRL extension
+ handling.
+ [Steve Henson]
+
+ *) Add a general user interface API (crypto/ui/). This is designed
+ to replace things like des_read_password and friends (backward
+ compatibility functions using this new API are provided).
+ The purpose is to remove prompting functions from the DES code
+ section as well as provide for prompting through dialog boxes in
+ a window system and the like.
+ [Richard Levitte]
+
+ *) Add "ex_data" support to ENGINE so implementations can add state at a
+ per-structure level rather than having to store it globally.
+ [Geoff]
+
+ *) Make it possible for ENGINE structures to be copied when retrieved by
+ ENGINE_by_id() if the ENGINE specifies a new flag: ENGINE_FLAGS_BY_ID_COPY.
+ This causes the "original" ENGINE structure to act like a template,
+ analogous to the RSA vs. RSA_METHOD type of separation. Because of this
+ operational state can be localised to each ENGINE structure, despite the
+ fact they all share the same "methods". New ENGINE structures returned in
+ this case have no functional references and the return value is the single
+ structural reference. This matches the single structural reference returned
+ by ENGINE_by_id() normally, when it is incremented on the pre-existing
+ ENGINE structure.
+ [Geoff]
+
+ *) Fix ASN1 decoder when decoding type ANY and V_ASN1_OTHER: since this
+ needs to match any other type at all we need to manually clear the
+ tag cache.
+ [Steve Henson]
+
+ *) Changes to the "openssl engine" utility to include;
+ - verbosity levels ('-v', '-vv', and '-vvv') that provide information
+ about an ENGINE's available control commands.
+ - executing control commands from command line arguments using the
+ '-pre' and '-post' switches. '-post' is only used if '-t' is
+ specified and the ENGINE is successfully initialised. The syntax for
+ the individual commands are colon-separated, for example;
+ openssl engine chil -pre FORK_CHECK:0 -pre SO_PATH:/lib/test.so
+ [Geoff]
+
+ *) New dynamic control command support for ENGINEs. ENGINEs can now
+ declare their own commands (numbers), names (strings), descriptions,
+ and input types for run-time discovery by calling applications. A
+ subset of these commands are implicitly classed as "executable"
+ depending on their input type, and only these can be invoked through
+ the new string-based API function ENGINE_ctrl_cmd_string(). (Eg. this
+ can be based on user input, config files, etc). The distinction is
+ that "executable" commands cannot return anything other than a boolean
+ result and can only support numeric or string input, whereas some
+ discoverable commands may only be for direct use through
+ ENGINE_ctrl(), eg. supporting the exchange of binary data, function
+ pointers, or other custom uses. The "executable" commands are to
+ support parameterisations of ENGINE behaviour that can be
+ unambiguously defined by ENGINEs and used consistently across any
+ OpenSSL-based application. Commands have been added to all the
+ existing hardware-supporting ENGINEs, noticeably "SO_PATH" to allow
+ control over shared-library paths without source code alterations.
+ [Geoff]
+
+ *) Changed all ENGINE implementations to dynamically allocate their
+ ENGINEs rather than declaring them statically. Apart from this being
+ necessary with the removal of the ENGINE_FLAGS_MALLOCED distinction,
+ this also allows the implementations to compile without using the
+ internal engine_int.h header.
+ [Geoff]
+
+ *) Minor adjustment to "rand" code. RAND_get_rand_method() now returns a
+ 'const' value. Any code that should be able to modify a RAND_METHOD
+ should already have non-const pointers to it (ie. they should only
+ modify their own ones).
+ [Geoff]
+
+ *) Made a variety of little tweaks to the ENGINE code.
+ - "atalla" and "ubsec" string definitions were moved from header files
+ to C code. "nuron" string definitions were placed in variables
+ rather than hard-coded - allowing parameterisation of these values
+ later on via ctrl() commands.
+ - Removed unused "#if 0"'d code.
+ - Fixed engine list iteration code so it uses ENGINE_free() to release
+ structural references.
+ - Constified the RAND_METHOD element of ENGINE structures.
+ - Constified various get/set functions as appropriate and added
+ missing functions (including a catch-all ENGINE_cpy that duplicates
+ all ENGINE values onto a new ENGINE except reference counts/state).
+ - Removed NULL parameter checks in get/set functions. Setting a method
+ or function to NULL is a way of cancelling out a previously set
+ value. Passing a NULL ENGINE parameter is just plain stupid anyway
+ and doesn't justify the extra error symbols and code.
+ - Deprecate the ENGINE_FLAGS_MALLOCED define and move the area for
+ flags from engine_int.h to engine.h.
+ - Changed prototypes for ENGINE handler functions (init(), finish(),
+ ctrl(), key-load functions, etc) to take an (ENGINE*) parameter.
+ [Geoff]
+
+ *) Implement binary inversion algorithm for BN_mod_inverse in addition
+ to the algorithm using long division. The binary algorithm can be
+ used only if the modulus is odd. On 32-bit systems, it is faster
+ only for relatively small moduli (roughly 20-30% for 128-bit moduli,
+ roughly 5-15% for 256-bit moduli), so we use it only for moduli
+ up to 450 bits. In 64-bit environments, the binary algorithm
+ appears to be advantageous for much longer moduli; here we use it
+ for moduli up to 2048 bits.
+ [Bodo Moeller]
+
+ *) Rewrite CHOICE field setting in ASN1_item_ex_d2i(). The old code
+ could not support the combine flag in choice fields.
+ [Steve Henson]
+
+ *) Add a 'copy_extensions' option to the 'ca' utility. This copies
+ extensions from a certificate request to the certificate.
+ [Steve Henson]
+
+ *) Allow multiple 'certopt' and 'nameopt' options to be separated
+ by commas. Add 'namopt' and 'certopt' options to the 'ca' config
+ file: this allows the display of the certificate about to be
+ signed to be customised, to allow certain fields to be included
+ or excluded and extension details. The old system didn't display
+ multicharacter strings properly, omitted fields not in the policy
+ and couldn't display additional details such as extensions.
+ [Steve Henson]
+
+ *) Function EC_POINTs_mul for multiple scalar multiplication
+ of an arbitrary number of elliptic curve points
+ \sum scalars[i]*points[i],
+ optionally including the generator defined for the EC_GROUP:
+ scalar*generator + \sum scalars[i]*points[i].
+
+ EC_POINT_mul is a simple wrapper function for the typical case
+ that the point list has just one item (besides the optional
+ generator).
+ [Bodo Moeller]
+
+ *) First EC_METHODs for curves over GF(p):
+
+ EC_GFp_simple_method() uses the basic BN_mod_mul and BN_mod_sqr
+ operations and provides various method functions that can also
+ operate with faster implementations of modular arithmetic.
+
+ EC_GFp_mont_method() reuses most functions that are part of
+ EC_GFp_simple_method, but uses Montgomery arithmetic.
+
+ [Bodo Moeller; point addition and point doubling
+ implementation directly derived from source code provided by
+ Lenka Fibikova <fibikova@exp-math.uni-essen.de>]
+
+ *) Framework for elliptic curves (crypto/ec/ec.h, crypto/ec/ec_lcl.h,
+ crypto/ec/ec_lib.c):
+
+ Curves are EC_GROUP objects (with an optional group generator)
+ based on EC_METHODs that are built into the library.
+
+ Points are EC_POINT objects based on EC_GROUP objects.
+
+ Most of the framework would be able to handle curves over arbitrary
+ finite fields, but as there are no obvious types for fields other
+ than GF(p), some functions are limited to that for now.
+ [Bodo Moeller]
+
+ *) Add the -HTTP option to s_server. It is similar to -WWW, but requires
+ that the file contains a complete HTTP response.
+ [Richard Levitte]
+
+ *) Add the ec directory to mkdef.pl and mkfiles.pl. In mkdef.pl
+ change the def and num file printf format specifier from "%-40sXXX"
+ to "%-39s XXX". The latter will always guarantee a space after the
+ field while the former will cause them to run together if the field
+ is 40 of more characters long.
+ [Steve Henson]
+
+ *) Constify the cipher and digest 'method' functions and structures
+ and modify related functions to take constant EVP_MD and EVP_CIPHER
+ pointers.
+ [Steve Henson]
+
+ *) Hide BN_CTX structure details in bn_lcl.h instead of publishing them
+ in <openssl/bn.h>. Also further increase BN_CTX_NUM to 32.
+ [Bodo Moeller]
+
+ *) Modify EVP_Digest*() routines so they now return values. Although the
+ internal software routines can never fail additional hardware versions
+ might.
+ [Steve Henson]
+
+ *) Clean up crypto/err/err.h and change some error codes to avoid conflicts:
+
+ Previously ERR_R_FATAL was too small and coincided with ERR_LIB_PKCS7
+ (= ERR_R_PKCS7_LIB); it is now 64 instead of 32.
+
+ ASN1 error codes
+ ERR_R_NESTED_ASN1_ERROR
+ ...
+ ERR_R_MISSING_ASN1_EOS
+ were 4 .. 9, conflicting with
+ ERR_LIB_RSA (= ERR_R_RSA_LIB)
+ ...
+ ERR_LIB_PEM (= ERR_R_PEM_LIB).
+ They are now 58 .. 63 (i.e., just below ERR_R_FATAL).
+
+ Add new error code 'ERR_R_INTERNAL_ERROR'.
+ [Bodo Moeller]
+
+ *) Don't overuse locks in crypto/err/err.c: For data retrieval, CRYPTO_r_lock
+ suffices.
+ [Bodo Moeller]
+
+ *) New option '-subj arg' for 'openssl req' and 'openssl ca'. This
+ sets the subject name for a new request or supersedes the
+ subject name in a given request. Formats that can be parsed are
+ 'CN=Some Name, OU=myOU, C=IT'
+ and
+ 'CN=Some Name/OU=myOU/C=IT'.
+
+ Add options '-batch' and '-verbose' to 'openssl req'.
+ [Massimiliano Pala <madwolf@hackmasters.net>]
+
+ *) Introduce the possibility to access global variables through
+ functions on platform were that's the best way to handle exporting
+ global variables in shared libraries. To enable this functionality,
+ one must configure with "EXPORT_VAR_AS_FN" or defined the C macro
+ "OPENSSL_EXPORT_VAR_AS_FUNCTION" in crypto/opensslconf.h (the latter
+ is normally done by Configure or something similar).
+
+ To implement a global variable, use the macro OPENSSL_IMPLEMENT_GLOBAL
+ in the source file (foo.c) like this:
+
+ OPENSSL_IMPLEMENT_GLOBAL(int,foo)=1;
+ OPENSSL_IMPLEMENT_GLOBAL(double,bar);
+
+ To declare a global variable, use the macros OPENSSL_DECLARE_GLOBAL
+ and OPENSSL_GLOBAL_REF in the header file (foo.h) like this:
+
+ OPENSSL_DECLARE_GLOBAL(int,foo);
+ #define foo OPENSSL_GLOBAL_REF(foo)
+ OPENSSL_DECLARE_GLOBAL(double,bar);
+ #define bar OPENSSL_GLOBAL_REF(bar)
+
+ The #defines are very important, and therefore so is including the
+ header file everywhere where the defined globals are used.
+
+ The macro OPENSSL_EXPORT_VAR_AS_FUNCTION also affects the definition
+ of ASN.1 items, but that structure is a bit different.
+
+ The largest change is in util/mkdef.pl which has been enhanced with
+ better and easier to understand logic to choose which symbols should
+ go into the Windows .def files as well as a number of fixes and code
+ cleanup (among others, algorithm keywords are now sorted
+ lexicographically to avoid constant rewrites).
+ [Richard Levitte]
+
+ *) In BN_div() keep a copy of the sign of 'num' before writing the
+ result to 'rm' because if rm==num the value will be overwritten
+ and produce the wrong result if 'num' is negative: this caused
+ problems with BN_mod() and BN_nnmod().
+ [Steve Henson]
+
+ *) Function OCSP_request_verify(). This checks the signature on an
+ OCSP request and verifies the signer certificate. The signer
+ certificate is just checked for a generic purpose and OCSP request
+ trust settings.
+ [Steve Henson]
+
+ *) Add OCSP_check_validity() function to check the validity of OCSP
+ responses. OCSP responses are prepared in real time and may only
+ be a few seconds old. Simply checking that the current time lies
+ between thisUpdate and nextUpdate max reject otherwise valid responses
+ caused by either OCSP responder or client clock inaccuracy. Instead
+ we allow thisUpdate and nextUpdate to fall within a certain period of
+ the current time. The age of the response can also optionally be
+ checked. Two new options -validity_period and -status_age added to
+ ocsp utility.
+ [Steve Henson]
+
+ *) If signature or public key algorithm is unrecognized print out its
+ OID rather that just UNKNOWN.
+ [Steve Henson]
+
+ *) Change OCSP_cert_to_id() to tolerate a NULL subject certificate and
+ OCSP_cert_id_new() a NULL serialNumber. This allows a partial certificate
+ ID to be generated from the issuer certificate alone which can then be
+ passed to OCSP_id_issuer_cmp().
+ [Steve Henson]
+
+ *) New compilation option ASN1_ITEM_FUNCTIONS. This causes the new
+ ASN1 modules to export functions returning ASN1_ITEM pointers
+ instead of the ASN1_ITEM structures themselves. This adds several
+ new macros which allow the underlying ASN1 function/structure to
+ be accessed transparently. As a result code should not use ASN1_ITEM
+ references directly (such as &X509_it) but instead use the relevant
+ macros (such as ASN1_ITEM_rptr(X509)). This option is to allow
+ use of the new ASN1 code on platforms where exporting structures
+ is problematical (for example in shared libraries) but exporting
+ functions returning pointers to structures is not.
+ [Steve Henson]
+
+ *) Add support for overriding the generation of SSL/TLS session IDs.
+ These callbacks can be registered either in an SSL_CTX or per SSL.
+ The purpose of this is to allow applications to control, if they wish,
+ the arbitrary values chosen for use as session IDs, particularly as it
+ can be useful for session caching in multiple-server environments. A
+ command-line switch for testing this (and any client code that wishes
+ to use such a feature) has been added to "s_server".
+ [Geoff Thorpe, Lutz Jaenicke]
+
+ *) Modify mkdef.pl to recognise and parse preprocessor conditionals
+ of the form '#if defined(...) || defined(...) || ...' and
+ '#if !defined(...) && !defined(...) && ...'. This also avoids
+ the growing number of special cases it was previously handling.
+ [Richard Levitte]
+
+ *) Make all configuration macros available for application by making
+ sure they are available in opensslconf.h, by giving them names starting
+ with "OPENSSL_" to avoid conflicts with other packages and by making
+ sure e_os2.h will cover all platform-specific cases together with
+ opensslconf.h.
+ Additionally, it is now possible to define configuration/platform-
+ specific names (called "system identities"). In the C code, these
+ are prefixed with "OPENSSL_SYSNAME_". e_os2.h will create another
+ macro with the name beginning with "OPENSSL_SYS_", which is determined
+ from "OPENSSL_SYSNAME_*" or compiler-specific macros depending on
+ what is available.
+ [Richard Levitte]
+
+ *) New option -set_serial to 'req' and 'x509' this allows the serial
+ number to use to be specified on the command line. Previously self
+ signed certificates were hard coded with serial number 0 and the
+ CA options of 'x509' had to use a serial number in a file which was
+ auto incremented.
+ [Steve Henson]
+
+ *) New options to 'ca' utility to support V2 CRL entry extensions.
+ Currently CRL reason, invalidity date and hold instruction are
+ supported. Add new CRL extensions to V3 code and some new objects.
+ [Steve Henson]
+
+ *) New function EVP_CIPHER_CTX_set_padding() this is used to
+ disable standard block padding (aka PKCS#5 padding) in the EVP
+ API, which was previously mandatory. This means that the data is
+ not padded in any way and so the total length much be a multiple
+ of the block size, otherwise an error occurs.
+ [Steve Henson]
+
+ *) Initial (incomplete) OCSP SSL support.
+ [Steve Henson]
+
+ *) New function OCSP_parse_url(). This splits up a URL into its host,
+ port and path components: primarily to parse OCSP URLs. New -url
+ option to ocsp utility.
+ [Steve Henson]
+
+ *) New nonce behavior. The return value of OCSP_check_nonce() now
+ reflects the various checks performed. Applications can decide
+ whether to tolerate certain situations such as an absent nonce
+ in a response when one was present in a request: the ocsp application
+ just prints out a warning. New function OCSP_add1_basic_nonce()
+ this is to allow responders to include a nonce in a response even if
+ the request is nonce-less.
+ [Steve Henson]
+
+ *) Disable stdin buffering in load_cert (apps/apps.c) so that no certs are
+ skipped when using openssl x509 multiple times on a single input file,
+ e.g. "(openssl x509 -out cert1; openssl x509 -out cert2) <certs".
+ [Bodo Moeller]
+
+ *) Make ASN1_UTCTIME_set_string() and ASN1_GENERALIZEDTIME_set_string()
+ set string type: to handle setting ASN1_TIME structures. Fix ca
+ utility to correctly initialize revocation date of CRLs.
+ [Steve Henson]
+
+ *) New option SSL_OP_CIPHER_SERVER_PREFERENCE allows the server to override
+ the clients preferred ciphersuites and rather use its own preferences.
+ Should help to work around M$ SGC (Server Gated Cryptography) bug in
+ Internet Explorer by ensuring unchanged hash method during stepup.
+ (Also replaces the broken/deactivated SSL_OP_NON_EXPORT_FIRST option.)
+ [Lutz Jaenicke]
+
+ *) Make mkdef.pl recognise all DECLARE_ASN1 macros, change rijndael
+ to aes and add a new 'exist' option to print out symbols that don't
+ appear to exist.
+ [Steve Henson]
+
+ *) Additional options to ocsp utility to allow flags to be set and
+ additional certificates supplied.
+ [Steve Henson]
+
+ *) Add the option -VAfile to 'openssl ocsp', so the user can give the
+ OCSP client a number of certificate to only verify the response
+ signature against.
+ [Richard Levitte]
+
+ *) Update Rijndael code to version 3.0 and change EVP AES ciphers to
+ handle the new API. Currently only ECB, CBC modes supported. Add new
+ AES OIDs.
+
+ Add TLS AES ciphersuites as described in RFC3268, "Advanced
+ Encryption Standard (AES) Ciphersuites for Transport Layer
+ Security (TLS)". (In beta versions of OpenSSL 0.9.7, these were
+ not enabled by default and were not part of the "ALL" ciphersuite
+ alias because they were not yet official; they could be
+ explicitly requested by specifying the "AESdraft" ciphersuite
+ group alias. In the final release of OpenSSL 0.9.7, the group
+ alias is called "AES" and is part of "ALL".)
+ [Ben Laurie, Steve Henson, Bodo Moeller]
+
+ *) New function OCSP_copy_nonce() to copy nonce value (if present) from
+ request to response.
+ [Steve Henson]
+
+ *) Functions for OCSP responders. OCSP_request_onereq_count(),
+ OCSP_request_onereq_get0(), OCSP_onereq_get0_id() and OCSP_id_get0_info()
+ extract information from a certificate request. OCSP_response_create()
+ creates a response and optionally adds a basic response structure.
+ OCSP_basic_add1_status() adds a complete single response to a basic
+ response and returns the OCSP_SINGLERESP structure just added (to allow
+ extensions to be included for example). OCSP_basic_add1_cert() adds a
+ certificate to a basic response and OCSP_basic_sign() signs a basic
+ response with various flags. New helper functions ASN1_TIME_check()
+ (checks validity of ASN1_TIME structure) and ASN1_TIME_to_generalizedtime()
+ (converts ASN1_TIME to GeneralizedTime).
+ [Steve Henson]
+
+ *) Various new functions. EVP_Digest() combines EVP_Digest{Init,Update,Final}()
+ in a single operation. X509_get0_pubkey_bitstr() extracts the public_key
+ structure from a certificate. X509_pubkey_digest() digests the public_key
+ contents: this is used in various key identifiers.
+ [Steve Henson]
+
+ *) Make sk_sort() tolerate a NULL argument.
+ [Steve Henson reported by Massimiliano Pala <madwolf@comune.modena.it>]
+
+ *) New OCSP verify flag OCSP_TRUSTOTHER. When set the "other" certificates
+ passed by the function are trusted implicitly. If any of them signed the
+ response then it is assumed to be valid and is not verified.
+ [Steve Henson]
+
+ *) In PKCS7_set_type() initialise content_type in PKCS7_ENC_CONTENT
+ to data. This was previously part of the PKCS7 ASN1 code. This
+ was causing problems with OpenSSL created PKCS#12 and PKCS#7 structures.
+ [Steve Henson, reported by Kenneth R. Robinette
+ <support@securenetterm.com>]
+
+ *) Add CRYPTO_push_info() and CRYPTO_pop_info() calls to new ASN1
+ routines: without these tracing memory leaks is very painful.
+ Fix leaks in PKCS12 and PKCS7 routines.
+ [Steve Henson]
+
+ *) Make X509_time_adj() cope with the new behaviour of ASN1_TIME_new().
+ Previously it initialised the 'type' argument to V_ASN1_UTCTIME which
+ effectively meant GeneralizedTime would never be used. Now it
+ is initialised to -1 but X509_time_adj() now has to check the value
+ and use ASN1_TIME_set() if the value is not V_ASN1_UTCTIME or
+ V_ASN1_GENERALIZEDTIME, without this it always uses GeneralizedTime.
+ [Steve Henson, reported by Kenneth R. Robinette
+ <support@securenetterm.com>]
+
+ *) Fixes to BN_to_ASN1_INTEGER when bn is zero. This would previously
+ result in a zero length in the ASN1_INTEGER structure which was
+ not consistent with the structure when d2i_ASN1_INTEGER() was used
+ and would cause ASN1_INTEGER_cmp() to fail. Enhance s2i_ASN1_INTEGER()
+ to cope with hex and negative integers. Fix bug in i2a_ASN1_INTEGER()
+ where it did not print out a minus for negative ASN1_INTEGER.
+ [Steve Henson]
+
+ *) Add summary printout to ocsp utility. The various functions which
+ convert status values to strings have been renamed to:
+ OCSP_response_status_str(), OCSP_cert_status_str() and
+ OCSP_crl_reason_str() and are no longer static. New options
+ to verify nonce values and to disable verification. OCSP response
+ printout format cleaned up.
+ [Steve Henson]
+
+ *) Add additional OCSP certificate checks. These are those specified
+ in RFC2560. This consists of two separate checks: the CA of the
+ certificate being checked must either be the OCSP signer certificate
+ or the issuer of the OCSP signer certificate. In the latter case the
+ OCSP signer certificate must contain the OCSP signing extended key
+ usage. This check is performed by attempting to match the OCSP
+ signer or the OCSP signer CA to the issuerNameHash and issuerKeyHash
+ in the OCSP_CERTID structures of the response.
+ [Steve Henson]
+
+ *) Initial OCSP certificate verification added to OCSP_basic_verify()
+ and related routines. This uses the standard OpenSSL certificate
+ verify routines to perform initial checks (just CA validity) and
+ to obtain the certificate chain. Then additional checks will be
+ performed on the chain. Currently the root CA is checked to see
+ if it is explicitly trusted for OCSP signing. This is used to set
+ a root CA as a global signing root: that is any certificate that
+ chains to that CA is an acceptable OCSP signing certificate.
+ [Steve Henson]
+
+ *) New '-extfile ...' option to 'openssl ca' for reading X.509v3
+ extensions from a separate configuration file.
+ As when reading extensions from the main configuration file,
+ the '-extensions ...' option may be used for specifying the
+ section to use.
+ [Massimiliano Pala <madwolf@comune.modena.it>]
+
+ *) New OCSP utility. Allows OCSP requests to be generated or
+ read. The request can be sent to a responder and the output
+ parsed, outputed or printed in text form. Not complete yet:
+ still needs to check the OCSP response validity.
+ [Steve Henson]
+
+ *) New subcommands for 'openssl ca':
+ 'openssl ca -status <serial>' prints the status of the cert with
+ the given serial number (according to the index file).
+ 'openssl ca -updatedb' updates the expiry status of certificates
+ in the index file.
+ [Massimiliano Pala <madwolf@comune.modena.it>]
+
+ *) New '-newreq-nodes' command option to CA.pl. This is like
+ '-newreq', but calls 'openssl req' with the '-nodes' option
+ so that the resulting key is not encrypted.
+ [Damien Miller <djm@mindrot.org>]
+
+ *) New configuration for the GNU Hurd.
+ [Jonathan Bartlett <johnnyb@wolfram.com> via Richard Levitte]
+
+ *) Initial code to implement OCSP basic response verify. This
+ is currently incomplete. Currently just finds the signer's
+ certificate and verifies the signature on the response.
+ [Steve Henson]
+
+ *) New SSLeay_version code SSLEAY_DIR to determine the compiled-in
+ value of OPENSSLDIR. This is available via the new '-d' option
+ to 'openssl version', and is also included in 'openssl version -a'.
+ [Bodo Moeller]
+
+ *) Allowing defining memory allocation callbacks that will be given
+ file name and line number information in additional arguments
+ (a const char* and an int). The basic functionality remains, as
+ well as the original possibility to just replace malloc(),
+ realloc() and free() by functions that do not know about these
+ additional arguments. To register and find out the current
+ settings for extended allocation functions, the following
+ functions are provided:
+
+ CRYPTO_set_mem_ex_functions
+ CRYPTO_set_locked_mem_ex_functions
+ CRYPTO_get_mem_ex_functions
+ CRYPTO_get_locked_mem_ex_functions
+
+ These work the same way as CRYPTO_set_mem_functions and friends.
+ CRYPTO_get_[locked_]mem_functions now writes 0 where such an
+ extended allocation function is enabled.
+ Similarly, CRYPTO_get_[locked_]mem_ex_functions writes 0 where
+ a conventional allocation function is enabled.
+ [Richard Levitte, Bodo Moeller]
+
+ *) Finish off removing the remaining LHASH function pointer casts.
+ There should no longer be any prototype-casting required when using
+ the LHASH abstraction, and any casts that remain are "bugs". See
+ the callback types and macros at the head of lhash.h for details
+ (and "OBJ_cleanup" in crypto/objects/obj_dat.c as an example).
+ [Geoff Thorpe]
+
+ *) Add automatic query of EGD sockets in RAND_poll() for the unix variant.
+ If /dev/[u]random devices are not available or do not return enough
+ entropy, EGD style sockets (served by EGD or PRNGD) will automatically
+ be queried.
+ The locations /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool, and
+ /etc/entropy will be queried once each in this sequence, quering stops
+ when enough entropy was collected without querying more sockets.
+ [Lutz Jaenicke]
+
+ *) Change the Unix RAND_poll() variant to be able to poll several
+ random devices, as specified by DEVRANDOM, until a sufficient amount
+ of data has been collected. We spend at most 10 ms on each file
+ (select timeout) and read in non-blocking mode. DEVRANDOM now
+ defaults to the list "/dev/urandom", "/dev/random", "/dev/srandom"
+ (previously it was just the string "/dev/urandom"), so on typical
+ platforms the 10 ms delay will never occur.
+ Also separate out the Unix variant to its own file, rand_unix.c.
+ For VMS, there's a currently-empty rand_vms.c.
+ [Richard Levitte]
+
+ *) Move OCSP client related routines to ocsp_cl.c. These
+ provide utility functions which an application needing
+ to issue a request to an OCSP responder and analyse the
+ response will typically need: as opposed to those which an
+ OCSP responder itself would need which will be added later.
+
+ OCSP_request_sign() signs an OCSP request with an API similar
+ to PKCS7_sign(). OCSP_response_status() returns status of OCSP
+ response. OCSP_response_get1_basic() extracts basic response
+ from response. OCSP_resp_find_status(): finds and extracts status
+ information from an OCSP_CERTID structure (which will be created
+ when the request structure is built). These are built from lower
+ level functions which work on OCSP_SINGLERESP structures but
+ wont normally be used unless the application wishes to examine
+ extensions in the OCSP response for example.
+
+ Replace nonce routines with a pair of functions.
+ OCSP_request_add1_nonce() adds a nonce value and optionally
+ generates a random value. OCSP_check_nonce() checks the
+ validity of the nonce in an OCSP response.
+ [Steve Henson]
+
+ *) Change function OCSP_request_add() to OCSP_request_add0_id().
+ This doesn't copy the supplied OCSP_CERTID and avoids the
+ need to free up the newly created id. Change return type
+ to OCSP_ONEREQ to return the internal OCSP_ONEREQ structure.
+ This can then be used to add extensions to the request.
+ Deleted OCSP_request_new(), since most of its functionality
+ is now in OCSP_REQUEST_new() (and the case insensitive name
+ clash) apart from the ability to set the request name which
+ will be added elsewhere.
+ [Steve Henson]
+
+ *) Update OCSP API. Remove obsolete extensions argument from
+ various functions. Extensions are now handled using the new
+ OCSP extension code. New simple OCSP HTTP function which
+ can be used to send requests and parse the response.
+ [Steve Henson]
+
+ *) Fix the PKCS#7 (S/MIME) code to work with new ASN1. Two new
+ ASN1_ITEM structures help with sign and verify. PKCS7_ATTR_SIGN
+ uses the special reorder version of SET OF to sort the attributes
+ and reorder them to match the encoded order. This resolves a long
+ standing problem: a verify on a PKCS7 structure just after signing
+ it used to fail because the attribute order did not match the
+ encoded order. PKCS7_ATTR_VERIFY does not reorder the attributes:
+ it uses the received order. This is necessary to tolerate some broken
+ software that does not order SET OF. This is handled by encoding
+ as a SEQUENCE OF but using implicit tagging (with UNIVERSAL class)
+ to produce the required SET OF.
+ [Steve Henson]
+
+ *) Have mk1mf.pl generate the macros OPENSSL_BUILD_SHLIBCRYPTO and
+ OPENSSL_BUILD_SHLIBSSL and use them appropriately in the header
+ files to get correct declarations of the ASN.1 item variables.
+ [Richard Levitte]
+
+ *) Rewrite of PKCS#12 code to use new ASN1 functionality. Replace many
+ PKCS#12 macros with real functions. Fix two unrelated ASN1 bugs:
+ asn1_check_tlen() would sometimes attempt to use 'ctx' when it was
+ NULL and ASN1_TYPE was not dereferenced properly in asn1_ex_c2i().
+ New ASN1 macro: DECLARE_ASN1_ITEM() which just declares the relevant
+ ASN1_ITEM and no wrapper functions.
+ [Steve Henson]
+
+ *) New functions or ASN1_item_d2i_fp() and ASN1_item_d2i_bio(). These
+ replace the old function pointer based I/O routines. Change most of
+ the *_d2i_bio() and *_d2i_fp() functions to use these.
+ [Steve Henson]
+
+ *) Enhance mkdef.pl to be more accepting about spacing in C preprocessor
+ lines, recognice more "algorithms" that can be deselected, and make
+ it complain about algorithm deselection that isn't recognised.
+ [Richard Levitte]
+
+ *) New ASN1 functions to handle dup, sign, verify, digest, pack and
+ unpack operations in terms of ASN1_ITEM. Modify existing wrappers
+ to use new functions. Add NO_ASN1_OLD which can be set to remove
+ some old style ASN1 functions: this can be used to determine if old
+ code will still work when these eventually go away.
+ [Steve Henson]
+
+ *) New extension functions for OCSP structures, these follow the
+ same conventions as certificates and CRLs.
+ [Steve Henson]
+
+ *) New function X509V3_add1_i2d(). This automatically encodes and
+ adds an extension. Its behaviour can be customised with various
+ flags to append, replace or delete. Various wrappers added for
+ certifcates and CRLs.
+ [Steve Henson]
+
+ *) Fix to avoid calling the underlying ASN1 print routine when
+ an extension cannot be parsed. Correct a typo in the
+ OCSP_SERVICELOC extension. Tidy up print OCSP format.
+ [Steve Henson]
+
+ *) Make mkdef.pl parse some of the ASN1 macros and add apropriate
+ entries for variables.
+ [Steve Henson]
+
+ *) Add functionality to apps/openssl.c for detecting locking
+ problems: As the program is single-threaded, all we have
+ to do is register a locking callback using an array for
+ storing which locks are currently held by the program.
+ [Bodo Moeller]
+
+ *) Use a lock around the call to CRYPTO_get_ex_new_index() in
+ SSL_get_ex_data_X509_STORE_idx(), which is used in
+ ssl_verify_cert_chain() and thus can be called at any time
+ during TLS/SSL handshakes so that thread-safety is essential.
+ Unfortunately, the ex_data design is not at all suited
+ for multi-threaded use, so it probably should be abolished.
+ [Bodo Moeller]
+
+ *) Added Broadcom "ubsec" ENGINE to OpenSSL.
+ [Broadcom, tweaked and integrated by Geoff Thorpe]
+
+ *) Move common extension printing code to new function
+ X509V3_print_extensions(). Reorganise OCSP print routines and
+ implement some needed OCSP ASN1 functions. Add OCSP extensions.
+ [Steve Henson]
+
+ *) New function X509_signature_print() to remove duplication in some
+ print routines.
+ [Steve Henson]
+
+ *) Add a special meaning when SET OF and SEQUENCE OF flags are both
+ set (this was treated exactly the same as SET OF previously). This
+ is used to reorder the STACK representing the structure to match the
+ encoding. This will be used to get round a problem where a PKCS7
+ structure which was signed could not be verified because the STACK
+ order did not reflect the encoded order.
+ [Steve Henson]
+
+ *) Reimplement the OCSP ASN1 module using the new code.
+ [Steve Henson]
+
+ *) Update the X509V3 code to permit the use of an ASN1_ITEM structure
+ for its ASN1 operations. The old style function pointers still exist
+ for now but they will eventually go away.
+ [Steve Henson]
+
+ *) Merge in replacement ASN1 code from the ASN1 branch. This almost
+ completely replaces the old ASN1 functionality with a table driven
+ encoder and decoder which interprets an ASN1_ITEM structure describing
+ the ASN1 module. Compatibility with the existing ASN1 API (i2d,d2i) is
+ largely maintained. Almost all of the old asn1_mac.h macro based ASN1
+ has also been converted to the new form.
+ [Steve Henson]
+
+ *) Change BN_mod_exp_recp so that negative moduli are tolerated
+ (the sign is ignored). Similarly, ignore the sign in BN_MONT_CTX_set
+ so that BN_mod_exp_mont and BN_mod_exp_mont_word work
+ for negative moduli.
+ [Bodo Moeller]
+
+ *) Fix BN_uadd and BN_usub: Always return non-negative results instead
+ of not touching the result's sign bit.
+ [Bodo Moeller]
+
+ *) BN_div bugfix: If the result is 0, the sign (res->neg) must not be
+ set.
+ [Bodo Moeller]
+
+ *) Changed the LHASH code to use prototypes for callbacks, and created
+ macros to declare and implement thin (optionally static) functions
+ that provide type-safety and avoid function pointer casting for the
+ type-specific callbacks.
+ [Geoff Thorpe]
+
+ *) Added Kerberos Cipher Suites to be used with TLS, as written in
+ RFC 2712.
+ [Veers Staats <staatsvr@asc.hpc.mil>,
+ Jeffrey Altman <jaltman@columbia.edu>, via Richard Levitte]
+
+ *) Reformat the FAQ so the different questions and answers can be divided
+ in sections depending on the subject.
+ [Richard Levitte]
+
+ *) Have the zlib compression code load ZLIB.DLL dynamically under
+ Windows.
+ [Richard Levitte]
+
+ *) New function BN_mod_sqrt for computing square roots modulo a prime
+ (using the probabilistic Tonelli-Shanks algorithm unless
+ p == 3 (mod 4) or p == 5 (mod 8), which are cases that can
+ be handled deterministically).
+ [Lenka Fibikova <fibikova@exp-math.uni-essen.de>, Bodo Moeller]
+
+ *) Make BN_mod_inverse faster by explicitly handling small quotients
+ in the Euclid loop. (Speed gain about 20% for small moduli [256 or
+ 512 bits], about 30% for larger ones [1024 or 2048 bits].)
+ [Bodo Moeller]
+
+ *) New function BN_kronecker.
+ [Bodo Moeller]
+
+ *) Fix BN_gcd so that it works on negative inputs; the result is
+ positive unless both parameters are zero.
+ Previously something reasonably close to an infinite loop was
+ possible because numbers could be growing instead of shrinking
+ in the implementation of Euclid's algorithm.
+ [Bodo Moeller]
+
+ *) Fix BN_is_word() and BN_is_one() macros to take into account the
+ sign of the number in question.
+
+ Fix BN_is_word(a,w) to work correctly for w == 0.
+
+ The old BN_is_word(a,w) macro is now called BN_abs_is_word(a,w)
+ because its test if the absolute value of 'a' equals 'w'.
+ Note that BN_abs_is_word does *not* handle w == 0 reliably;
+ it exists mostly for use in the implementations of BN_is_zero(),
+ BN_is_one(), and BN_is_word().
+ [Bodo Moeller]
+
+ *) New function BN_swap.
+ [Bodo Moeller]
+
+ *) Use BN_nnmod instead of BN_mod in crypto/bn/bn_exp.c so that
+ the exponentiation functions are more likely to produce reasonable
+ results on negative inputs.
+ [Bodo Moeller]
+
+ *) Change BN_mod_mul so that the result is always non-negative.
+ Previously, it could be negative if one of the factors was negative;
+ I don't think anyone really wanted that behaviour.
+ [Bodo Moeller]
+
+ *) Move BN_mod_... functions into new file crypto/bn/bn_mod.c
+ (except for exponentiation, which stays in crypto/bn/bn_exp.c,
+ and BN_mod_mul_reciprocal, which stays in crypto/bn/bn_recp.c)
+ and add new functions:
+
+ BN_nnmod
+ BN_mod_sqr
+ BN_mod_add
+ BN_mod_add_quick
+ BN_mod_sub
+ BN_mod_sub_quick
+ BN_mod_lshift1
+ BN_mod_lshift1_quick
+ BN_mod_lshift
+ BN_mod_lshift_quick
+
+ These functions always generate non-negative results.
+
+ BN_nnmod otherwise is like BN_mod (if BN_mod computes a remainder r
+ such that |m| < r < 0, BN_nnmod will output rem + |m| instead).
+
+ BN_mod_XXX_quick(r, a, [b,] m) generates the same result as
+ BN_mod_XXX(r, a, [b,] m, ctx), but requires that a [and b]
+ be reduced modulo m.
+ [Lenka Fibikova <fibikova@exp-math.uni-essen.de>, Bodo Moeller]
+
+#if 0
+ The following entry accidentily appeared in the CHANGES file
+ distributed with OpenSSL 0.9.7. The modifications described in
+ it do *not* apply to OpenSSL 0.9.7.
+
+ *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there
+ was actually never needed) and in BN_mul(). The removal in BN_mul()
+ required a small change in bn_mul_part_recursive() and the addition
+ of the functions bn_cmp_part_words(), bn_sub_part_words() and
+ bn_add_part_words(), which do the same thing as bn_cmp_words(),
+ bn_sub_words() and bn_add_words() except they take arrays with
+ differing sizes.
+ [Richard Levitte]
+#endif
+
+ *) In 'openssl passwd', verify passwords read from the terminal
+ unless the '-salt' option is used (which usually means that
+ verification would just waste user's time since the resulting
+ hash is going to be compared with some given password hash)
+ or the new '-noverify' option is used.
+
+ This is an incompatible change, but it does not affect
+ non-interactive use of 'openssl passwd' (passwords on the command
+ line, '-stdin' option, '-in ...' option) and thus should not
+ cause any problems.
+ [Bodo Moeller]
+
+ *) Remove all references to RSAref, since there's no more need for it.
+ [Richard Levitte]
+
+ *) Make DSO load along a path given through an environment variable
+ (SHLIB_PATH) with shl_load().
+ [Richard Levitte]
+
+ *) Constify the ENGINE code as a result of BIGNUM constification.
+ Also constify the RSA code and most things related to it. In a
+ few places, most notable in the depth of the ASN.1 code, ugly
+ casts back to non-const were required (to be solved at a later
+ time)
+ [Richard Levitte]
+
+ *) Make it so the openssl application has all engines loaded by default.
+ [Richard Levitte]
+
+ *) Constify the BIGNUM routines a little more.
+ [Richard Levitte]
+
+ *) Add the following functions:
+
+ ENGINE_load_cswift()
+ ENGINE_load_chil()
+ ENGINE_load_atalla()
+ ENGINE_load_nuron()
+ ENGINE_load_builtin_engines()
+
+ That way, an application can itself choose if external engines that
+ are built-in in OpenSSL shall ever be used or not. The benefit is
+ that applications won't have to be linked with libdl or other dso
+ libraries unless it's really needed.
+
+ Changed 'openssl engine' to load all engines on demand.
+ Changed the engine header files to avoid the duplication of some
+ declarations (they differed!).
+ [Richard Levitte]
+
+ *) 'openssl engine' can now list capabilities.
+ [Richard Levitte]
+
+ *) Better error reporting in 'openssl engine'.
+ [Richard Levitte]
+
+ *) Never call load_dh_param(NULL) in s_server.
+ [Bodo Moeller]
+
+ *) Add engine application. It can currently list engines by name and
+ identity, and test if they are actually available.
+ [Richard Levitte]
+
+ *) Improve RPM specification file by forcing symbolic linking and making
+ sure the installed documentation is also owned by root.root.
+ [Damien Miller <djm@mindrot.org>]
+
+ *) Give the OpenSSL applications more possibilities to make use of
+ keys (public as well as private) handled by engines.
+ [Richard Levitte]
+
+ *) Add OCSP code that comes from CertCo.
+ [Richard Levitte]
+
+ *) Add VMS support for the Rijndael code.
+ [Richard Levitte]
+
+ *) Added untested support for Nuron crypto accelerator.
+ [Ben Laurie]
+
+ *) Add support for external cryptographic devices. This code was
+ previously distributed separately as the "engine" branch.
+ [Geoff Thorpe, Richard Levitte]
+
+ *) Rework the filename-translation in the DSO code. It is now possible to
+ have far greater control over how a "name" is turned into a filename
+ depending on the operating environment and any oddities about the
+ different shared library filenames on each system.
+ [Geoff Thorpe]
+
+ *) Support threads on FreeBSD-elf in Configure.
+ [Richard Levitte]
+
+ *) Fix for SHA1 assembly problem with MASM: it produces
+ warnings about corrupt line number information when assembling
+ with debugging information. This is caused by the overlapping
+ of two sections.
+ [Bernd Matthes <mainbug@celocom.de>, Steve Henson]
+
+ *) NCONF changes.
+ NCONF_get_number() has no error checking at all. As a replacement,
+ NCONF_get_number_e() is defined (_e for "error checking") and is
+ promoted strongly. The old NCONF_get_number is kept around for
+ binary backward compatibility.
+ Make it possible for methods to load from something other than a BIO,
+ by providing a function pointer that is given a name instead of a BIO.
+ For example, this could be used to load configuration data from an
+ LDAP server.
+ [Richard Levitte]
+
+ *) Fix for non blocking accept BIOs. Added new I/O special reason
+ BIO_RR_ACCEPT to cover this case. Previously use of accept BIOs
+ with non blocking I/O was not possible because no retry code was
+ implemented. Also added new SSL code SSL_WANT_ACCEPT to cover
+ this case.
+ [Steve Henson]
+
+ *) Added the beginnings of Rijndael support.
+ [Ben Laurie]
+
+ *) Fix for bug in DirectoryString mask setting. Add support for
+ X509_NAME_print_ex() in 'req' and X509_print_ex() function
+ to allow certificate printing to more controllable, additional
+ 'certopt' option to 'x509' to allow new printing options to be
+ set.
+ [Steve Henson]
+
+ *) Clean old EAY MD5 hack from e_os.h.
+ [Richard Levitte]
+
+ Changes between 0.9.6l and 0.9.6m [17 Mar 2004]
+
+ *) Fix null-pointer assignment in do_change_cipher_spec() revealed
+ by using the Codenomicon TLS Test Tool (CVE-2004-0079)
+ [Joe Orton, Steve Henson]
+
+ Changes between 0.9.6k and 0.9.6l [04 Nov 2003]
+
+ *) Fix additional bug revealed by the NISCC test suite:
+
+ Stop bug triggering large recursion when presented with
+ certain ASN.1 tags (CVE-2003-0851)
+ [Steve Henson]
+
+ Changes between 0.9.6j and 0.9.6k [30 Sep 2003]
+
+ *) Fix various bugs revealed by running the NISCC test suite:
+
+ Stop out of bounds reads in the ASN1 code when presented with
+ invalid tags (CVE-2003-0543 and CVE-2003-0544).
+
+ If verify callback ignores invalid public key errors don't try to check
+ certificate signature with the NULL public key.
+
+ [Steve Henson]
+
+ *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate
+ if the server requested one: as stated in TLS 1.0 and SSL 3.0
+ specifications.
+ [Steve Henson]
+
+ *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional
+ extra data after the compression methods not only for TLS 1.0
+ but also for SSL 3.0 (as required by the specification).
+ [Bodo Moeller; problem pointed out by Matthias Loepfe]
+
+ *) Change X509_certificate_type() to mark the key as exported/exportable
+ when it's 512 *bits* long, not 512 bytes.
+ [Richard Levitte]
+
+ Changes between 0.9.6i and 0.9.6j [10 Apr 2003]
+
+ *) Countermeasure against the Klima-Pokorny-Rosa extension of
+ Bleichbacher's attack on PKCS #1 v1.5 padding: treat
+ a protocol version number mismatch like a decryption error
+ in ssl3_get_client_key_exchange (ssl/s3_srvr.c).
+ [Bodo Moeller]
+
+ *) Turn on RSA blinding by default in the default implementation
+ to avoid a timing attack. Applications that don't want it can call
+ RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING.
+ They would be ill-advised to do so in most cases.
+ [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller]
+
+ *) Change RSA blinding code so that it works when the PRNG is not
+ seeded (in this case, the secret RSA exponent is abused as
+ an unpredictable seed -- if it is not unpredictable, there
+ is no point in blinding anyway). Make RSA blinding thread-safe
+ by remembering the creator's thread ID in rsa->blinding and
+ having all other threads use local one-time blinding factors
+ (this requires more computation than sharing rsa->blinding, but
+ avoids excessive locking; and if an RSA object is not shared
+ between threads, blinding will still be very fast).
+ [Bodo Moeller]
+
+ Changes between 0.9.6h and 0.9.6i [19 Feb 2003]
+
+ *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked
+ via timing by performing a MAC computation even if incorrrect
+ block cipher padding has been found. This is a countermeasure
+ against active attacks where the attacker has to distinguish
+ between bad padding and a MAC verification error. (CVE-2003-0078)
+
+ [Bodo Moeller; problem pointed out by Brice Canvel (EPFL),
+ Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and
+ Martin Vuagnoux (EPFL, Ilion)]
+
+ Changes between 0.9.6g and 0.9.6h [5 Dec 2002]
+
+ *) New function OPENSSL_cleanse(), which is used to cleanse a section of
+ memory from it's contents. This is done with a counter that will
+ place alternating values in each byte. This can be used to solve
+ two issues: 1) the removal of calls to memset() by highly optimizing
+ compilers, and 2) cleansing with other values than 0, since those can
+ be read through on certain media, for example a swap space on disk.
+ [Geoff Thorpe]
+
+ *) Bugfix: client side session caching did not work with external caching,
+ because the session->cipher setting was not restored when reloading
+ from the external cache. This problem was masked, when
+ SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG (part of SSL_OP_ALL) was set.
+ (Found by Steve Haslam <steve@araqnid.ddts.net>.)
+ [Lutz Jaenicke]
+
+ *) Fix client_certificate (ssl/s2_clnt.c): The permissible total
+ length of the REQUEST-CERTIFICATE message is 18 .. 34, not 17 .. 33.
+ [Zeev Lieber <zeev-l@yahoo.com>]
+
+ *) Undo an undocumented change introduced in 0.9.6e which caused
+ repeated calls to OpenSSL_add_all_ciphers() and
+ OpenSSL_add_all_digests() to be ignored, even after calling
+ EVP_cleanup().
+ [Richard Levitte]
+
+ *) Change the default configuration reader to deal with last line not
+ being properly terminated.
+ [Richard Levitte]
+
+ *) Change X509_NAME_cmp() so it applies the special rules on handling
+ DN values that are of type PrintableString, as well as RDNs of type
+ emailAddress where the value has the type ia5String.
+ [stefank@valicert.com via Richard Levitte]
+
+ *) Add a SSL_SESS_CACHE_NO_INTERNAL_STORE flag to take over half
+ the job SSL_SESS_CACHE_NO_INTERNAL_LOOKUP was inconsistently
+ doing, define a new flag (SSL_SESS_CACHE_NO_INTERNAL) to be
+ the bitwise-OR of the two for use by the majority of applications
+ wanting this behaviour, and update the docs. The documented
+ behaviour and actual behaviour were inconsistent and had been
+ changing anyway, so this is more a bug-fix than a behavioural
+ change.
+ [Geoff Thorpe, diagnosed by Nadav Har'El]
+
+ *) Don't impose a 16-byte length minimum on session IDs in ssl/s3_clnt.c
+ (the SSL 3.0 and TLS 1.0 specifications allow any length up to 32 bytes).
+ [Bodo Moeller]
+
+ *) Fix initialization code race conditions in
+ SSLv23_method(), SSLv23_client_method(), SSLv23_server_method(),
+ SSLv2_method(), SSLv2_client_method(), SSLv2_server_method(),
+ SSLv3_method(), SSLv3_client_method(), SSLv3_server_method(),
+ TLSv1_method(), TLSv1_client_method(), TLSv1_server_method(),
+ ssl2_get_cipher_by_char(),
+ ssl3_get_cipher_by_char().
+ [Patrick McCormick <patrick@tellme.com>, Bodo Moeller]
+
+ *) Reorder cleanup sequence in SSL_CTX_free(): only remove the ex_data after
+ the cached sessions are flushed, as the remove_cb() might use ex_data
+ contents. Bug found by Sam Varshavchik <mrsam@courier-mta.com>
+ (see [openssl.org #212]).
+ [Geoff Thorpe, Lutz Jaenicke]
+
+ *) Fix typo in OBJ_txt2obj which incorrectly passed the content
+ length, instead of the encoding length to d2i_ASN1_OBJECT.
+ [Steve Henson]
+
+ Changes between 0.9.6f and 0.9.6g [9 Aug 2002]
+
+ *) [In 0.9.6g-engine release:]
+ Fix crypto/engine/vendor_defns/cswift.h for WIN32 (use '_stdcall').
+ [Lynn Gazis <lgazis@rainbow.com>]
+
+ Changes between 0.9.6e and 0.9.6f [8 Aug 2002]
+
+ *) Fix ASN1 checks. Check for overflow by comparing with LONG_MAX
+ and get fix the header length calculation.
+ [Florian Weimer <Weimer@CERT.Uni-Stuttgart.DE>,
+ Alon Kantor <alonk@checkpoint.com> (and others),
+ Steve Henson]
+
+ *) Use proper error handling instead of 'assertions' in buffer
+ overflow checks added in 0.9.6e. This prevents DoS (the
+ assertions could call abort()).
+ [Arne Ansper <arne@ats.cyber.ee>, Bodo Moeller]
+
+ Changes between 0.9.6d and 0.9.6e [30 Jul 2002]
+
+ *) Add various sanity checks to asn1_get_length() to reject
+ the ASN1 length bytes if they exceed sizeof(long), will appear
+ negative or the content length exceeds the length of the
+ supplied buffer.
+ [Steve Henson, Adi Stav <stav@mercury.co.il>, James Yonan <jim@ntlp.com>]
+
+ *) Fix cipher selection routines: ciphers without encryption had no flags
+ for the cipher strength set and where therefore not handled correctly
+ by the selection routines (PR #130).
+ [Lutz Jaenicke]
+
+ *) Fix EVP_dsa_sha macro.
+ [Nils Larsch]
+
+ *) New option
+ SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
+ for disabling the SSL 3.0/TLS 1.0 CBC vulnerability countermeasure
+ that was added in OpenSSL 0.9.6d.
+
+ As the countermeasure turned out to be incompatible with some
+ broken SSL implementations, the new option is part of SSL_OP_ALL.
+ SSL_OP_ALL is usually employed when compatibility with weird SSL
+ implementations is desired (e.g. '-bugs' option to 's_client' and
+ 's_server'), so the new option is automatically set in many
+ applications.
+ [Bodo Moeller]
+
+ *) Changes in security patch:
+
+ Changes marked "(CHATS)" were sponsored by the Defense Advanced
+ Research Projects Agency (DARPA) and Air Force Research Laboratory,
+ Air Force Materiel Command, USAF, under agreement number
+ F30602-01-2-0537.
+
+ *) Add various sanity checks to asn1_get_length() to reject
+ the ASN1 length bytes if they exceed sizeof(long), will appear
+ negative or the content length exceeds the length of the
+ supplied buffer. (CVE-2002-0659)
+ [Steve Henson, Adi Stav <stav@mercury.co.il>, James Yonan <jim@ntlp.com>]
+
+ *) Assertions for various potential buffer overflows, not known to
+ happen in practice.
+ [Ben Laurie (CHATS)]
+
+ *) Various temporary buffers to hold ASCII versions of integers were
+ too small for 64 bit platforms. (CVE-2002-0655)
+ [Matthew Byng-Maddick <mbm@aldigital.co.uk> and Ben Laurie (CHATS)>
+
+ *) Remote buffer overflow in SSL3 protocol - an attacker could
+ supply an oversized session ID to a client. (CVE-2002-0656)
+ [Ben Laurie (CHATS)]
+
+ *) Remote buffer overflow in SSL2 protocol - an attacker could
+ supply an oversized client master key. (CVE-2002-0656)
+ [Ben Laurie (CHATS)]
+
+ Changes between 0.9.6c and 0.9.6d [9 May 2002]
+
+ *) Fix crypto/asn1/a_sign.c so that 'parameters' is omitted (not
+ encoded as NULL) with id-dsa-with-sha1.
+ [Nils Larsch <nla@trustcenter.de>; problem pointed out by Bodo Moeller]
+
+ *) Check various X509_...() return values in apps/req.c.
+ [Nils Larsch <nla@trustcenter.de>]
+
+ *) Fix BASE64 decode (EVP_DecodeUpdate) for data with CR/LF ended lines:
+ an end-of-file condition would erronously be flagged, when the CRLF
+ was just at the end of a processed block. The bug was discovered when
+ processing data through a buffering memory BIO handing the data to a
+ BASE64-decoding BIO. Bug fund and patch submitted by Pavel Tsekov
+ <ptsekov@syntrex.com> and Nedelcho Stanev.
+ [Lutz Jaenicke]
+
+ *) Implement a countermeasure against a vulnerability recently found
+ in CBC ciphersuites in SSL 3.0/TLS 1.0: Send an empty fragment
+ before application data chunks to avoid the use of known IVs
+ with data potentially chosen by the attacker.
+ [Bodo Moeller]
+
+ *) Fix length checks in ssl3_get_client_hello().
+ [Bodo Moeller]
+
+ *) TLS/SSL library bugfix: use s->s3->in_read_app_data differently
+ to prevent ssl3_read_internal() from incorrectly assuming that
+ ssl3_read_bytes() found application data while handshake
+ processing was enabled when in fact s->s3->in_read_app_data was
+ merely automatically cleared during the initial handshake.
+ [Bodo Moeller; problem pointed out by Arne Ansper <arne@ats.cyber.ee>]
+
+ *) Fix object definitions for Private and Enterprise: they were not
+ recognized in their shortname (=lowercase) representation. Extend
+ obj_dat.pl to issue an error when using undefined keywords instead
+ of silently ignoring the problem (Svenning Sorensen
+ <sss@sss.dnsalias.net>).
+ [Lutz Jaenicke]
+
+ *) Fix DH_generate_parameters() so that it works for 'non-standard'
+ generators, i.e. generators other than 2 and 5. (Previously, the
+ code did not properly initialise the 'add' and 'rem' values to
+ BN_generate_prime().)
+
+ In the new general case, we do not insist that 'generator' is
+ actually a primitive root: This requirement is rather pointless;
+ a generator of the order-q subgroup is just as good, if not
+ better.
+ [Bodo Moeller]
+
+ *) Map new X509 verification errors to alerts. Discovered and submitted by
+ Tom Wu <tom@arcot.com>.
+ [Lutz Jaenicke]
+
+ *) Fix ssl3_pending() (ssl/s3_lib.c) to prevent SSL_pending() from
+ returning non-zero before the data has been completely received
+ when using non-blocking I/O.
+ [Bodo Moeller; problem pointed out by John Hughes]
+
+ *) Some of the ciphers missed the strength entry (SSL_LOW etc).
+ [Ben Laurie, Lutz Jaenicke]
+
+ *) Fix bug in SSL_clear(): bad sessions were not removed (found by
+ Yoram Zahavi <YoramZ@gilian.com>).
+ [Lutz Jaenicke]
+
+ *) Add information about CygWin 1.3 and on, and preserve proper
+ configuration for the versions before that.
+ [Corinna Vinschen <vinschen@redhat.com> and Richard Levitte]
+
+ *) Make removal from session cache (SSL_CTX_remove_session()) more robust:
+ check whether we deal with a copy of a session and do not delete from
+ the cache in this case. Problem reported by "Izhar Shoshani Levi"
+ <izhar@checkpoint.com>.
+ [Lutz Jaenicke]
+
+ *) Do not store session data into the internal session cache, if it
+ is never intended to be looked up (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
+ flag is set). Proposed by Aslam <aslam@funk.com>.
+ [Lutz Jaenicke]
+
+ *) Have ASN1_BIT_STRING_set_bit() really clear a bit when the requested
+ value is 0.
+ [Richard Levitte]
+
+ *) [In 0.9.6d-engine release:]
+ Fix a crashbug and a logic bug in hwcrhk_load_pubkey().
+ [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
+
+ *) Add the configuration target linux-s390x.
+ [Neale Ferguson <Neale.Ferguson@SoftwareAG-USA.com> via Richard Levitte]
+
+ *) The earlier bugfix for the SSL3_ST_SW_HELLO_REQ_C case of
+ ssl3_accept (ssl/s3_srvr.c) incorrectly used a local flag
+ variable as an indication that a ClientHello message has been
+ received. As the flag value will be lost between multiple
+ invocations of ssl3_accept when using non-blocking I/O, the
+ function may not be aware that a handshake has actually taken
+ place, thus preventing a new session from being added to the
+ session cache.
+
+ To avoid this problem, we now set s->new_session to 2 instead of
+ using a local variable.
+ [Lutz Jaenicke, Bodo Moeller]
+
+ *) Bugfix: Return -1 from ssl3_get_server_done (ssl3/s3_clnt.c)
+ if the SSL_R_LENGTH_MISMATCH error is detected.
+ [Geoff Thorpe, Bodo Moeller]
+
+ *) New 'shared_ldflag' column in Configure platform table.
+ [Richard Levitte]
+
+ *) Fix EVP_CIPHER_mode macro.
+ ["Dan S. Camper" <dan@bti.net>]
+
+ *) Fix ssl3_read_bytes (ssl/s3_pkt.c): To ignore messages of unknown
+ type, we must throw them away by setting rr->length to 0.
+ [D P Chang <dpc@qualys.com>]
+
+ Changes between 0.9.6b and 0.9.6c [21 dec 2001]
+
+ *) Fix BN_rand_range bug pointed out by Dominikus Scherkl
+ <Dominikus.Scherkl@biodata.com>. (The previous implementation
+ worked incorrectly for those cases where range = 10..._2 and
+ 3*range is two bits longer than range.)
+ [Bodo Moeller]
+
+ *) Only add signing time to PKCS7 structures if it is not already
+ present.
+ [Steve Henson]
+
+ *) Fix crypto/objects/objects.h: "ld-ce" should be "id-ce",
+ OBJ_ld_ce should be OBJ_id_ce.
+ Also some ip-pda OIDs in crypto/objects/objects.txt were
+ incorrect (cf. RFC 3039).
+ [Matt Cooper, Frederic Giudicelli, Bodo Moeller]
+
+ *) Release CRYPTO_LOCK_DYNLOCK when CRYPTO_destroy_dynlockid()
+ returns early because it has nothing to do.
+ [Andy Schneider <andy.schneider@bjss.co.uk>]
+
+ *) [In 0.9.6c-engine release:]
+ Fix mutex callback return values in crypto/engine/hw_ncipher.c.
+ [Andy Schneider <andy.schneider@bjss.co.uk>]
+
+ *) [In 0.9.6c-engine release:]
+ Add support for Cryptographic Appliance's keyserver technology.
+ (Use engine 'keyclient')
+ [Cryptographic Appliances and Geoff Thorpe]
+
+ *) Add a configuration entry for OS/390 Unix. The C compiler 'c89'
+ is called via tools/c89.sh because arguments have to be
+ rearranged (all '-L' options must appear before the first object
+ modules).
+ [Richard Shapiro <rshapiro@abinitio.com>]
+
+ *) [In 0.9.6c-engine release:]
+ Add support for Broadcom crypto accelerator cards, backported
+ from 0.9.7.
+ [Broadcom, Nalin Dahyabhai <nalin@redhat.com>, Mark Cox]
+
+ *) [In 0.9.6c-engine release:]
+ Add support for SureWare crypto accelerator cards from
+ Baltimore Technologies. (Use engine 'sureware')
+ [Baltimore Technologies and Mark Cox]
+
+ *) [In 0.9.6c-engine release:]
+ Add support for crypto accelerator cards from Accelerated
+ Encryption Processing, www.aep.ie. (Use engine 'aep')
+ [AEP Inc. and Mark Cox]
+
+ *) Add a configuration entry for gcc on UnixWare.
+ [Gary Benson <gbenson@redhat.com>]
+
+ *) Change ssl/s2_clnt.c and ssl/s2_srvr.c so that received handshake
+ messages are stored in a single piece (fixed-length part and
+ variable-length part combined) and fix various bugs found on the way.
+ [Bodo Moeller]
+
+ *) Disable caching in BIO_gethostbyname(), directly use gethostbyname()
+ instead. BIO_gethostbyname() does not know what timeouts are
+ appropriate, so entries would stay in cache even when they have
+ become invalid.
+ [Bodo Moeller; problem pointed out by Rich Salz <rsalz@zolera.com>
+
+ *) Change ssl23_get_client_hello (ssl/s23_srvr.c) behaviour when
+ faced with a pathologically small ClientHello fragment that does
+ not contain client_version: Instead of aborting with an error,
+ simply choose the highest available protocol version (i.e.,
+ TLS 1.0 unless it is disabled). In practice, ClientHello
+ messages are never sent like this, but this change gives us
+ strictly correct behaviour at least for TLS.
+ [Bodo Moeller]
+
+ *) Fix SSL handshake functions and SSL_clear() such that SSL_clear()
+ never resets s->method to s->ctx->method when called from within
+ one of the SSL handshake functions.
+ [Bodo Moeller; problem pointed out by Niko Baric]
+
+ *) In ssl3_get_client_hello (ssl/s3_srvr.c), generate a fatal alert
+ (sent using the client's version number) if client_version is
+ smaller than the protocol version in use. Also change
+ ssl23_get_client_hello (ssl/s23_srvr.c) to select TLS 1.0 if
+ the client demanded SSL 3.0 but only TLS 1.0 is enabled; then
+ the client will at least see that alert.
+ [Bodo Moeller]
+
+ *) Fix ssl3_get_message (ssl/s3_both.c) to handle message fragmentation
+ correctly.
+ [Bodo Moeller]
+
+ *) Avoid infinite loop in ssl3_get_message (ssl/s3_both.c) if a
+ client receives HelloRequest while in a handshake.
+ [Bodo Moeller; bug noticed by Andy Schneider <andy.schneider@bjss.co.uk>]
+
+ *) Bugfix in ssl3_accept (ssl/s3_srvr.c): Case SSL3_ST_SW_HELLO_REQ_C
+ should end in 'break', not 'goto end' which circuments various
+ cleanups done in state SSL_ST_OK. But session related stuff
+ must be disabled for SSL_ST_OK in the case that we just sent a
+ HelloRequest.
+
+ Also avoid some overhead by not calling ssl_init_wbio_buffer()
+ before just sending a HelloRequest.
+ [Bodo Moeller, Eric Rescorla <ekr@rtfm.com>]
+
+ *) Fix ssl/s3_enc.c, ssl/t1_enc.c and ssl/s3_pkt.c so that we don't
+ reveal whether illegal block cipher padding was found or a MAC
+ verification error occured. (Neither SSLerr() codes nor alerts
+ are directly visible to potential attackers, but the information
+ may leak via logfiles.)
+
+ Similar changes are not required for the SSL 2.0 implementation
+ because the number of padding bytes is sent in clear for SSL 2.0,
+ and the extra bytes are just ignored. However ssl/s2_pkt.c
+ failed to verify that the purported number of padding bytes is in
+ the legal range.
+ [Bodo Moeller]
+
+ *) Add OpenUNIX-8 support including shared libraries
+ (Boyd Lynn Gerber <gerberb@zenez.com>).
+ [Lutz Jaenicke]
+
+ *) Improve RSA_padding_check_PKCS1_OAEP() check again to avoid
+ 'wristwatch attack' using huge encoding parameters (cf.
+ James H. Manger's CRYPTO 2001 paper). Note that the
+ RSA_PKCS1_OAEP_PADDING case of RSA_private_decrypt() does not use
+ encoding parameters and hence was not vulnerable.
+ [Bodo Moeller]
+
+ *) BN_sqr() bug fix.
+ [Ulf Möller, reported by Jim Ellis <jim.ellis@cavium.com>]
+
+ *) Rabin-Miller test analyses assume uniformly distributed witnesses,
+ so use BN_pseudo_rand_range() instead of using BN_pseudo_rand()
+ followed by modular reduction.
+ [Bodo Moeller; pointed out by Adam Young <AYoung1@NCSUS.JNJ.COM>]
+
+ *) Add BN_pseudo_rand_range() with obvious functionality: BN_rand_range()
+ equivalent based on BN_pseudo_rand() instead of BN_rand().
+ [Bodo Moeller]
+
+ *) s3_srvr.c: allow sending of large client certificate lists (> 16 kB).
+ This function was broken, as the check for a new client hello message
+ to handle SGC did not allow these large messages.
+ (Tracked down by "Douglas E. Engert" <deengert@anl.gov>.)
+ [Lutz Jaenicke]
+
+ *) Add alert descriptions for TLSv1 to SSL_alert_desc_string[_long]().
+ [Lutz Jaenicke]
+
+ *) Fix buggy behaviour of BIO_get_num_renegotiates() and BIO_ctrl()
+ for BIO_C_GET_WRITE_BUF_SIZE ("Stephen Hinton" <shinton@netopia.com>).
+ [Lutz Jaenicke]
+
+ *) Rework the configuration and shared library support for Tru64 Unix.
+ The configuration part makes use of modern compiler features and
+ still retains old compiler behavior for those that run older versions
+ of the OS. The shared library support part includes a variant that
+ uses the RPATH feature, and is available through the special
+ configuration target "alpha-cc-rpath", which will never be selected
+ automatically.
+ [Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu> via Richard Levitte]
+
+ *) In ssl3_get_key_exchange (ssl/s3_clnt.c), call ssl3_get_message()
+ with the same message size as in ssl3_get_certificate_request().
+ Otherwise, if no ServerKeyExchange message occurs, CertificateRequest
+ messages might inadvertently be reject as too long.
+ [Petr Lampa <lampa@fee.vutbr.cz>]
+
+ *) Enhanced support for IA-64 Unix platforms (well, Linux and HP-UX).
+ [Andy Polyakov]
+
+ *) Modified SSL library such that the verify_callback that has been set
+ specificly for an SSL object with SSL_set_verify() is actually being
+ used. Before the change, a verify_callback set with this function was
+ ignored and the verify_callback() set in the SSL_CTX at the time of
+ the call was used. New function X509_STORE_CTX_set_verify_cb() introduced
+ to allow the necessary settings.
+ [Lutz Jaenicke]
+
+ *) Initialize static variable in crypto/dsa/dsa_lib.c and crypto/dh/dh_lib.c
+ explicitly to NULL, as at least on Solaris 8 this seems not always to be
+ done automatically (in contradiction to the requirements of the C
+ standard). This made problems when used from OpenSSH.
+ [Lutz Jaenicke]
+
+ *) In OpenSSL 0.9.6a and 0.9.6b, crypto/dh/dh_key.c ignored
+ dh->length and always used
+
+ BN_rand_range(priv_key, dh->p).
+
+ BN_rand_range() is not necessary for Diffie-Hellman, and this
+ specific range makes Diffie-Hellman unnecessarily inefficient if
+ dh->length (recommended exponent length) is much smaller than the
+ length of dh->p. We could use BN_rand_range() if the order of
+ the subgroup was stored in the DH structure, but we only have
+ dh->length.
+
+ So switch back to
+
+ BN_rand(priv_key, l, ...)
+
+ where 'l' is dh->length if this is defined, or BN_num_bits(dh->p)-1
+ otherwise.
+ [Bodo Moeller]
+
+ *) In
+
+ RSA_eay_public_encrypt
+ RSA_eay_private_decrypt
+ RSA_eay_private_encrypt (signing)
+ RSA_eay_public_decrypt (signature verification)
+
+ (default implementations for RSA_public_encrypt,
+ RSA_private_decrypt, RSA_private_encrypt, RSA_public_decrypt),
+ always reject numbers >= n.
+ [Bodo Moeller]
+
+ *) In crypto/rand/md_rand.c, use a new short-time lock CRYPTO_LOCK_RAND2
+ to synchronize access to 'locking_thread'. This is necessary on
+ systems where access to 'locking_thread' (an 'unsigned long'
+ variable) is not atomic.
+ [Bodo Moeller]
+
+ *) In crypto/rand/md_rand.c, set 'locking_thread' to current thread's ID
+ *before* setting the 'crypto_lock_rand' flag. The previous code had
+ a race condition if 0 is a valid thread ID.
+ [Travis Vitek <vitek@roguewave.com>]
+
+ *) Add support for shared libraries under Irix.
+ [Albert Chin-A-Young <china@thewrittenword.com>]
+
+ *) Add configuration option to build on Linux on both big-endian and
+ little-endian MIPS.
+ [Ralf Baechle <ralf@uni-koblenz.de>]
+
+ *) Add the possibility to create shared libraries on HP-UX.
+ [Richard Levitte]
+
+ Changes between 0.9.6a and 0.9.6b [9 Jul 2001]
+
+ *) Change ssleay_rand_bytes (crypto/rand/md_rand.c)
+ to avoid a SSLeay/OpenSSL PRNG weakness pointed out by
+ Markku-Juhani O. Saarinen <markku-juhani.saarinen@nokia.com>:
+ PRNG state recovery was possible based on the output of
+ one PRNG request appropriately sized to gain knowledge on
+ 'md' followed by enough consecutive 1-byte PRNG requests
+ to traverse all of 'state'.
+
+ 1. When updating 'md_local' (the current thread's copy of 'md')
+ during PRNG output generation, hash all of the previous
+ 'md_local' value, not just the half used for PRNG output.
+
+ 2. Make the number of bytes from 'state' included into the hash
+ independent from the number of PRNG bytes requested.
+
+ The first measure alone would be sufficient to avoid
+ Markku-Juhani's attack. (Actually it had never occurred
+ to me that the half of 'md_local' used for chaining was the
+ half from which PRNG output bytes were taken -- I had always
+ assumed that the secret half would be used.) The second
+ measure makes sure that additional data from 'state' is never
+ mixed into 'md_local' in small portions; this heuristically
+ further strengthens the PRNG.
+ [Bodo Moeller]
+
+ *) Fix crypto/bn/asm/mips3.s.
+ [Andy Polyakov]
+
+ *) When only the key is given to "enc", the IV is undefined. Print out
+ an error message in this case.
+ [Lutz Jaenicke]
+
+ *) Handle special case when X509_NAME is empty in X509 printing routines.
+ [Steve Henson]
+
+ *) In dsa_do_verify (crypto/dsa/dsa_ossl.c), verify that r and s are
+ positive and less than q.
+ [Bodo Moeller]
+
+ *) Don't change *pointer in CRYPTO_add_lock() is add_lock_callback is
+ used: it isn't thread safe and the add_lock_callback should handle
+ that itself.
+ [Paul Rose <Paul.Rose@bridge.com>]
+
+ *) Verify that incoming data obeys the block size in
+ ssl3_enc (ssl/s3_enc.c) and tls1_enc (ssl/t1_enc.c).
+ [Bodo Moeller]
+
+ *) Fix OAEP check.
+ [Ulf Möller, Bodo Möller]
+
+ *) The countermeasure against Bleichbacher's attack on PKCS #1 v1.5
+ RSA encryption was accidentally removed in s3_srvr.c in OpenSSL 0.9.5
+ when fixing the server behaviour for backwards-compatible 'client
+ hello' messages. (Note that the attack is impractical against
+ SSL 3.0 and TLS 1.0 anyway because length and version checking
+ means that the probability of guessing a valid ciphertext is
+ around 2^-40; see section 5 in Bleichenbacher's CRYPTO '98
+ paper.)
+
+ Before 0.9.5, the countermeasure (hide the error by generating a
+ random 'decryption result') did not work properly because
+ ERR_clear_error() was missing, meaning that SSL_get_error() would
+ detect the supposedly ignored error.
+
+ Both problems are now fixed.
+ [Bodo Moeller]
+
+ *) In crypto/bio/bf_buff.c, increase DEFAULT_BUFFER_SIZE to 4096
+ (previously it was 1024).
+ [Bodo Moeller]
+
+ *) Fix for compatibility mode trust settings: ignore trust settings
+ unless some valid trust or reject settings are present.
+ [Steve Henson]
+
+ *) Fix for blowfish EVP: its a variable length cipher.
+ [Steve Henson]
+
+ *) Fix various bugs related to DSA S/MIME verification. Handle missing
+ parameters in DSA public key structures and return an error in the
+ DSA routines if parameters are absent.
+ [Steve Henson]
+
+ *) In versions up to 0.9.6, RAND_file_name() resorted to file ".rnd"
+ in the current directory if neither $RANDFILE nor $HOME was set.
+ RAND_file_name() in 0.9.6a returned NULL in this case. This has
+ caused some confusion to Windows users who haven't defined $HOME.
+ Thus RAND_file_name() is changed again: e_os.h can define a
+ DEFAULT_HOME, which will be used if $HOME is not set.
+ For Windows, we use "C:"; on other platforms, we still require
+ environment variables.
+
+ *) Move 'if (!initialized) RAND_poll()' into regions protected by
+ CRYPTO_LOCK_RAND. This is not strictly necessary, but avoids
+ having multiple threads call RAND_poll() concurrently.
+ [Bodo Moeller]
+
+ *) In crypto/rand/md_rand.c, replace 'add_do_not_lock' flag by a
+ combination of a flag and a thread ID variable.
+ Otherwise while one thread is in ssleay_rand_bytes (which sets the
+ flag), *other* threads can enter ssleay_add_bytes without obeying
+ the CRYPTO_LOCK_RAND lock (and may even illegally release the lock
+ that they do not hold after the first thread unsets add_do_not_lock).
+ [Bodo Moeller]
+
+ *) Change bctest again: '-x' expressions are not available in all
+ versions of 'test'.
+ [Bodo Moeller]
+
+ Changes between 0.9.6 and 0.9.6a [5 Apr 2001]
+
+ *) Fix a couple of memory leaks in PKCS7_dataDecode()
+ [Steve Henson, reported by Heyun Zheng <hzheng@atdsprint.com>]
+
+ *) Change Configure and Makefiles to provide EXE_EXT, which will contain
+ the default extension for executables, if any. Also, make the perl
+ scripts that use symlink() to test if it really exists and use "cp"
+ if it doesn't. All this made OpenSSL compilable and installable in
+ CygWin.
+ [Richard Levitte]
+
+ *) Fix for asn1_GetSequence() for indefinite length constructed data.
+ If SEQUENCE is length is indefinite just set c->slen to the total
+ amount of data available.
+ [Steve Henson, reported by shige@FreeBSD.org]
+ [This change does not apply to 0.9.7.]
+
+ *) Change bctest to avoid here-documents inside command substitution
+ (workaround for FreeBSD /bin/sh bug).
+ For compatibility with Ultrix, avoid shell functions (introduced
+ in the bctest version that searches along $PATH).
+ [Bodo Moeller]
+
+ *) Rename 'des_encrypt' to 'des_encrypt1'. This avoids the clashes
+ with des_encrypt() defined on some operating systems, like Solaris
+ and UnixWare.
+ [Richard Levitte]
+
+ *) Check the result of RSA-CRT (see D. Boneh, R. DeMillo, R. Lipton:
+ On the Importance of Eliminating Errors in Cryptographic
+ Computations, J. Cryptology 14 (2001) 2, 101-119,
+ http://theory.stanford.edu/~dabo/papers/faults.ps.gz).
+ [Ulf Moeller]
+
+ *) MIPS assembler BIGNUM division bug fix.
+ [Andy Polyakov]
+
+ *) Disabled incorrect Alpha assembler code.
+ [Richard Levitte]
+
+ *) Fix PKCS#7 decode routines so they correctly update the length
+ after reading an EOC for the EXPLICIT tag.
+ [Steve Henson]
+ [This change does not apply to 0.9.7.]
+
+ *) Fix bug in PKCS#12 key generation routines. This was triggered
+ if a 3DES key was generated with a 0 initial byte. Include
+ PKCS12_BROKEN_KEYGEN compilation option to retain the old
+ (but broken) behaviour.
+ [Steve Henson]
+
+ *) Enhance bctest to search for a working bc along $PATH and print
+ it when found.
+ [Tim Rice <tim@multitalents.net> via Richard Levitte]
+
+ *) Fix memory leaks in err.c: free err_data string if necessary;
+ don't write to the wrong index in ERR_set_error_data.
+ [Bodo Moeller]
+
+ *) Implement ssl23_peek (analogous to ssl23_read), which previously
+ did not exist.
+ [Bodo Moeller]
+
+ *) Replace rdtsc with _emit statements for VC++ version 5.
+ [Jeremy Cooper <jeremy@baymoo.org>]
+
+ *) Make it possible to reuse SSLv2 sessions.
+ [Richard Levitte]
+
+ *) In copy_email() check for >= 0 as a return value for
+ X509_NAME_get_index_by_NID() since 0 is a valid index.
+ [Steve Henson reported by Massimiliano Pala <madwolf@opensca.org>]
+
+ *) Avoid coredump with unsupported or invalid public keys by checking if
+ X509_get_pubkey() fails in PKCS7_verify(). Fix memory leak when
+ PKCS7_verify() fails with non detached data.
+ [Steve Henson]
+
+ *) Don't use getenv in library functions when run as setuid/setgid.
+ New function OPENSSL_issetugid().
+ [Ulf Moeller]
+
+ *) Avoid false positives in memory leak detection code (crypto/mem_dbg.c)
+ due to incorrect handling of multi-threading:
+
+ 1. Fix timing glitch in the MemCheck_off() portion of CRYPTO_mem_ctrl().
+
+ 2. Fix logical glitch in is_MemCheck_on() aka CRYPTO_is_mem_check_on().
+
+ 3. Count how many times MemCheck_off() has been called so that
+ nested use can be treated correctly. This also avoids
+ inband-signalling in the previous code (which relied on the
+ assumption that thread ID 0 is impossible).
+ [Bodo Moeller]
+
+ *) Add "-rand" option also to s_client and s_server.
+ [Lutz Jaenicke]
+
+ *) Fix CPU detection on Irix 6.x.
+ [Kurt Hockenbury <khockenb@stevens-tech.edu> and
+ "Bruce W. Forsberg" <bruce.forsberg@baesystems.com>]
+
+ *) Fix X509_NAME bug which produced incorrect encoding if X509_NAME
+ was empty.
+ [Steve Henson]
+ [This change does not apply to 0.9.7.]
+
+ *) Use the cached encoding of an X509_NAME structure rather than
+ copying it. This is apparently the reason for the libsafe "errors"
+ but the code is actually correct.
+ [Steve Henson]
+
+ *) Add new function BN_rand_range(), and fix DSA_sign_setup() to prevent
+ Bleichenbacher's DSA attack.
+ Extend BN_[pseudo_]rand: As before, top=1 forces the highest two bits
+ to be set and top=0 forces the highest bit to be set; top=-1 is new
+ and leaves the highest bit random.
+ [Ulf Moeller, Bodo Moeller]
+
+ *) In the NCONF_...-based implementations for CONF_... queries
+ (crypto/conf/conf_lib.c), if the input LHASH is NULL, avoid using
+ a temporary CONF structure with the data component set to NULL
+ (which gives segmentation faults in lh_retrieve).
+ Instead, use NULL for the CONF pointer in CONF_get_string and
+ CONF_get_number (which may use environment variables) and directly
+ return NULL from CONF_get_section.
+ [Bodo Moeller]
+
+ *) Fix potential buffer overrun for EBCDIC.
+ [Ulf Moeller]
+
+ *) Tolerate nonRepudiation as being valid for S/MIME signing and certSign
+ keyUsage if basicConstraints absent for a CA.
+ [Steve Henson]
+
+ *) Make SMIME_write_PKCS7() write mail header values with a format that
+ is more generally accepted (no spaces before the semicolon), since
+ some programs can't parse those values properly otherwise. Also make
+ sure BIO's that break lines after each write do not create invalid
+ headers.
+ [Richard Levitte]
+
+ *) Make the CRL encoding routines work with empty SEQUENCE OF. The
+ macros previously used would not encode an empty SEQUENCE OF
+ and break the signature.
+ [Steve Henson]
+ [This change does not apply to 0.9.7.]
+
+ *) Zero the premaster secret after deriving the master secret in
+ DH ciphersuites.
+ [Steve Henson]
+
+ *) Add some EVP_add_digest_alias registrations (as found in
+ OpenSSL_add_all_digests()) to SSL_library_init()
+ aka OpenSSL_add_ssl_algorithms(). This provides improved
+ compatibility with peers using X.509 certificates
+ with unconventional AlgorithmIdentifier OIDs.
+ [Bodo Moeller]
+
+ *) Fix for Irix with NO_ASM.
+ ["Bruce W. Forsberg" <bruce.forsberg@baesystems.com>]
+
+ *) ./config script fixes.
+ [Ulf Moeller, Richard Levitte]
+
+ *) Fix 'openssl passwd -1'.
+ [Bodo Moeller]
+
+ *) Change PKCS12_key_gen_asc() so it can cope with non null
+ terminated strings whose length is passed in the passlen
+ parameter, for example from PEM callbacks. This was done
+ by adding an extra length parameter to asc2uni().
+ [Steve Henson, reported by <oddissey@samsung.co.kr>]
+
+ *) Fix C code generated by 'openssl dsaparam -C': If a BN_bin2bn
+ call failed, free the DSA structure.
+ [Bodo Moeller]
+
+ *) Fix to uni2asc() to cope with zero length Unicode strings.
+ These are present in some PKCS#12 files.
+ [Steve Henson]
+
+ *) Increase s2->wbuf allocation by one byte in ssl2_new (ssl/s2_lib.c).
+ Otherwise do_ssl_write (ssl/s2_pkt.c) will write beyond buffer limits
+ when writing a 32767 byte record.
+ [Bodo Moeller; problem reported by Eric Day <eday@concentric.net>]
+
+ *) In RSA_eay_public_{en,ed}crypt and RSA_eay_mod_exp (rsa_eay.c),
+ obtain lock CRYPTO_LOCK_RSA before setting rsa->_method_mod_{n,p,q}.
+
+ (RSA objects have a reference count access to which is protected
+ by CRYPTO_LOCK_RSA [see rsa_lib.c, s3_srvr.c, ssl_cert.c, ssl_rsa.c],
+ so they are meant to be shared between threads.)
+ [Bodo Moeller, Geoff Thorpe; original patch submitted by
+ "Reddie, Steven" <Steven.Reddie@ca.com>]
+
+ *) Fix a deadlock in CRYPTO_mem_leaks().
+ [Bodo Moeller]
+
+ *) Use better test patterns in bntest.
+ [Ulf Möller]
+
+ *) rand_win.c fix for Borland C.
+ [Ulf Möller]
+
+ *) BN_rshift bugfix for n == 0.
+ [Bodo Moeller]
+
+ *) Add a 'bctest' script that checks for some known 'bc' bugs
+ so that 'make test' does not abort just because 'bc' is broken.
+ [Bodo Moeller]
+
+ *) Store verify_result within SSL_SESSION also for client side to
+ avoid potential security hole. (Re-used sessions on the client side
+ always resulted in verify_result==X509_V_OK, not using the original
+ result of the server certificate verification.)
+ [Lutz Jaenicke]
+
+ *) Fix ssl3_pending: If the record in s->s3->rrec is not of type
+ SSL3_RT_APPLICATION_DATA, return 0.
+ Similarly, change ssl2_pending to return 0 if SSL_in_init(s) is true.
+ [Bodo Moeller]
+
+ *) Fix SSL_peek:
+ Both ssl2_peek and ssl3_peek, which were totally broken in earlier
+ releases, have been re-implemented by renaming the previous
+ implementations of ssl2_read and ssl3_read to ssl2_read_internal
+ and ssl3_read_internal, respectively, and adding 'peek' parameters
+ to them. The new ssl[23]_{read,peek} functions are calls to
+ ssl[23]_read_internal with the 'peek' flag set appropriately.
+ A 'peek' parameter has also been added to ssl3_read_bytes, which
+ does the actual work for ssl3_read_internal.
+ [Bodo Moeller]
+
+ *) Initialise "ex_data" member of RSA/DSA/DH structures prior to calling
+ the method-specific "init()" handler. Also clean up ex_data after
+ calling the method-specific "finish()" handler. Previously, this was
+ happening the other way round.
+ [Geoff Thorpe]
+
+ *) Increase BN_CTX_NUM (the number of BIGNUMs in a BN_CTX) to 16.
+ The previous value, 12, was not always sufficient for BN_mod_exp().
+ [Bodo Moeller]
+
+ *) Make sure that shared libraries get the internal name engine with
+ the full version number and not just 0. This should mark the
+ shared libraries as not backward compatible. Of course, this should
+ be changed again when we can guarantee backward binary compatibility.
+ [Richard Levitte]
+
+ *) Fix typo in get_cert_by_subject() in by_dir.c
+ [Jean-Marc Desperrier <jean-marc.desperrier@certplus.com>]
+
+ *) Rework the system to generate shared libraries:
+
+ - Make note of the expected extension for the shared libraries and
+ if there is a need for symbolic links from for example libcrypto.so.0
+ to libcrypto.so.0.9.7. There is extended info in Configure for
+ that.
+
+ - Make as few rebuilds of the shared libraries as possible.
+
+ - Still avoid linking the OpenSSL programs with the shared libraries.
+
+ - When installing, install the shared libraries separately from the
+ static ones.
+ [Richard Levitte]
+
+ *) Fix SSL_CTX_set_read_ahead macro to actually use its argument.
+
+ Copy SSL_CTX's read_ahead flag to SSL object directly in SSL_new
+ and not in SSL_clear because the latter is also used by the
+ accept/connect functions; previously, the settings made by
+ SSL_set_read_ahead would be lost during the handshake.
+ [Bodo Moeller; problems reported by Anders Gertz <gertz@epact.se>]
+
+ *) Correct util/mkdef.pl to be selective about disabled algorithms.
+ Previously, it would create entries for disableed algorithms no
+ matter what.
+ [Richard Levitte]
+
+ *) Added several new manual pages for SSL_* function.
+ [Lutz Jaenicke]
+
+ Changes between 0.9.5a and 0.9.6 [24 Sep 2000]
+
+ *) In ssl23_get_client_hello, generate an error message when faced
+ with an initial SSL 3.0/TLS record that is too small to contain the
+ first two bytes of the ClientHello message, i.e. client_version.
+ (Note that this is a pathologic case that probably has never happened
+ in real life.) The previous approach was to use the version number
+ from the record header as a substitute; but our protocol choice
+ should not depend on that one because it is not authenticated
+ by the Finished messages.
+ [Bodo Moeller]
+
+ *) More robust randomness gathering functions for Windows.
+ [Jeffrey Altman <jaltman@columbia.edu>]
+
+ *) For compatibility reasons if the flag X509_V_FLAG_ISSUER_CHECK is
+ not set then we don't setup the error code for issuer check errors
+ to avoid possibly overwriting other errors which the callback does
+ handle. If an application does set the flag then we assume it knows
+ what it is doing and can handle the new informational codes
+ appropriately.
+ [Steve Henson]
+
+ *) Fix for a nasty bug in ASN1_TYPE handling. ASN1_TYPE is used for
+ a general "ANY" type, as such it should be able to decode anything
+ including tagged types. However it didn't check the class so it would
+ wrongly interpret tagged types in the same way as their universal
+ counterpart and unknown types were just rejected. Changed so that the
+ tagged and unknown types are handled in the same way as a SEQUENCE:
+ that is the encoding is stored intact. There is also a new type
+ "V_ASN1_OTHER" which is used when the class is not universal, in this
+ case we have no idea what the actual type is so we just lump them all
+ together.
+ [Steve Henson]
+
+ *) On VMS, stdout may very well lead to a file that is written to
+ in a record-oriented fashion. That means that every write() will
+ write a separate record, which will be read separately by the
+ programs trying to read from it. This can be very confusing.
+
+ The solution is to put a BIO filter in the way that will buffer
+ text until a linefeed is reached, and then write everything a
+ line at a time, so every record written will be an actual line,
+ not chunks of lines and not (usually doesn't happen, but I've
+ seen it once) several lines in one record. BIO_f_linebuffer() is
+ the answer.
+
+ Currently, it's a VMS-only method, because that's where it has
+ been tested well enough.
+ [Richard Levitte]
+
+ *) Remove 'optimized' squaring variant in BN_mod_mul_montgomery,
+ it can return incorrect results.
+ (Note: The buggy variant was not enabled in OpenSSL 0.9.5a,
+ but it was in 0.9.6-beta[12].)
+ [Bodo Moeller]
+
+ *) Disable the check for content being present when verifying detached
+ signatures in pk7_smime.c. Some versions of Netscape (wrongly)
+ include zero length content when signing messages.
+ [Steve Henson]
+
+ *) New BIO_shutdown_wr macro, which invokes the BIO_C_SHUTDOWN_WR
+ BIO_ctrl (for BIO pairs).
+ [Bodo Möller]
+
+ *) Add DSO method for VMS.
+ [Richard Levitte]
+
+ *) Bug fix: Montgomery multiplication could produce results with the
+ wrong sign.
+ [Ulf Möller]
+
+ *) Add RPM specification openssl.spec and modify it to build three
+ packages. The default package contains applications, application
+ documentation and run-time libraries. The devel package contains
+ include files, static libraries and function documentation. The
+ doc package contains the contents of the doc directory. The original
+ openssl.spec was provided by Damien Miller <djm@mindrot.org>.
+ [Richard Levitte]
+
+ *) Add a large number of documentation files for many SSL routines.
+ [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>]
+
+ *) Add a configuration entry for Sony News 4.
+ [NAKAJI Hiroyuki <nakaji@tutrp.tut.ac.jp>]
+
+ *) Don't set the two most significant bits to one when generating a
+ random number < q in the DSA library.
+ [Ulf Möller]
+
+ *) New SSL API mode 'SSL_MODE_AUTO_RETRY'. This disables the default
+ behaviour that SSL_read may result in SSL_ERROR_WANT_READ (even if
+ the underlying transport is blocking) if a handshake took place.
+ (The default behaviour is needed by applications such as s_client
+ and s_server that use select() to determine when to use SSL_read;
+ but for applications that know in advance when to expect data, it
+ just makes things more complicated.)
+ [Bodo Moeller]
+
+ *) Add RAND_egd_bytes(), which gives control over the number of bytes read
+ from EGD.
+ [Ben Laurie]
+
+ *) Add a few more EBCDIC conditionals that make `req' and `x509'
+ work better on such systems.
+ [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
+
+ *) Add two demo programs for PKCS12_parse() and PKCS12_create().
+ Update PKCS12_parse() so it copies the friendlyName and the
+ keyid to the certificates aux info.
+ [Steve Henson]
+
+ *) Fix bug in PKCS7_verify() which caused an infinite loop
+ if there was more than one signature.
+ [Sven Uszpelkat <su@celocom.de>]
+
+ *) Major change in util/mkdef.pl to include extra information
+ about each symbol, as well as presentig variables as well
+ as functions. This change means that there's n more need
+ to rebuild the .num files when some algorithms are excluded.
+ [Richard Levitte]
+
+ *) Allow the verify time to be set by an application,
+ rather than always using the current time.
+ [Steve Henson]
+
+ *) Phase 2 verify code reorganisation. The certificate
+ verify code now looks up an issuer certificate by a
+ number of criteria: subject name, authority key id
+ and key usage. It also verifies self signed certificates
+ by the same criteria. The main comparison function is
+ X509_check_issued() which performs these checks.
+
+ Lot of changes were necessary in order to support this
+ without completely rewriting the lookup code.
+
+ Authority and subject key identifier are now cached.
+
+ The LHASH 'certs' is X509_STORE has now been replaced
+ by a STACK_OF(X509_OBJECT). This is mainly because an
+ LHASH can't store or retrieve multiple objects with
+ the same hash value.
+
+ As a result various functions (which were all internal
+ use only) have changed to handle the new X509_STORE
+ structure. This will break anything that messed round
+ with X509_STORE internally.
+
+ The functions X509_STORE_add_cert() now checks for an
+ exact match, rather than just subject name.
+
+ The X509_STORE API doesn't directly support the retrieval
+ of multiple certificates matching a given criteria, however
+ this can be worked round by performing a lookup first
+ (which will fill the cache with candidate certificates)
+ and then examining the cache for matches. This is probably
+ the best we can do without throwing out X509_LOOKUP
+ entirely (maybe later...).
+
+ The X509_VERIFY_CTX structure has been enhanced considerably.
+
+ All certificate lookup operations now go via a get_issuer()
+ callback. Although this currently uses an X509_STORE it
+ can be replaced by custom lookups. This is a simple way
+ to bypass the X509_STORE hackery necessary to make this
+ work and makes it possible to use more efficient techniques
+ in future. A very simple version which uses a simple
+ STACK for its trusted certificate store is also provided
+ using X509_STORE_CTX_trusted_stack().
+
+ The verify_cb() and verify() callbacks now have equivalents
+ in the X509_STORE_CTX structure.
+
+ X509_STORE_CTX also has a 'flags' field which can be used
+ to customise the verify behaviour.
+ [Steve Henson]
+
+ *) Add new PKCS#7 signing option PKCS7_NOSMIMECAP which
+ excludes S/MIME capabilities.
+ [Steve Henson]
+
+ *) When a certificate request is read in keep a copy of the
+ original encoding of the signed data and use it when outputing
+ again. Signatures then use the original encoding rather than
+ a decoded, encoded version which may cause problems if the
+ request is improperly encoded.
+ [Steve Henson]
+
+ *) For consistency with other BIO_puts implementations, call
+ buffer_write(b, ...) directly in buffer_puts instead of calling
+ BIO_write(b, ...).
+
+ In BIO_puts, increment b->num_write as in BIO_write.
+ [Peter.Sylvester@EdelWeb.fr]
+
+ *) Fix BN_mul_word for the case where the word is 0. (We have to use
+ BN_zero, we may not return a BIGNUM with an array consisting of
+ words set to zero.)
+ [Bodo Moeller]
+
+ *) Avoid calling abort() from within the library when problems are
+ detected, except if preprocessor symbols have been defined
+ (such as REF_CHECK, BN_DEBUG etc.).
+ [Bodo Moeller]
+
+ *) New openssl application 'rsautl'. This utility can be
+ used for low level RSA operations. DER public key
+ BIO/fp routines also added.
+ [Steve Henson]
+
+ *) New Configure entry and patches for compiling on QNX 4.
+ [Andreas Schneider <andreas@ds3.etech.fh-hamburg.de>]
+
+ *) A demo state-machine implementation was sponsored by
+ Nuron (http://www.nuron.com/) and is now available in
+ demos/state_machine.
+ [Ben Laurie]
+
+ *) New options added to the 'dgst' utility for signature
+ generation and verification.
+ [Steve Henson]
+
+ *) Unrecognized PKCS#7 content types are now handled via a
+ catch all ASN1_TYPE structure. This allows unsupported
+ types to be stored as a "blob" and an application can
+ encode and decode it manually.
+ [Steve Henson]
+
+ *) Fix various signed/unsigned issues to make a_strex.c
+ compile under VC++.
+ [Oscar Jacobsson <oscar.jacobsson@celocom.com>]
+
+ *) ASN1 fixes. i2d_ASN1_OBJECT was not returning the correct
+ length if passed a buffer. ASN1_INTEGER_to_BN failed
+ if passed a NULL BN and its argument was negative.
+ [Steve Henson, pointed out by Sven Heiberg <sven@tartu.cyber.ee>]
+
+ *) Modification to PKCS#7 encoding routines to output definite
+ length encoding. Since currently the whole structures are in
+ memory there's not real point in using indefinite length
+ constructed encoding. However if OpenSSL is compiled with
+ the flag PKCS7_INDEFINITE_ENCODING the old form is used.
+ [Steve Henson]
+
+ *) Added BIO_vprintf() and BIO_vsnprintf().
+ [Richard Levitte]
+
+ *) Added more prefixes to parse for in the the strings written
+ through a logging bio, to cover all the levels that are available
+ through syslog. The prefixes are now:
+
+ PANIC, EMERG, EMR => LOG_EMERG
+ ALERT, ALR => LOG_ALERT
+ CRIT, CRI => LOG_CRIT
+ ERROR, ERR => LOG_ERR
+ WARNING, WARN, WAR => LOG_WARNING
+ NOTICE, NOTE, NOT => LOG_NOTICE
+ INFO, INF => LOG_INFO
+ DEBUG, DBG => LOG_DEBUG
+
+ and as before, if none of those prefixes are present at the
+ beginning of the string, LOG_ERR is chosen.
+
+ On Win32, the LOG_* levels are mapped according to this:
+
+ LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR => EVENTLOG_ERROR_TYPE
+ LOG_WARNING => EVENTLOG_WARNING_TYPE
+ LOG_NOTICE, LOG_INFO, LOG_DEBUG => EVENTLOG_INFORMATION_TYPE
+
+ [Richard Levitte]
+
+ *) Made it possible to reconfigure with just the configuration
+ argument "reconf" or "reconfigure". The command line arguments
+ are stored in Makefile.ssl in the variable CONFIGURE_ARGS,
+ and are retrieved from there when reconfiguring.
+ [Richard Levitte]
+
+ *) MD4 implemented.
+ [Assar Westerlund <assar@sics.se>, Richard Levitte]
+
+ *) Add the arguments -CAfile and -CApath to the pkcs12 utility.
+ [Richard Levitte]
+
+ *) The obj_dat.pl script was messing up the sorting of object
+ names. The reason was that it compared the quoted version
+ of strings as a result "OCSP" > "OCSP Signing" because
+ " > SPACE. Changed script to store unquoted versions of
+ names and add quotes on output. It was also omitting some
+ names from the lookup table if they were given a default
+ value (that is if SN is missing it is given the same
+ value as LN and vice versa), these are now added on the
+ grounds that if an object has a name we should be able to
+ look it up. Finally added warning output when duplicate
+ short or long names are found.
+ [Steve Henson]
+
+ *) Changes needed for Tandem NSK.
+ [Scott Uroff <scott@xypro.com>]
+
+ *) Fix SSL 2.0 rollback checking: Due to an off-by-one error in
+ RSA_padding_check_SSLv23(), special padding was never detected
+ and thus the SSL 3.0/TLS 1.0 countermeasure against protocol
+ version rollback attacks was not effective.
+
+ In s23_clnt.c, don't use special rollback-attack detection padding
+ (RSA_SSLV23_PADDING) if SSL 2.0 is the only protocol enabled in the
+ client; similarly, in s23_srvr.c, don't do the rollback check if
+ SSL 2.0 is the only protocol enabled in the server.
+ [Bodo Moeller]
+
+ *) Make it possible to get hexdumps of unprintable data with 'openssl
+ asn1parse'. By implication, the functions ASN1_parse_dump() and
+ BIO_dump_indent() are added.
+ [Richard Levitte]
+
+ *) New functions ASN1_STRING_print_ex() and X509_NAME_print_ex()
+ these print out strings and name structures based on various
+ flags including RFC2253 support and proper handling of
+ multibyte characters. Added options to the 'x509' utility
+ to allow the various flags to be set.
+ [Steve Henson]
+
+ *) Various fixes to use ASN1_TIME instead of ASN1_UTCTIME.
+ Also change the functions X509_cmp_current_time() and
+ X509_gmtime_adj() work with an ASN1_TIME structure,
+ this will enable certificates using GeneralizedTime in validity
+ dates to be checked.
+ [Steve Henson]
+
+ *) Make the NEG_PUBKEY_BUG code (which tolerates invalid
+ negative public key encodings) on by default,
+ NO_NEG_PUBKEY_BUG can be set to disable it.
+ [Steve Henson]
+
+ *) New function c2i_ASN1_OBJECT() which acts on ASN1_OBJECT
+ content octets. An i2c_ASN1_OBJECT is unnecessary because
+ the encoding can be trivially obtained from the structure.
+ [Steve Henson]
+
+ *) crypto/err.c locking bugfix: Use write locks (CRYPTO_w_[un]lock),
+ not read locks (CRYPTO_r_[un]lock).
+ [Bodo Moeller]
+
+ *) A first attempt at creating official support for shared
+ libraries through configuration. I've kept it so the
+ default is static libraries only, and the OpenSSL programs
+ are always statically linked for now, but there are
+ preparations for dynamic linking in place.
+ This has been tested on Linux and Tru64.
+ [Richard Levitte]
+
+ *) Randomness polling function for Win9x, as described in:
+ Peter Gutmann, Software Generation of Practically Strong
+ Random Numbers.
+ [Ulf Möller]
+
+ *) Fix so PRNG is seeded in req if using an already existing
+ DSA key.
+ [Steve Henson]
+
+ *) New options to smime application. -inform and -outform
+ allow alternative formats for the S/MIME message including
+ PEM and DER. The -content option allows the content to be
+ specified separately. This should allow things like Netscape
+ form signing output easier to verify.
+ [Steve Henson]
+
+ *) Fix the ASN1 encoding of tags using the 'long form'.
+ [Steve Henson]
+
+ *) New ASN1 functions, i2c_* and c2i_* for INTEGER and BIT
+ STRING types. These convert content octets to and from the
+ underlying type. The actual tag and length octets are
+ already assumed to have been read in and checked. These
+ are needed because all other string types have virtually
+ identical handling apart from the tag. By having versions
+ of the ASN1 functions that just operate on content octets
+ IMPLICIT tagging can be handled properly. It also allows
+ the ASN1_ENUMERATED code to be cut down because ASN1_ENUMERATED
+ and ASN1_INTEGER are identical apart from the tag.
+ [Steve Henson]
+
+ *) Change the handling of OID objects as follows:
+
+ - New object identifiers are inserted in objects.txt, following
+ the syntax given in objects.README.
+ - objects.pl is used to process obj_mac.num and create a new
+ obj_mac.h.
+ - obj_dat.pl is used to create a new obj_dat.h, using the data in
+ obj_mac.h.
+
+ This is currently kind of a hack, and the perl code in objects.pl
+ isn't very elegant, but it works as I intended. The simplest way
+ to check that it worked correctly is to look in obj_dat.h and
+ check the array nid_objs and make sure the objects haven't moved
+ around (this is important!). Additions are OK, as well as
+ consistent name changes.
+ [Richard Levitte]
+
+ *) Add BSD-style MD5-based passwords to 'openssl passwd' (option '-1').
+ [Bodo Moeller]
+
+ *) Addition of the command line parameter '-rand file' to 'openssl req'.
+ The given file adds to whatever has already been seeded into the
+ random pool through the RANDFILE configuration file option or
+ environment variable, or the default random state file.
+ [Richard Levitte]
+
+ *) mkstack.pl now sorts each macro group into lexical order.
+ Previously the output order depended on the order the files
+ appeared in the directory, resulting in needless rewriting
+ of safestack.h .
+ [Steve Henson]
+
+ *) Patches to make OpenSSL compile under Win32 again. Mostly
+ work arounds for the VC++ problem that it treats func() as
+ func(void). Also stripped out the parts of mkdef.pl that
+ added extra typesafe functions: these no longer exist.
+ [Steve Henson]
+
+ *) Reorganisation of the stack code. The macros are now all
+ collected in safestack.h . Each macro is defined in terms of
+ a "stack macro" of the form SKM_<name>(type, a, b). The
+ DEBUG_SAFESTACK is now handled in terms of function casts,
+ this has the advantage of retaining type safety without the
+ use of additional functions. If DEBUG_SAFESTACK is not defined
+ then the non typesafe macros are used instead. Also modified the
+ mkstack.pl script to handle the new form. Needs testing to see
+ if which (if any) compilers it chokes and maybe make DEBUG_SAFESTACK
+ the default if no major problems. Similar behaviour for ASN1_SET_OF
+ and PKCS12_STACK_OF.
+ [Steve Henson]
+
+ *) When some versions of IIS use the 'NET' form of private key the
+ key derivation algorithm is different. Normally MD5(password) is
+ used as a 128 bit RC4 key. In the modified case
+ MD5(MD5(password) + "SGCKEYSALT") is used insted. Added some
+ new functions i2d_RSA_NET(), d2i_RSA_NET() etc which are the same
+ as the old Netscape_RSA functions except they have an additional
+ 'sgckey' parameter which uses the modified algorithm. Also added
+ an -sgckey command line option to the rsa utility. Thanks to
+ Adrian Peck <bertie@ncipher.com> for posting details of the modified
+ algorithm to openssl-dev.
+ [Steve Henson]
+
+ *) The evp_local.h macros were using 'c.##kname' which resulted in
+ invalid expansion on some systems (SCO 5.0.5 for example).
+ Corrected to 'c.kname'.
+ [Phillip Porch <root@theporch.com>]
+
+ *) New X509_get1_email() and X509_REQ_get1_email() functions that return
+ a STACK of email addresses from a certificate or request, these look
+ in the subject name and the subject alternative name extensions and
+ omit any duplicate addresses.
+ [Steve Henson]
+
+ *) Re-implement BN_mod_exp2_mont using independent (and larger) windows.
+ This makes DSA verification about 2 % faster.
+ [Bodo Moeller]
+
+ *) Increase maximum window size in BN_mod_exp_... to 6 bits instead of 5
+ (meaning that now 2^5 values will be precomputed, which is only 4 KB
+ plus overhead for 1024 bit moduli).
+ This makes exponentiations about 0.5 % faster for 1024 bit
+ exponents (as measured by "openssl speed rsa2048").
+ [Bodo Moeller]
+
+ *) Rename memory handling macros to avoid conflicts with other
+ software:
+ Malloc => OPENSSL_malloc
+ Malloc_locked => OPENSSL_malloc_locked
+ Realloc => OPENSSL_realloc
+ Free => OPENSSL_free
+ [Richard Levitte]
+
+ *) New function BN_mod_exp_mont_word for small bases (roughly 15%
+ faster than BN_mod_exp_mont, i.e. 7% for a full DH exchange).
+ [Bodo Moeller]
+
+ *) CygWin32 support.
+ [John Jarvie <jjarvie@newsguy.com>]
+
+ *) The type-safe stack code has been rejigged. It is now only compiled
+ in when OpenSSL is configured with the DEBUG_SAFESTACK option and
+ by default all type-specific stack functions are "#define"d back to
+ standard stack functions. This results in more streamlined output
+ but retains the type-safety checking possibilities of the original
+ approach.
+ [Geoff Thorpe]
+
+ *) The STACK code has been cleaned up, and certain type declarations
+ that didn't make a lot of sense have been brought in line. This has
+ also involved a cleanup of sorts in safestack.h to more correctly
+ map type-safe stack functions onto their plain stack counterparts.
+ This work has also resulted in a variety of "const"ifications of
+ lots of the code, especially "_cmp" operations which should normally
+ be prototyped with "const" parameters anyway.
+ [Geoff Thorpe]
+
+ *) When generating bytes for the first time in md_rand.c, 'stir the pool'
+ by seeding with STATE_SIZE dummy bytes (with zero entropy count).
+ (The PRNG state consists of two parts, the large pool 'state' and 'md',
+ where all of 'md' is used each time the PRNG is used, but 'state'
+ is used only indexed by a cyclic counter. As entropy may not be
+ well distributed from the beginning, 'md' is important as a
+ chaining variable. However, the output function chains only half
+ of 'md', i.e. 80 bits. ssleay_rand_add, on the other hand, chains
+ all of 'md', and seeding with STATE_SIZE dummy bytes will result
+ in all of 'state' being rewritten, with the new values depending
+ on virtually all of 'md'. This overcomes the 80 bit limitation.)
+ [Bodo Moeller]
+
+ *) In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when
+ the handshake is continued after ssl_verify_cert_chain();
+ otherwise, if SSL_VERIFY_NONE is set, remaining error codes
+ can lead to 'unexplainable' connection aborts later.
+ [Bodo Moeller; problem tracked down by Lutz Jaenicke]
+
+ *) Major EVP API cipher revision.
+ Add hooks for extra EVP features. This allows various cipher
+ parameters to be set in the EVP interface. Support added for variable
+ key length ciphers via the EVP_CIPHER_CTX_set_key_length() function and
+ setting of RC2 and RC5 parameters.
+
+ Modify EVP_OpenInit() and EVP_SealInit() to cope with variable key length
+ ciphers.
+
+ Remove lots of duplicated code from the EVP library. For example *every*
+ cipher init() function handles the 'iv' in the same way according to the
+ cipher mode. They also all do nothing if the 'key' parameter is NULL and
+ for CFB and OFB modes they zero ctx->num.
+
+ New functionality allows removal of S/MIME code RC2 hack.
+
+ Most of the routines have the same form and so can be declared in terms
+ of macros.
+
+ By shifting this to the top level EVP_CipherInit() it can be removed from
+ all individual ciphers. If the cipher wants to handle IVs or keys
+ differently it can set the EVP_CIPH_CUSTOM_IV or EVP_CIPH_ALWAYS_CALL_INIT
+ flags.
+
+ Change lots of functions like EVP_EncryptUpdate() to now return a
+ value: although software versions of the algorithms cannot fail
+ any installed hardware versions can.
+ [Steve Henson]
+
+ *) Implement SSL_OP_TLS_ROLLBACK_BUG: In ssl3_get_client_key_exchange, if
+ this option is set, tolerate broken clients that send the negotiated
+ protocol version number instead of the requested protocol version
+ number.
+ [Bodo Moeller]
+
+ *) Call dh_tmp_cb (set by ..._TMP_DH_CB) with correct 'is_export' flag;
+ i.e. non-zero for export ciphersuites, zero otherwise.
+ Previous versions had this flag inverted, inconsistent with
+ rsa_tmp_cb (..._TMP_RSA_CB).
+ [Bodo Moeller; problem reported by Amit Chopra]
+
+ *) Add missing DSA library text string. Work around for some IIS
+ key files with invalid SEQUENCE encoding.
+ [Steve Henson]
+
+ *) Add a document (doc/standards.txt) that list all kinds of standards
+ and so on that are implemented in OpenSSL.
+ [Richard Levitte]
+
+ *) Enhance c_rehash script. Old version would mishandle certificates
+ with the same subject name hash and wouldn't handle CRLs at all.
+ Added -fingerprint option to crl utility, to support new c_rehash
+ features.
+ [Steve Henson]
+
+ *) Eliminate non-ANSI declarations in crypto.h and stack.h.
+ [Ulf Möller]
+
+ *) Fix for SSL server purpose checking. Server checking was
+ rejecting certificates which had extended key usage present
+ but no ssl client purpose.
+ [Steve Henson, reported by Rene Grosser <grosser@hisolutions.com>]
+
+ *) Make PKCS#12 code work with no password. The PKCS#12 spec
+ is a little unclear about how a blank password is handled.
+ Since the password in encoded as a BMPString with terminating
+ double NULL a zero length password would end up as just the
+ double NULL. However no password at all is different and is
+ handled differently in the PKCS#12 key generation code. NS
+ treats a blank password as zero length. MSIE treats it as no
+ password on export: but it will try both on import. We now do
+ the same: PKCS12_parse() tries zero length and no password if
+ the password is set to "" or NULL (NULL is now a valid password:
+ it wasn't before) as does the pkcs12 application.
+ [Steve Henson]
+
+ *) Bugfixes in apps/x509.c: Avoid a memory leak; and don't use
+ perror when PEM_read_bio_X509_REQ fails, the error message must
+ be obtained from the error queue.
+ [Bodo Moeller]
+
+ *) Avoid 'thread_hash' memory leak in crypto/err/err.c by freeing
+ it in ERR_remove_state if appropriate, and change ERR_get_state
+ accordingly to avoid race conditions (this is necessary because
+ thread_hash is no longer constant once set).
+ [Bodo Moeller]
+
+ *) Bugfix for linux-elf makefile.one.
+ [Ulf Möller]
+
+ *) RSA_get_default_method() will now cause a default
+ RSA_METHOD to be chosen if one doesn't exist already.
+ Previously this was only set during a call to RSA_new()
+ or RSA_new_method(NULL) meaning it was possible for
+ RSA_get_default_method() to return NULL.
+ [Geoff Thorpe]
+
+ *) Added native name translation to the existing DSO code
+ that will convert (if the flag to do so is set) filenames
+ that are sufficiently small and have no path information
+ into a canonical native form. Eg. "blah" converted to
+ "libblah.so" or "blah.dll" etc.
+ [Geoff Thorpe]
+
+ *) New function ERR_error_string_n(e, buf, len) which is like
+ ERR_error_string(e, buf), but writes at most 'len' bytes
+ including the 0 terminator. For ERR_error_string_n, 'buf'
+ may not be NULL.
+ [Damien Miller <djm@mindrot.org>, Bodo Moeller]
+
+ *) CONF library reworked to become more general. A new CONF
+ configuration file reader "class" is implemented as well as a
+ new functions (NCONF_*, for "New CONF") to handle it. The now
+ old CONF_* functions are still there, but are reimplemented to
+ work in terms of the new functions. Also, a set of functions
+ to handle the internal storage of the configuration data is
+ provided to make it easier to write new configuration file
+ reader "classes" (I can definitely see something reading a
+ configuration file in XML format, for example), called _CONF_*,
+ or "the configuration storage API"...
+
+ The new configuration file reading functions are:
+
+ NCONF_new, NCONF_free, NCONF_load, NCONF_load_fp, NCONF_load_bio,
+ NCONF_get_section, NCONF_get_string, NCONF_get_numbre
+
+ NCONF_default, NCONF_WIN32
+
+ NCONF_dump_fp, NCONF_dump_bio
+
+ NCONF_default and NCONF_WIN32 are method (or "class") choosers,
+ NCONF_new creates a new CONF object. This works in the same way
+ as other interfaces in OpenSSL, like the BIO interface.
+ NCONF_dump_* dump the internal storage of the configuration file,
+ which is useful for debugging. All other functions take the same
+ arguments as the old CONF_* functions wth the exception of the
+ first that must be a `CONF *' instead of a `LHASH *'.
+
+ To make it easer to use the new classes with the old CONF_* functions,
+ the function CONF_set_default_method is provided.
+ [Richard Levitte]
+
+ *) Add '-tls1' option to 'openssl ciphers', which was already
+ mentioned in the documentation but had not been implemented.
+ (This option is not yet really useful because even the additional
+ experimental TLS 1.0 ciphers are currently treated as SSL 3.0 ciphers.)
+ [Bodo Moeller]
+
+ *) Initial DSO code added into libcrypto for letting OpenSSL (and
+ OpenSSL-based applications) load shared libraries and bind to
+ them in a portable way.
+ [Geoff Thorpe, with contributions from Richard Levitte]
+
+ Changes between 0.9.5 and 0.9.5a [1 Apr 2000]
+
+ *) Make sure _lrotl and _lrotr are only used with MSVC.
+
+ *) Use lock CRYPTO_LOCK_RAND correctly in ssleay_rand_status
+ (the default implementation of RAND_status).
+
+ *) Rename openssl x509 option '-crlext', which was added in 0.9.5,
+ to '-clrext' (= clear extensions), as intended and documented.
+ [Bodo Moeller; inconsistency pointed out by Michael Attili
+ <attili@amaxo.com>]
+
+ *) Fix for HMAC. It wasn't zeroing the rest of the block if the key length
+ was larger than the MD block size.
+ [Steve Henson, pointed out by Yost William <YostW@tce.com>]
+
+ *) Modernise PKCS12_parse() so it uses STACK_OF(X509) for its ca argument
+ fix a leak when the ca argument was passed as NULL. Stop X509_PUBKEY_set()
+ using the passed key: if the passed key was a private key the result
+ of X509_print(), for example, would be to print out all the private key
+ components.
+ [Steve Henson]
+
+ *) des_quad_cksum() byte order bug fix.
+ [Ulf Möller, using the problem description in krb4-0.9.7, where
+ the solution is attributed to Derrick J Brashear <shadow@DEMENTIA.ORG>]
+
+ *) Fix so V_ASN1_APP_CHOOSE works again: however its use is strongly
+ discouraged.
+ [Steve Henson, pointed out by Brian Korver <briank@cs.stanford.edu>]
+
+ *) For easily testing in shell scripts whether some command
+ 'openssl XXX' exists, the new pseudo-command 'openssl no-XXX'
+ returns with exit code 0 iff no command of the given name is available.
+ 'no-XXX' is printed in this case, 'XXX' otherwise. In both cases,
+ the output goes to stdout and nothing is printed to stderr.
+ Additional arguments are always ignored.
+
+ Since for each cipher there is a command of the same name,
+ the 'no-cipher' compilation switches can be tested this way.
+
+ ('openssl no-XXX' is not able to detect pseudo-commands such
+ as 'quit', 'list-XXX-commands', or 'no-XXX' itself.)
+ [Bodo Moeller]
+
+ *) Update test suite so that 'make test' succeeds in 'no-rsa' configuration.
+ [Bodo Moeller]
+
+ *) For SSL_[CTX_]set_tmp_dh, don't create a DH key if SSL_OP_SINGLE_DH_USE
+ is set; it will be thrown away anyway because each handshake creates
+ its own key.
+ ssl_cert_dup, which is used by SSL_new, now copies DH keys in addition
+ to parameters -- in previous versions (since OpenSSL 0.9.3) the
+ 'default key' from SSL_CTX_set_tmp_dh would always be lost, meanining
+ you effectivly got SSL_OP_SINGLE_DH_USE when using this macro.
+ [Bodo Moeller]
+
+ *) New s_client option -ign_eof: EOF at stdin is ignored, and
+ 'Q' and 'R' lose their special meanings (quit/renegotiate).
+ This is part of what -quiet does; unlike -quiet, -ign_eof
+ does not suppress any output.
+ [Richard Levitte]
+
+ *) Add compatibility options to the purpose and trust code. The
+ purpose X509_PURPOSE_ANY is "any purpose" which automatically
+ accepts a certificate or CA, this was the previous behaviour,
+ with all the associated security issues.
+
+ X509_TRUST_COMPAT is the old trust behaviour: only and
+ automatically trust self signed roots in certificate store. A
+ new trust setting X509_TRUST_DEFAULT is used to specify that
+ a purpose has no associated trust setting and it should instead
+ use the value in the default purpose.
+ [Steve Henson]
+
+ *) Fix the PKCS#8 DSA private key code so it decodes keys again
+ and fix a memory leak.
+ [Steve Henson]
+
+ *) In util/mkerr.pl (which implements 'make errors'), preserve
+ reason strings from the previous version of the .c file, as
+ the default to have only downcase letters (and digits) in
+ automatically generated reasons codes is not always appropriate.
+ [Bodo Moeller]
+
+ *) In ERR_load_ERR_strings(), build an ERR_LIB_SYS error reason table
+ using strerror. Previously, ERR_reason_error_string() returned
+ library names as reason strings for SYSerr; but SYSerr is a special
+ case where small numbers are errno values, not library numbers.
+ [Bodo Moeller]
+
+ *) Add '-dsaparam' option to 'openssl dhparam' application. This
+ converts DSA parameters into DH parameters. (When creating parameters,
+ DSA_generate_parameters is used.)
+ [Bodo Moeller]
+
+ *) Include 'length' (recommended exponent length) in C code generated
+ by 'openssl dhparam -C'.
+ [Bodo Moeller]
+
+ *) The second argument to set_label in perlasm was already being used
+ so couldn't be used as a "file scope" flag. Moved to third argument
+ which was free.
+ [Steve Henson]
+
+ *) In PEM_ASN1_write_bio and some other functions, use RAND_pseudo_bytes
+ instead of RAND_bytes for encryption IVs and salts.
+ [Bodo Moeller]
+
+ *) Include RAND_status() into RAND_METHOD instead of implementing
+ it only for md_rand.c Otherwise replacing the PRNG by calling
+ RAND_set_rand_method would be impossible.
+ [Bodo Moeller]
+
+ *) Don't let DSA_generate_key() enter an infinite loop if the random
+ number generation fails.
+ [Bodo Moeller]
+
+ *) New 'rand' application for creating pseudo-random output.
+ [Bodo Moeller]
+
+ *) Added configuration support for Linux/IA64
+ [Rolf Haberrecker <rolf@suse.de>]
+
+ *) Assembler module support for Mingw32.
+ [Ulf Möller]
+
+ *) Shared library support for HPUX (in shlib/).
+ [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> and Anonymous]
+
+ *) Shared library support for Solaris gcc.
+ [Lutz Behnke <behnke@trustcenter.de>]
+
+ Changes between 0.9.4 and 0.9.5 [28 Feb 2000]
+
+ *) PKCS7_encrypt() was adding text MIME headers twice because they
+ were added manually and by SMIME_crlf_copy().
+ [Steve Henson]
+
+ *) In bntest.c don't call BN_rand with zero bits argument.
+ [Steve Henson, pointed out by Andrew W. Gray <agray@iconsinc.com>]
+
+ *) BN_mul bugfix: In bn_mul_part_recursion() only the a>a[n] && b>b[n]
+ case was implemented. This caused BN_div_recp() to fail occasionally.
+ [Ulf Möller]
+
+ *) Add an optional second argument to the set_label() in the perl
+ assembly language builder. If this argument exists and is set
+ to 1 it signals that the assembler should use a symbol whose
+ scope is the entire file, not just the current function. This
+ is needed with MASM which uses the format label:: for this scope.
+ [Steve Henson, pointed out by Peter Runestig <peter@runestig.com>]
+
+ *) Change the ASN1 types so they are typedefs by default. Before
+ almost all types were #define'd to ASN1_STRING which was causing
+ STACK_OF() problems: you couldn't declare STACK_OF(ASN1_UTF8STRING)
+ for example.
+ [Steve Henson]
+
+ *) Change names of new functions to the new get1/get0 naming
+ convention: After 'get1', the caller owns a reference count
+ and has to call ..._free; 'get0' returns a pointer to some
+ data structure without incrementing reference counters.
+ (Some of the existing 'get' functions increment a reference
+ counter, some don't.)
+ Similarly, 'set1' and 'add1' functions increase reference
+ counters or duplicate objects.
+ [Steve Henson]
+
+ *) Allow for the possibility of temp RSA key generation failure:
+ the code used to assume it always worked and crashed on failure.
+ [Steve Henson]
+
+ *) Fix potential buffer overrun problem in BIO_printf().
+ [Ulf Möller, using public domain code by Patrick Powell; problem
+ pointed out by David Sacerdote <das33@cornell.edu>]
+
+ *) Support EGD <http://www.lothar.com/tech/crypto/>. New functions
+ RAND_egd() and RAND_status(). In the command line application,
+ the EGD socket can be specified like a seed file using RANDFILE
+ or -rand.
+ [Ulf Möller]
+
+ *) Allow the string CERTIFICATE to be tolerated in PKCS#7 structures.
+ Some CAs (e.g. Verisign) distribute certificates in this form.
+ [Steve Henson]
+
+ *) Remove the SSL_ALLOW_ADH compile option and set the default cipher
+ list to exclude them. This means that no special compilation option
+ is needed to use anonymous DH: it just needs to be included in the
+ cipher list.
+ [Steve Henson]
+
+ *) Change the EVP_MD_CTX_type macro so its meaning consistent with
+ EVP_MD_type. The old functionality is available in a new macro called
+ EVP_MD_md(). Change code that uses it and update docs.
+ [Steve Henson]
+
+ *) ..._ctrl functions now have corresponding ..._callback_ctrl functions
+ where the 'void *' argument is replaced by a function pointer argument.
+ Previously 'void *' was abused to point to functions, which works on
+ many platforms, but is not correct. As these functions are usually
+ called by macros defined in OpenSSL header files, most source code
+ should work without changes.
+ [Richard Levitte]
+
+ *) <openssl/opensslconf.h> (which is created by Configure) now contains
+ sections with information on -D... compiler switches used for
+ compiling the library so that applications can see them. To enable
+ one of these sections, a pre-processor symbol OPENSSL_..._DEFINES
+ must be defined. E.g.,
+ #define OPENSSL_ALGORITHM_DEFINES
+ #include <openssl/opensslconf.h>
+ defines all pertinent NO_<algo> symbols, such as NO_IDEA, NO_RSA, etc.
+ [Richard Levitte, Ulf and Bodo Möller]
+
+ *) Bugfix: Tolerate fragmentation and interleaving in the SSL 3/TLS
+ record layer.
+ [Bodo Moeller]
+
+ *) Change the 'other' type in certificate aux info to a STACK_OF
+ X509_ALGOR. Although not an AlgorithmIdentifier as such it has
+ the required ASN1 format: arbitrary types determined by an OID.
+ [Steve Henson]
+
+ *) Add some PEM_write_X509_REQ_NEW() functions and a command line
+ argument to 'req'. This is not because the function is newer or
+ better than others it just uses the work 'NEW' in the certificate
+ request header lines. Some software needs this.
+ [Steve Henson]
+
+ *) Reorganise password command line arguments: now passwords can be
+ obtained from various sources. Delete the PEM_cb function and make
+ it the default behaviour: i.e. if the callback is NULL and the
+ usrdata argument is not NULL interpret it as a null terminated pass
+ phrase. If usrdata and the callback are NULL then the pass phrase
+ is prompted for as usual.
+ [Steve Henson]
+
+ *) Add support for the Compaq Atalla crypto accelerator. If it is installed,
+ the support is automatically enabled. The resulting binaries will
+ autodetect the card and use it if present.
+ [Ben Laurie and Compaq Inc.]
+
+ *) Work around for Netscape hang bug. This sends certificate request
+ and server done in one record. Since this is perfectly legal in the
+ SSL/TLS protocol it isn't a "bug" option and is on by default. See
+ the bugs/SSLv3 entry for more info.
+ [Steve Henson]
+
+ *) HP-UX tune-up: new unified configs, HP C compiler bug workaround.
+ [Andy Polyakov]
+
+ *) Add -rand argument to smime and pkcs12 applications and read/write
+ of seed file.
+ [Steve Henson]
+
+ *) New 'passwd' tool for crypt(3) and apr1 password hashes.
+ [Bodo Moeller]
+
+ *) Add command line password options to the remaining applications.
+ [Steve Henson]
+
+ *) Bug fix for BN_div_recp() for numerators with an even number of
+ bits.
+ [Ulf Möller]
+
+ *) More tests in bntest.c, and changed test_bn output.
+ [Ulf Möller]
+
+ *) ./config recognizes MacOS X now.
+ [Andy Polyakov]
+
+ *) Bug fix for BN_div() when the first words of num and divsor are
+ equal (it gave wrong results if (rem=(n1-q*d0)&BN_MASK2) < d0).
+ [Ulf Möller]
+
+ *) Add support for various broken PKCS#8 formats, and command line
+ options to produce them.
+ [Steve Henson]
+
+ *) New functions BN_CTX_start(), BN_CTX_get() and BT_CTX_end() to
+ get temporary BIGNUMs from a BN_CTX.
+ [Ulf Möller]
+
+ *) Correct return values in BN_mod_exp_mont() and BN_mod_exp2_mont()
+ for p == 0.
+ [Ulf Möller]
+
+ *) Change the SSLeay_add_all_*() functions to OpenSSL_add_all_*() and
+ include a #define from the old name to the new. The original intent
+ was that statically linked binaries could for example just call
+ SSLeay_add_all_ciphers() to just add ciphers to the table and not
+ link with digests. This never worked becayse SSLeay_add_all_digests()
+ and SSLeay_add_all_ciphers() were in the same source file so calling
+ one would link with the other. They are now in separate source files.
+ [Steve Henson]
+
+ *) Add a new -notext option to 'ca' and a -pubkey option to 'spkac'.
+ [Steve Henson]
+
+ *) Use a less unusual form of the Miller-Rabin primality test (it used
+ a binary algorithm for exponentiation integrated into the Miller-Rabin
+ loop, our standard modexp algorithms are faster).
+ [Bodo Moeller]
+
+ *) Support for the EBCDIC character set completed.
+ [Martin Kraemer <Martin.Kraemer@Mch.SNI.De>]
+
+ *) Source code cleanups: use const where appropriate, eliminate casts,
+ use void * instead of char * in lhash.
+ [Ulf Möller]
+
+ *) Bugfix: ssl3_send_server_key_exchange was not restartable
+ (the state was not changed to SSL3_ST_SW_KEY_EXCH_B, and because of
+ this the server could overwrite ephemeral keys that the client
+ has already seen).
+ [Bodo Moeller]
+
+ *) Turn DSA_is_prime into a macro that calls BN_is_prime,
+ using 50 iterations of the Rabin-Miller test.
+
+ DSA_generate_parameters now uses BN_is_prime_fasttest (with 50
+ iterations of the Rabin-Miller test as required by the appendix
+ to FIPS PUB 186[-1]) instead of DSA_is_prime.
+ As BN_is_prime_fasttest includes trial division, DSA parameter
+ generation becomes much faster.
+
+ This implies a change for the callback functions in DSA_is_prime
+ and DSA_generate_parameters: The callback function is called once
+ for each positive witness in the Rabin-Miller test, not just
+ occasionally in the inner loop; and the parameters to the
+ callback function now provide an iteration count for the outer
+ loop rather than for the current invocation of the inner loop.
+ DSA_generate_parameters additionally can call the callback
+ function with an 'iteration count' of -1, meaning that a
+ candidate has passed the trial division test (when q is generated
+ from an application-provided seed, trial division is skipped).
+ [Bodo Moeller]
+
+ *) New function BN_is_prime_fasttest that optionally does trial
+ division before starting the Rabin-Miller test and has
+ an additional BN_CTX * argument (whereas BN_is_prime always
+ has to allocate at least one BN_CTX).
+ 'callback(1, -1, cb_arg)' is called when a number has passed the
+ trial division stage.
+ [Bodo Moeller]
+
+ *) Fix for bug in CRL encoding. The validity dates weren't being handled
+ as ASN1_TIME.
+ [Steve Henson]
+
+ *) New -pkcs12 option to CA.pl script to write out a PKCS#12 file.
+ [Steve Henson]
+
+ *) New function BN_pseudo_rand().
+ [Ulf Möller]
+
+ *) Clean up BN_mod_mul_montgomery(): replace the broken (and unreadable)
+ bignum version of BN_from_montgomery() with the working code from
+ SSLeay 0.9.0 (the word based version is faster anyway), and clean up
+ the comments.
+ [Ulf Möller]
+
+ *) Avoid a race condition in s2_clnt.c (function get_server_hello) that
+ made it impossible to use the same SSL_SESSION data structure in
+ SSL2 clients in multiple threads.
+ [Bodo Moeller]
+
+ *) The return value of RAND_load_file() no longer counts bytes obtained
+ by stat(). RAND_load_file(..., -1) is new and uses the complete file
+ to seed the PRNG (previously an explicit byte count was required).
+ [Ulf Möller, Bodo Möller]
+
+ *) Clean up CRYPTO_EX_DATA functions, some of these didn't have prototypes
+ used (char *) instead of (void *) and had casts all over the place.
+ [Steve Henson]
+
+ *) Make BN_generate_prime() return NULL on error if ret!=NULL.
+ [Ulf Möller]
+
+ *) Retain source code compatibility for BN_prime_checks macro:
+ BN_is_prime(..., BN_prime_checks, ...) now uses
+ BN_prime_checks_for_size to determine the appropriate number of
+ Rabin-Miller iterations.
+ [Ulf Möller]
+
+ *) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to
+ DH_CHECK_P_NOT_SAFE_PRIME.
+ (Check if this is true? OpenPGP calls them "strong".)
+ [Ulf Möller]
+
+ *) Merge the functionality of "dh" and "gendh" programs into a new program
+ "dhparam". The old programs are retained for now but will handle DH keys
+ (instead of parameters) in future.
+ [Steve Henson]
+
+ *) Make the ciphers, s_server and s_client programs check the return values
+ when a new cipher list is set.
+ [Steve Henson]
+
+ *) Enhance the SSL/TLS cipher mechanism to correctly handle the TLS 56bit
+ ciphers. Before when the 56bit ciphers were enabled the sorting was
+ wrong.
+
+ The syntax for the cipher sorting has been extended to support sorting by
+ cipher-strength (using the strength_bits hard coded in the tables).
+ The new command is "@STRENGTH" (see also doc/apps/ciphers.pod).
+
+ Fix a bug in the cipher-command parser: when supplying a cipher command
+ string with an "undefined" symbol (neither command nor alphanumeric
+ [A-Za-z0-9], ssl_set_cipher_list used to hang in an endless loop. Now
+ an error is flagged.
+
+ Due to the strength-sorting extension, the code of the
+ ssl_create_cipher_list() function was completely rearranged. I hope that
+ the readability was also increased :-)
+ [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>]
+
+ *) Minor change to 'x509' utility. The -CAcreateserial option now uses 1
+ for the first serial number and places 2 in the serial number file. This
+ avoids problems when the root CA is created with serial number zero and
+ the first user certificate has the same issuer name and serial number
+ as the root CA.
+ [Steve Henson]
+
+ *) Fixes to X509_ATTRIBUTE utilities, change the 'req' program so it uses
+ the new code. Add documentation for this stuff.
+ [Steve Henson]
+
+ *) Changes to X509_ATTRIBUTE utilities. These have been renamed from
+ X509_*() to X509at_*() on the grounds that they don't handle X509
+ structures and behave in an analagous way to the X509v3 functions:
+ they shouldn't be called directly but wrapper functions should be used
+ instead.
+
+ So we also now have some wrapper functions that call the X509at functions
+ when passed certificate requests. (TO DO: similar things can be done with
+ PKCS#7 signed and unsigned attributes, PKCS#12 attributes and a few other
+ things. Some of these need some d2i or i2d and print functionality
+ because they handle more complex structures.)
+ [Steve Henson]
+
+ *) Add missing #ifndefs that caused missing symbols when building libssl
+ as a shared library without RSA. Use #ifndef NO_SSL2 instead of
+ NO_RSA in ssl/s2*.c.
+ [Kris Kennaway <kris@hub.freebsd.org>, modified by Ulf Möller]
+
+ *) Precautions against using the PRNG uninitialized: RAND_bytes() now
+ has a return value which indicates the quality of the random data
+ (1 = ok, 0 = not seeded). Also an error is recorded on the thread's
+ error queue. New function RAND_pseudo_bytes() generates output that is
+ guaranteed to be unique but not unpredictable. RAND_add is like
+ RAND_seed, but takes an extra argument for an entropy estimate
+ (RAND_seed always assumes full entropy).
+ [Ulf Möller]
+
+ *) Do more iterations of Rabin-Miller probable prime test (specifically,
+ 3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes
+ instead of only 2 for all lengths; see BN_prime_checks_for_size definition
+ in crypto/bn/bn_prime.c for the complete table). This guarantees a
+ false-positive rate of at most 2^-80 for random input.
+ [Bodo Moeller]
+
+ *) Rewrite ssl3_read_n (ssl/s3_pkt.c) avoiding a couple of bugs.
+ [Bodo Moeller]
+
+ *) New function X509_CTX_rget_chain() (renamed to X509_CTX_get1_chain
+ in the 0.9.5 release), this returns the chain
+ from an X509_CTX structure with a dup of the stack and all
+ the X509 reference counts upped: so the stack will exist
+ after X509_CTX_cleanup() has been called. Modify pkcs12.c
+ to use this.
+
+ Also make SSL_SESSION_print() print out the verify return
+ code.
+ [Steve Henson]
+
+ *) Add manpage for the pkcs12 command. Also change the default
+ behaviour so MAC iteration counts are used unless the new
+ -nomaciter option is used. This improves file security and
+ only older versions of MSIE (4.0 for example) need it.
+ [Steve Henson]
+
+ *) Honor the no-xxx Configure options when creating .DEF files.
+ [Ulf Möller]
+
+ *) Add PKCS#10 attributes to field table: challengePassword,
+ unstructuredName and unstructuredAddress. These are taken from
+ draft PKCS#9 v2.0 but are compatible with v1.2 provided no
+ international characters are used.
+
+ More changes to X509_ATTRIBUTE code: allow the setting of types
+ based on strings. Remove the 'loc' parameter when adding
+ attributes because these will be a SET OF encoding which is sorted
+ in ASN1 order.
+ [Steve Henson]
+
+ *) Initial changes to the 'req' utility to allow request generation
+ automation. This will allow an application to just generate a template
+ file containing all the field values and have req construct the
+ request.
+
+ Initial support for X509_ATTRIBUTE handling. Stacks of these are
+ used all over the place including certificate requests and PKCS#7
+ structures. They are currently handled manually where necessary with
+ some primitive wrappers for PKCS#7. The new functions behave in a
+ manner analogous to the X509 extension functions: they allow
+ attributes to be looked up by NID and added.
+
+ Later something similar to the X509V3 code would be desirable to
+ automatically handle the encoding, decoding and printing of the
+ more complex types. The string types like challengePassword can
+ be handled by the string table functions.
+
+ Also modified the multi byte string table handling. Now there is
+ a 'global mask' which masks out certain types. The table itself
+ can use the flag STABLE_NO_MASK to ignore the mask setting: this
+ is useful when for example there is only one permissible type
+ (as in countryName) and using the mask might result in no valid
+ types at all.
+ [Steve Henson]
+
+ *) Clean up 'Finished' handling, and add functions SSL_get_finished and
+ SSL_get_peer_finished to allow applications to obtain the latest
+ Finished messages sent to the peer or expected from the peer,
+ respectively. (SSL_get_peer_finished is usually the Finished message
+ actually received from the peer, otherwise the protocol will be aborted.)
+
+ As the Finished message are message digests of the complete handshake
+ (with a total of 192 bits for TLS 1.0 and more for SSL 3.0), they can
+ be used for external authentication procedures when the authentication
+ provided by SSL/TLS is not desired or is not enough.
+ [Bodo Moeller]
+
+ *) Enhanced support for Alpha Linux is added. Now ./config checks if
+ the host supports BWX extension and if Compaq C is present on the
+ $PATH. Just exploiting of the BWX extension results in 20-30%
+ performance kick for some algorithms, e.g. DES and RC4 to mention
+ a couple. Compaq C in turn generates ~20% faster code for MD5 and
+ SHA1.
+ [Andy Polyakov]
+
+ *) Add support for MS "fast SGC". This is arguably a violation of the
+ SSL3/TLS protocol. Netscape SGC does two handshakes: the first with
+ weak crypto and after checking the certificate is SGC a second one
+ with strong crypto. MS SGC stops the first handshake after receiving
+ the server certificate message and sends a second client hello. Since
+ a server will typically do all the time consuming operations before
+ expecting any further messages from the client (server key exchange
+ is the most expensive) there is little difference between the two.
+
+ To get OpenSSL to support MS SGC we have to permit a second client
+ hello message after we have sent server done. In addition we have to
+ reset the MAC if we do get this second client hello.
+ [Steve Henson]
+
+ *) Add a function 'd2i_AutoPrivateKey()' this will automatically decide
+ if a DER encoded private key is RSA or DSA traditional format. Changed
+ d2i_PrivateKey_bio() to use it. This is only needed for the "traditional"
+ format DER encoded private key. Newer code should use PKCS#8 format which
+ has the key type encoded in the ASN1 structure. Added DER private key
+ support to pkcs8 application.
+ [Steve Henson]
+
+ *) SSL 3/TLS 1 servers now don't request certificates when an anonymous
+ ciphersuites has been selected (as required by the SSL 3/TLS 1
+ specifications). Exception: When SSL_VERIFY_FAIL_IF_NO_PEER_CERT
+ is set, we interpret this as a request to violate the specification
+ (the worst that can happen is a handshake failure, and 'correct'
+ behaviour would result in a handshake failure anyway).
+ [Bodo Moeller]
+
+ *) In SSL_CTX_add_session, take into account that there might be multiple
+ SSL_SESSION structures with the same session ID (e.g. when two threads
+ concurrently obtain them from an external cache).
+ The internal cache can handle only one SSL_SESSION with a given ID,
+ so if there's a conflict, we now throw out the old one to achieve
+ consistency.
+ [Bodo Moeller]
+
+ *) Add OIDs for idea and blowfish in CBC mode. This will allow both
+ to be used in PKCS#5 v2.0 and S/MIME. Also add checking to
+ some routines that use cipher OIDs: some ciphers do not have OIDs
+ defined and so they cannot be used for S/MIME and PKCS#5 v2.0 for
+ example.
+ [Steve Henson]
+
+ *) Simplify the trust setting structure and code. Now we just have
+ two sequences of OIDs for trusted and rejected settings. These will
+ typically have values the same as the extended key usage extension
+ and any application specific purposes.
+
+ The trust checking code now has a default behaviour: it will just
+ check for an object with the same NID as the passed id. Functions can
+ be provided to override either the default behaviour or the behaviour
+ for a given id. SSL client, server and email already have functions
+ in place for compatibility: they check the NID and also return "trusted"
+ if the certificate is self signed.
+ [Steve Henson]
+
+ *) Add d2i,i2d bio/fp functions for PrivateKey: these convert the
+ traditional format into an EVP_PKEY structure.
+ [Steve Henson]
+
+ *) Add a password callback function PEM_cb() which either prompts for
+ a password if usr_data is NULL or otherwise assumes it is a null
+ terminated password. Allow passwords to be passed on command line
+ environment or config files in a few more utilities.
+ [Steve Henson]
+
+ *) Add a bunch of DER and PEM functions to handle PKCS#8 format private
+ keys. Add some short names for PKCS#8 PBE algorithms and allow them
+ to be specified on the command line for the pkcs8 and pkcs12 utilities.
+ Update documentation.
+ [Steve Henson]
+
+ *) Support for ASN1 "NULL" type. This could be handled before by using
+ ASN1_TYPE but there wasn't any function that would try to read a NULL
+ and produce an error if it couldn't. For compatibility we also have
+ ASN1_NULL_new() and ASN1_NULL_free() functions but these are faked and
+ don't allocate anything because they don't need to.
+ [Steve Henson]
+
+ *) Initial support for MacOS is now provided. Examine INSTALL.MacOS
+ for details.
+ [Andy Polyakov, Roy Woods <roy@centicsystems.ca>]
+
+ *) Rebuild of the memory allocation routines used by OpenSSL code and
+ possibly others as well. The purpose is to make an interface that
+ provide hooks so anyone can build a separate set of allocation and
+ deallocation routines to be used by OpenSSL, for example memory
+ pool implementations, or something else, which was previously hard
+ since Malloc(), Realloc() and Free() were defined as macros having
+ the values malloc, realloc and free, respectively (except for Win32
+ compilations). The same is provided for memory debugging code.
+ OpenSSL already comes with functionality to find memory leaks, but
+ this gives people a chance to debug other memory problems.
+
+ With these changes, a new set of functions and macros have appeared:
+
+ CRYPTO_set_mem_debug_functions() [F]
+ CRYPTO_get_mem_debug_functions() [F]
+ CRYPTO_dbg_set_options() [F]
+ CRYPTO_dbg_get_options() [F]
+ CRYPTO_malloc_debug_init() [M]
+
+ The memory debug functions are NULL by default, unless the library
+ is compiled with CRYPTO_MDEBUG or friends is defined. If someone
+ wants to debug memory anyway, CRYPTO_malloc_debug_init() (which
+ gives the standard debugging functions that come with OpenSSL) or
+ CRYPTO_set_mem_debug_functions() (tells OpenSSL to use functions
+ provided by the library user) must be used. When the standard
+ debugging functions are used, CRYPTO_dbg_set_options can be used to
+ request additional information:
+ CRYPTO_dbg_set_options(V_CYRPTO_MDEBUG_xxx) corresponds to setting
+ the CRYPTO_MDEBUG_xxx macro when compiling the library.
+
+ Also, things like CRYPTO_set_mem_functions will always give the
+ expected result (the new set of functions is used for allocation
+ and deallocation) at all times, regardless of platform and compiler
+ options.
+
+ To finish it up, some functions that were never use in any other
+ way than through macros have a new API and new semantic:
+
+ CRYPTO_dbg_malloc()
+ CRYPTO_dbg_realloc()
+ CRYPTO_dbg_free()
+
+ All macros of value have retained their old syntax.
+ [Richard Levitte and Bodo Moeller]
+
+ *) Some S/MIME fixes. The OID for SMIMECapabilities was wrong, the
+ ordering of SMIMECapabilities wasn't in "strength order" and there
+ was a missing NULL in the AlgorithmIdentifier for the SHA1 signature
+ algorithm.
+ [Steve Henson]
+
+ *) Some ASN1 types with illegal zero length encoding (INTEGER,
+ ENUMERATED and OBJECT IDENTIFIER) choked the ASN1 routines.
+ [Frans Heymans <fheymans@isaserver.be>, modified by Steve Henson]
+
+ *) Merge in my S/MIME library for OpenSSL. This provides a simple
+ S/MIME API on top of the PKCS#7 code, a MIME parser (with enough
+ functionality to handle multipart/signed properly) and a utility
+ called 'smime' to call all this stuff. This is based on code I
+ originally wrote for Celo who have kindly allowed it to be
+ included in OpenSSL.
+ [Steve Henson]
+
+ *) Add variants des_set_key_checked and des_set_key_unchecked of
+ des_set_key (aka des_key_sched). Global variable des_check_key
+ decides which of these is called by des_set_key; this way
+ des_check_key behaves as it always did, but applications and
+ the library itself, which was buggy for des_check_key == 1,
+ have a cleaner way to pick the version they need.
+ [Bodo Moeller]
+
+ *) New function PKCS12_newpass() which changes the password of a
+ PKCS12 structure.
+ [Steve Henson]
+
+ *) Modify X509_TRUST and X509_PURPOSE so it also uses a static and
+ dynamic mix. In both cases the ids can be used as an index into the
+ table. Also modified the X509_TRUST_add() and X509_PURPOSE_add()
+ functions so they accept a list of the field values and the
+ application doesn't need to directly manipulate the X509_TRUST
+ structure.
+ [Steve Henson]
+
+ *) Modify the ASN1_STRING_TABLE stuff so it also uses bsearch and doesn't
+ need initialising.
+ [Steve Henson]
+
+ *) Modify the way the V3 extension code looks up extensions. This now
+ works in a similar way to the object code: we have some "standard"
+ extensions in a static table which is searched with OBJ_bsearch()
+ and the application can add dynamic ones if needed. The file
+ crypto/x509v3/ext_dat.h now has the info: this file needs to be
+ updated whenever a new extension is added to the core code and kept
+ in ext_nid order. There is a simple program 'tabtest.c' which checks
+ this. New extensions are not added too often so this file can readily
+ be maintained manually.
+
+ There are two big advantages in doing things this way. The extensions
+ can be looked up immediately and no longer need to be "added" using
+ X509V3_add_standard_extensions(): this function now does nothing.
+ [Side note: I get *lots* of email saying the extension code doesn't
+ work because people forget to call this function]
+ Also no dynamic allocation is done unless new extensions are added:
+ so if we don't add custom extensions there is no need to call
+ X509V3_EXT_cleanup().
+ [Steve Henson]
+
+ *) Modify enc utility's salting as follows: make salting the default. Add a
+ magic header, so unsalted files fail gracefully instead of just decrypting
+ to garbage. This is because not salting is a big security hole, so people
+ should be discouraged from doing it.
+ [Ben Laurie]
+
+ *) Fixes and enhancements to the 'x509' utility. It allowed a message
+ digest to be passed on the command line but it only used this
+ parameter when signing a certificate. Modified so all relevant
+ operations are affected by the digest parameter including the
+ -fingerprint and -x509toreq options. Also -x509toreq choked if a
+ DSA key was used because it didn't fix the digest.
+ [Steve Henson]
+
+ *) Initial certificate chain verify code. Currently tests the untrusted
+ certificates for consistency with the verify purpose (which is set
+ when the X509_STORE_CTX structure is set up) and checks the pathlength.
+
+ There is a NO_CHAIN_VERIFY compilation option to keep the old behaviour:
+ this is because it will reject chains with invalid extensions whereas
+ every previous version of OpenSSL and SSLeay made no checks at all.
+
+ Trust code: checks the root CA for the relevant trust settings. Trust
+ settings have an initial value consistent with the verify purpose: e.g.
+ if the verify purpose is for SSL client use it expects the CA to be
+ trusted for SSL client use. However the default value can be changed to
+ permit custom trust settings: one example of this would be to only trust
+ certificates from a specific "secure" set of CAs.
+
+ Also added X509_STORE_CTX_new() and X509_STORE_CTX_free() functions
+ which should be used for version portability: especially since the
+ verify structure is likely to change more often now.
+
+ SSL integration. Add purpose and trust to SSL_CTX and SSL and functions
+ to set them. If not set then assume SSL clients will verify SSL servers
+ and vice versa.
+
+ Two new options to the verify program: -untrusted allows a set of
+ untrusted certificates to be passed in and -purpose which sets the
+ intended purpose of the certificate. If a purpose is set then the
+ new chain verify code is used to check extension consistency.
+ [Steve Henson]
+
+ *) Support for the authority information access extension.
+ [Steve Henson]
+
+ *) Modify RSA and DSA PEM read routines to transparently handle
+ PKCS#8 format private keys. New *_PUBKEY_* functions that handle
+ public keys in a format compatible with certificate
+ SubjectPublicKeyInfo structures. Unfortunately there were already
+ functions called *_PublicKey_* which used various odd formats so
+ these are retained for compatibility: however the DSA variants were
+ never in a public release so they have been deleted. Changed dsa/rsa
+ utilities to handle the new format: note no releases ever handled public
+ keys so we should be OK.
+
+ The primary motivation for this change is to avoid the same fiasco
+ that dogs private keys: there are several incompatible private key
+ formats some of which are standard and some OpenSSL specific and
+ require various evil hacks to allow partial transparent handling and
+ even then it doesn't work with DER formats. Given the option anything
+ other than PKCS#8 should be dumped: but the other formats have to
+ stay in the name of compatibility.
+
+ With public keys and the benefit of hindsight one standard format
+ is used which works with EVP_PKEY, RSA or DSA structures: though
+ it clearly returns an error if you try to read the wrong kind of key.
+
+ Added a -pubkey option to the 'x509' utility to output the public key.
+ Also rename the EVP_PKEY_get_*() to EVP_PKEY_rget_*()
+ (renamed to EVP_PKEY_get1_*() in the OpenSSL 0.9.5 release) and add
+ EVP_PKEY_rset_*() functions (renamed to EVP_PKEY_set1_*())
+ that do the same as the EVP_PKEY_assign_*() except they up the
+ reference count of the added key (they don't "swallow" the
+ supplied key).
+ [Steve Henson]
+
+ *) Fixes to crypto/x509/by_file.c the code to read in certificates and
+ CRLs would fail if the file contained no certificates or no CRLs:
+ added a new function to read in both types and return the number
+ read: this means that if none are read it will be an error. The
+ DER versions of the certificate and CRL reader would always fail
+ because it isn't possible to mix certificates and CRLs in DER format
+ without choking one or the other routine. Changed this to just read
+ a certificate: this is the best we can do. Also modified the code
+ in apps/verify.c to take notice of return codes: it was previously
+ attempting to read in certificates from NULL pointers and ignoring
+ any errors: this is one reason why the cert and CRL reader seemed
+ to work. It doesn't check return codes from the default certificate
+ routines: these may well fail if the certificates aren't installed.
+ [Steve Henson]
+
+ *) Code to support otherName option in GeneralName.
+ [Steve Henson]
+
+ *) First update to verify code. Change the verify utility
+ so it warns if it is passed a self signed certificate:
+ for consistency with the normal behaviour. X509_verify
+ has been modified to it will now verify a self signed
+ certificate if *exactly* the same certificate appears
+ in the store: it was previously impossible to trust a
+ single self signed certificate. This means that:
+ openssl verify ss.pem
+ now gives a warning about a self signed certificate but
+ openssl verify -CAfile ss.pem ss.pem
+ is OK.
+ [Steve Henson]
+
+ *) For servers, store verify_result in SSL_SESSION data structure
+ (and add it to external session representation).
+ This is needed when client certificate verifications fails,
+ but an application-provided verification callback (set by
+ SSL_CTX_set_cert_verify_callback) allows accepting the session
+ anyway (i.e. leaves x509_store_ctx->error != X509_V_OK
+ but returns 1): When the session is reused, we have to set
+ ssl->verify_result to the appropriate error code to avoid
+ security holes.
+ [Bodo Moeller, problem pointed out by Lutz Jaenicke]
+
+ *) Fix a bug in the new PKCS#7 code: it didn't consider the
+ case in PKCS7_dataInit() where the signed PKCS7 structure
+ didn't contain any existing data because it was being created.
+ [Po-Cheng Chen <pocheng@nst.com.tw>, slightly modified by Steve Henson]
+
+ *) Add a salt to the key derivation routines in enc.c. This
+ forms the first 8 bytes of the encrypted file. Also add a
+ -S option to allow a salt to be input on the command line.
+ [Steve Henson]
+
+ *) New function X509_cmp(). Oddly enough there wasn't a function
+ to compare two certificates. We do this by working out the SHA1
+ hash and comparing that. X509_cmp() will be needed by the trust
+ code.
+ [Steve Henson]
+
+ *) SSL_get1_session() is like SSL_get_session(), but increments
+ the reference count in the SSL_SESSION returned.
+ [Geoff Thorpe <geoff@eu.c2.net>]
+
+ *) Fix for 'req': it was adding a null to request attributes.
+ Also change the X509_LOOKUP and X509_INFO code to handle
+ certificate auxiliary information.
+ [Steve Henson]
+
+ *) Add support for 40 and 64 bit RC2 and RC4 algorithms: document
+ the 'enc' command.
+ [Steve Henson]
+
+ *) Add the possibility to add extra information to the memory leak
+ detecting output, to form tracebacks, showing from where each
+ allocation was originated: CRYPTO_push_info("constant string") adds
+ the string plus current file name and line number to a per-thread
+ stack, CRYPTO_pop_info() does the obvious, CRYPTO_remove_all_info()
+ is like calling CYRPTO_pop_info() until the stack is empty.
+ Also updated memory leak detection code to be multi-thread-safe.
+ [Richard Levitte]
+
+ *) Add options -text and -noout to pkcs7 utility and delete the
+ encryption options which never did anything. Update docs.
+ [Steve Henson]
+
+ *) Add options to some of the utilities to allow the pass phrase
+ to be included on either the command line (not recommended on
+ OSes like Unix) or read from the environment. Update the
+ manpages and fix a few bugs.
+ [Steve Henson]
+
+ *) Add a few manpages for some of the openssl commands.
+ [Steve Henson]
+
+ *) Fix the -revoke option in ca. It was freeing up memory twice,
+ leaking and not finding already revoked certificates.
+ [Steve Henson]
+
+ *) Extensive changes to support certificate auxiliary information.
+ This involves the use of X509_CERT_AUX structure and X509_AUX
+ functions. An X509_AUX function such as PEM_read_X509_AUX()
+ can still read in a certificate file in the usual way but it
+ will also read in any additional "auxiliary information". By
+ doing things this way a fair degree of compatibility can be
+ retained: existing certificates can have this information added
+ using the new 'x509' options.
+
+ Current auxiliary information includes an "alias" and some trust
+ settings. The trust settings will ultimately be used in enhanced
+ certificate chain verification routines: currently a certificate
+ can only be trusted if it is self signed and then it is trusted
+ for all purposes.
+ [Steve Henson]
+
+ *) Fix assembler for Alpha (tested only on DEC OSF not Linux or *BSD).
+ The problem was that one of the replacement routines had not been working
+ since SSLeay releases. For now the offending routine has been replaced
+ with non-optimised assembler. Even so, this now gives around 95%
+ performance improvement for 1024 bit RSA signs.
+ [Mark Cox]
+
+ *) Hack to fix PKCS#7 decryption when used with some unorthodox RC2
+ handling. Most clients have the effective key size in bits equal to
+ the key length in bits: so a 40 bit RC2 key uses a 40 bit (5 byte) key.
+ A few however don't do this and instead use the size of the decrypted key
+ to determine the RC2 key length and the AlgorithmIdentifier to determine
+ the effective key length. In this case the effective key length can still
+ be 40 bits but the key length can be 168 bits for example. This is fixed
+ by manually forcing an RC2 key into the EVP_PKEY structure because the
+ EVP code can't currently handle unusual RC2 key sizes: it always assumes
+ the key length and effective key length are equal.
+ [Steve Henson]
+
+ *) Add a bunch of functions that should simplify the creation of
+ X509_NAME structures. Now you should be able to do:
+ X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, "Steve", -1, -1, 0);
+ and have it automatically work out the correct field type and fill in
+ the structures. The more adventurous can try:
+ X509_NAME_add_entry_by_txt(nm, field, MBSTRING_UTF8, str, -1, -1, 0);
+ and it will (hopefully) work out the correct multibyte encoding.
+ [Steve Henson]
+
+ *) Change the 'req' utility to use the new field handling and multibyte
+ copy routines. Before the DN field creation was handled in an ad hoc
+ way in req, ca, and x509 which was rather broken and didn't support
+ BMPStrings or UTF8Strings. Since some software doesn't implement
+ BMPStrings or UTF8Strings yet, they can be enabled using the config file
+ using the dirstring_type option. See the new comment in the default
+ openssl.cnf for more info.
+ [Steve Henson]
+
+ *) Make crypto/rand/md_rand.c more robust:
+ - Assure unique random numbers after fork().
+ - Make sure that concurrent threads access the global counter and
+ md serializably so that we never lose entropy in them
+ or use exactly the same state in multiple threads.
+ Access to the large state is not always serializable because
+ the additional locking could be a performance killer, and
+ md should be large enough anyway.
+ [Bodo Moeller]
+
+ *) New file apps/app_rand.c with commonly needed functionality
+ for handling the random seed file.
+
+ Use the random seed file in some applications that previously did not:
+ ca,
+ dsaparam -genkey (which also ignored its '-rand' option),
+ s_client,
+ s_server,
+ x509 (when signing).
+ Except on systems with /dev/urandom, it is crucial to have a random
+ seed file at least for key creation, DSA signing, and for DH exchanges;
+ for RSA signatures we could do without one.
+
+ gendh and gendsa (unlike genrsa) used to read only the first byte
+ of each file listed in the '-rand' option. The function as previously
+ found in genrsa is now in app_rand.c and is used by all programs
+ that support '-rand'.
+ [Bodo Moeller]
+
+ *) In RAND_write_file, use mode 0600 for creating files;
+ don't just chmod when it may be too late.
+ [Bodo Moeller]
+
+ *) Report an error from X509_STORE_load_locations
+ when X509_LOOKUP_load_file or X509_LOOKUP_add_dir failed.
+ [Bill Perry]
+
+ *) New function ASN1_mbstring_copy() this copies a string in either
+ ASCII, Unicode, Universal (4 bytes per character) or UTF8 format
+ into an ASN1_STRING type. A mask of permissible types is passed
+ and it chooses the "minimal" type to use or an error if not type
+ is suitable.
+ [Steve Henson]
+
+ *) Add function equivalents to the various macros in asn1.h. The old
+ macros are retained with an M_ prefix. Code inside the library can
+ use the M_ macros. External code (including the openssl utility)
+ should *NOT* in order to be "shared library friendly".
+ [Steve Henson]
+
+ *) Add various functions that can check a certificate's extensions
+ to see if it usable for various purposes such as SSL client,
+ server or S/MIME and CAs of these types. This is currently
+ VERY EXPERIMENTAL but will ultimately be used for certificate chain
+ verification. Also added a -purpose flag to x509 utility to
+ print out all the purposes.
+ [Steve Henson]
+
+ *) Add a CRYPTO_EX_DATA to X509 certificate structure and associated
+ functions.
+ [Steve Henson]
+
+ *) New X509V3_{X509,CRL,REVOKED}_get_d2i() functions. These will search
+ for, obtain and decode and extension and obtain its critical flag.
+ This allows all the necessary extension code to be handled in a
+ single function call.
+ [Steve Henson]
+
+ *) RC4 tune-up featuring 30-40% performance improvement on most RISC
+ platforms. See crypto/rc4/rc4_enc.c for further details.
+ [Andy Polyakov]
+
+ *) New -noout option to asn1parse. This causes no output to be produced
+ its main use is when combined with -strparse and -out to extract data
+ from a file (which may not be in ASN.1 format).
+ [Steve Henson]
+
+ *) Fix for pkcs12 program. It was hashing an invalid certificate pointer
+ when producing the local key id.
+ [Richard Levitte <levitte@stacken.kth.se>]
+
+ *) New option -dhparam in s_server. This allows a DH parameter file to be
+ stated explicitly. If it is not stated then it tries the first server
+ certificate file. The previous behaviour hard coded the filename
+ "server.pem".
+ [Steve Henson]
+
+ *) Add -pubin and -pubout options to the rsa and dsa commands. These allow
+ a public key to be input or output. For example:
+ openssl rsa -in key.pem -pubout -out pubkey.pem
+ Also added necessary DSA public key functions to handle this.
+ [Steve Henson]
+
+ *) Fix so PKCS7_dataVerify() doesn't crash if no certificates are contained
+ in the message. This was handled by allowing
+ X509_find_by_issuer_and_serial() to tolerate a NULL passed to it.
+ [Steve Henson, reported by Sampo Kellomaki <sampo@mail.neuronio.pt>]
+
+ *) Fix for bug in d2i_ASN1_bytes(): other ASN1 functions add an extra null
+ to the end of the strings whereas this didn't. This would cause problems
+ if strings read with d2i_ASN1_bytes() were later modified.
+ [Steve Henson, reported by Arne Ansper <arne@ats.cyber.ee>]
+
+ *) Fix for base64 decode bug. When a base64 bio reads only one line of
+ data and it contains EOF it will end up returning an error. This is
+ caused by input 46 bytes long. The cause is due to the way base64
+ BIOs find the start of base64 encoded data. They do this by trying a
+ trial decode on each line until they find one that works. When they
+ do a flag is set and it starts again knowing it can pass all the
+ data directly through the decoder. Unfortunately it doesn't reset
+ the context it uses. This means that if EOF is reached an attempt
+ is made to pass two EOFs through the context and this causes the
+ resulting error. This can also cause other problems as well. As is
+ usual with these problems it takes *ages* to find and the fix is
+ trivial: move one line.
+ [Steve Henson, reported by ian@uns.ns.ac.yu (Ivan Nejgebauer) ]
+
+ *) Ugly workaround to get s_client and s_server working under Windows. The
+ old code wouldn't work because it needed to select() on sockets and the
+ tty (for keypresses and to see if data could be written). Win32 only
+ supports select() on sockets so we select() with a 1s timeout on the
+ sockets and then see if any characters are waiting to be read, if none
+ are present then we retry, we also assume we can always write data to
+ the tty. This isn't nice because the code then blocks until we've
+ received a complete line of data and it is effectively polling the
+ keyboard at 1s intervals: however it's quite a bit better than not
+ working at all :-) A dedicated Windows application might handle this
+ with an event loop for example.
+ [Steve Henson]
+
+ *) Enhance RSA_METHOD structure. Now there are two extra methods, rsa_sign
+ and rsa_verify. When the RSA_FLAGS_SIGN_VER option is set these functions
+ will be called when RSA_sign() and RSA_verify() are used. This is useful
+ if rsa_pub_dec() and rsa_priv_enc() equivalents are not available.
+ For this to work properly RSA_public_decrypt() and RSA_private_encrypt()
+ should *not* be used: RSA_sign() and RSA_verify() must be used instead.
+ This necessitated the support of an extra signature type NID_md5_sha1
+ for SSL signatures and modifications to the SSL library to use it instead
+ of calling RSA_public_decrypt() and RSA_private_encrypt().
+ [Steve Henson]
+
+ *) Add new -verify -CAfile and -CApath options to the crl program, these
+ will lookup a CRL issuers certificate and verify the signature in a
+ similar way to the verify program. Tidy up the crl program so it
+ no longer accesses structures directly. Make the ASN1 CRL parsing a bit
+ less strict. It will now permit CRL extensions even if it is not
+ a V2 CRL: this will allow it to tolerate some broken CRLs.
+ [Steve Henson]
+
+ *) Initialize all non-automatic variables each time one of the openssl
+ sub-programs is started (this is necessary as they may be started
+ multiple times from the "OpenSSL>" prompt).
+ [Lennart Bang, Bodo Moeller]
+
+ *) Preliminary compilation option RSA_NULL which disables RSA crypto without
+ removing all other RSA functionality (this is what NO_RSA does). This
+ is so (for example) those in the US can disable those operations covered
+ by the RSA patent while allowing storage and parsing of RSA keys and RSA
+ key generation.
+ [Steve Henson]
+
+ *) Non-copying interface to BIO pairs.
+ (still largely untested)
+ [Bodo Moeller]
+
+ *) New function ANS1_tag2str() to convert an ASN1 tag to a descriptive
+ ASCII string. This was handled independently in various places before.
+ [Steve Henson]
+
+ *) New functions UTF8_getc() and UTF8_putc() that parse and generate
+ UTF8 strings a character at a time.
+ [Steve Henson]
+
+ *) Use client_version from client hello to select the protocol
+ (s23_srvr.c) and for RSA client key exchange verification
+ (s3_srvr.c), as required by the SSL 3.0/TLS 1.0 specifications.
+ [Bodo Moeller]
+
+ *) Add various utility functions to handle SPKACs, these were previously
+ handled by poking round in the structure internals. Added new function
+ NETSCAPE_SPKI_print() to print out SPKAC and a new utility 'spkac' to
+ print, verify and generate SPKACs. Based on an original idea from
+ Massimiliano Pala <madwolf@comune.modena.it> but extensively modified.
+ [Steve Henson]
+
+ *) RIPEMD160 is operational on all platforms and is back in 'make test'.
+ [Andy Polyakov]
+
+ *) Allow the config file extension section to be overwritten on the
+ command line. Based on an original idea from Massimiliano Pala
+ <madwolf@comune.modena.it>. The new option is called -extensions
+ and can be applied to ca, req and x509. Also -reqexts to override
+ the request extensions in req and -crlexts to override the crl extensions
+ in ca.
+ [Steve Henson]
+
+ *) Add new feature to the SPKAC handling in ca. Now you can include
+ the same field multiple times by preceding it by "XXXX." for example:
+ 1.OU="Unit name 1"
+ 2.OU="Unit name 2"
+ this is the same syntax as used in the req config file.
+ [Steve Henson]
+
+ *) Allow certificate extensions to be added to certificate requests. These
+ are specified in a 'req_extensions' option of the req section of the
+ config file. They can be printed out with the -text option to req but
+ are otherwise ignored at present.
+ [Steve Henson]
+
+ *) Fix a horrible bug in enc_read() in crypto/evp/bio_enc.c: if the first
+ data read consists of only the final block it would not decrypted because
+ EVP_CipherUpdate() would correctly report zero bytes had been decrypted.
+ A misplaced 'break' also meant the decrypted final block might not be
+ copied until the next read.
+ [Steve Henson]
+
+ *) Initial support for DH_METHOD. Again based on RSA_METHOD. Also added
+ a few extra parameters to the DH structure: these will be useful if
+ for example we want the value of 'q' or implement X9.42 DH.
+ [Steve Henson]
+
+ *) Initial support for DSA_METHOD. This is based on the RSA_METHOD and
+ provides hooks that allow the default DSA functions or functions on a
+ "per key" basis to be replaced. This allows hardware acceleration and
+ hardware key storage to be handled without major modification to the
+ library. Also added low level modexp hooks and CRYPTO_EX structure and
+ associated functions.
+ [Steve Henson]
+
+ *) Add a new flag to memory BIOs, BIO_FLAG_MEM_RDONLY. This marks the BIO
+ as "read only": it can't be written to and the buffer it points to will
+ not be freed. Reading from a read only BIO is much more efficient than
+ a normal memory BIO. This was added because there are several times when
+ an area of memory needs to be read from a BIO. The previous method was
+ to create a memory BIO and write the data to it, this results in two
+ copies of the data and an O(n^2) reading algorithm. There is a new
+ function BIO_new_mem_buf() which creates a read only memory BIO from
+ an area of memory. Also modified the PKCS#7 routines to use read only
+ memory BIOs.
+ [Steve Henson]
+
+ *) Bugfix: ssl23_get_client_hello did not work properly when called in
+ state SSL23_ST_SR_CLNT_HELLO_B, i.e. when the first 7 bytes of
+ a SSLv2-compatible client hello for SSLv3 or TLSv1 could be read,
+ but a retry condition occured while trying to read the rest.
+ [Bodo Moeller]
+
+ *) The PKCS7_ENC_CONTENT_new() function was setting the content type as
+ NID_pkcs7_encrypted by default: this was wrong since this should almost
+ always be NID_pkcs7_data. Also modified the PKCS7_set_type() to handle
+ the encrypted data type: this is a more sensible place to put it and it
+ allows the PKCS#12 code to be tidied up that duplicated this
+ functionality.
+ [Steve Henson]
+
+ *) Changed obj_dat.pl script so it takes its input and output files on
+ the command line. This should avoid shell escape redirection problems
+ under Win32.
+ [Steve Henson]
+
+ *) Initial support for certificate extension requests, these are included
+ in things like Xenroll certificate requests. Included functions to allow
+ extensions to be obtained and added.
+ [Steve Henson]
+
+ *) -crlf option to s_client and s_server for sending newlines as
+ CRLF (as required by many protocols).
+ [Bodo Moeller]
+
+ Changes between 0.9.3a and 0.9.4 [09 Aug 1999]
+
+ *) Install libRSAglue.a when OpenSSL is built with RSAref.
+ [Ralf S. Engelschall]
+
+ *) A few more ``#ifndef NO_FP_API / #endif'' pairs for consistency.
+ [Andrija Antonijevic <TheAntony2@bigfoot.com>]
+
+ *) Fix -startdate and -enddate (which was missing) arguments to 'ca'
+ program.
+ [Steve Henson]
+
+ *) New function DSA_dup_DH, which duplicates DSA parameters/keys as
+ DH parameters/keys (q is lost during that conversion, but the resulting
+ DH parameters contain its length).
+
+ For 1024-bit p, DSA_generate_parameters followed by DSA_dup_DH is
+ much faster than DH_generate_parameters (which creates parameters
+ where p = 2*q + 1), and also the smaller q makes DH computations
+ much more efficient (160-bit exponentiation instead of 1024-bit
+ exponentiation); so this provides a convenient way to support DHE
+ ciphersuites in SSL/TLS servers (see ssl/ssltest.c). It is of
+ utter importance to use
+ SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
+ or
+ SSL_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
+ when such DH parameters are used, because otherwise small subgroup
+ attacks may become possible!
+ [Bodo Moeller]
+
+ *) Avoid memory leak in i2d_DHparams.
+ [Bodo Moeller]
+
+ *) Allow the -k option to be used more than once in the enc program:
+ this allows the same encrypted message to be read by multiple recipients.
+ [Steve Henson]
+
+ *) New function OBJ_obj2txt(buf, buf_len, a, no_name), this converts
+ an ASN1_OBJECT to a text string. If the "no_name" parameter is set then
+ it will always use the numerical form of the OID, even if it has a short
+ or long name.
+ [Steve Henson]
+
+ *) Added an extra RSA flag: RSA_FLAG_EXT_PKEY. Previously the rsa_mod_exp
+ method only got called if p,q,dmp1,dmq1,iqmp components were present,
+ otherwise bn_mod_exp was called. In the case of hardware keys for example
+ no private key components need be present and it might store extra data
+ in the RSA structure, which cannot be accessed from bn_mod_exp.
+ By setting RSA_FLAG_EXT_PKEY rsa_mod_exp will always be called for
+ private key operations.
+ [Steve Henson]
+
+ *) Added support for SPARC Linux.
+ [Andy Polyakov]
+
+ *) pem_password_cb function type incompatibly changed from
+ typedef int pem_password_cb(char *buf, int size, int rwflag);
+ to
+ ....(char *buf, int size, int rwflag, void *userdata);
+ so that applications can pass data to their callbacks:
+ The PEM[_ASN1]_{read,write}... functions and macros now take an
+ additional void * argument, which is just handed through whenever
+ the password callback is called.
+ [Damien Miller <dmiller@ilogic.com.au>; tiny changes by Bodo Moeller]
+
+ New function SSL_CTX_set_default_passwd_cb_userdata.
+
+ Compatibility note: As many C implementations push function arguments
+ onto the stack in reverse order, the new library version is likely to
+ interoperate with programs that have been compiled with the old
+ pem_password_cb definition (PEM_whatever takes some data that
+ happens to be on the stack as its last argument, and the callback
+ just ignores this garbage); but there is no guarantee whatsoever that
+ this will work.
+
+ *) The -DPLATFORM="\"$(PLATFORM)\"" definition and the similar -DCFLAGS=...
+ (both in crypto/Makefile.ssl for use by crypto/cversion.c) caused
+ problems not only on Windows, but also on some Unix platforms.
+ To avoid problematic command lines, these definitions are now in an
+ auto-generated file crypto/buildinf.h (created by crypto/Makefile.ssl
+ for standard "make" builds, by util/mk1mf.pl for "mk1mf" builds).
+ [Bodo Moeller]
+
+ *) MIPS III/IV assembler module is reimplemented.
+ [Andy Polyakov]
+
+ *) More DES library cleanups: remove references to srand/rand and
+ delete an unused file.
+ [Ulf Möller]
+
+ *) Add support for the the free Netwide assembler (NASM) under Win32,
+ since not many people have MASM (ml) and it can be hard to obtain.
+ This is currently experimental but it seems to work OK and pass all
+ the tests. Check out INSTALL.W32 for info.
+ [Steve Henson]
+
+ *) Fix memory leaks in s3_clnt.c: All non-anonymous SSL3/TLS1 connections
+ without temporary keys kept an extra copy of the server key,
+ and connections with temporary keys did not free everything in case
+ of an error.
+ [Bodo Moeller]
+
+ *) New function RSA_check_key and new openssl rsa option -check
+ for verifying the consistency of RSA keys.
+ [Ulf Moeller, Bodo Moeller]
+
+ *) Various changes to make Win32 compile work:
+ 1. Casts to avoid "loss of data" warnings in p5_crpt2.c
+ 2. Change unsigned int to int in b_dump.c to avoid "signed/unsigned
+ comparison" warnings.
+ 3. Add sk_<TYPE>_sort to DEF file generator and do make update.
+ [Steve Henson]
+
+ *) Add a debugging option to PKCS#5 v2 key generation function: when
+ you #define DEBUG_PKCS5V2 passwords, salts, iteration counts and
+ derived keys are printed to stderr.
+ [Steve Henson]
+
+ *) Copy the flags in ASN1_STRING_dup().
+ [Roman E. Pavlov <pre@mo.msk.ru>]
+
+ *) The x509 application mishandled signing requests containing DSA
+ keys when the signing key was also DSA and the parameters didn't match.
+
+ It was supposed to omit the parameters when they matched the signing key:
+ the verifying software was then supposed to automatically use the CA's
+ parameters if they were absent from the end user certificate.
+
+ Omitting parameters is no longer recommended. The test was also
+ the wrong way round! This was probably due to unusual behaviour in
+ EVP_cmp_parameters() which returns 1 if the parameters match.
+ This meant that parameters were omitted when they *didn't* match and
+ the certificate was useless. Certificates signed with 'ca' didn't have
+ this bug.
+ [Steve Henson, reported by Doug Erickson <Doug.Erickson@Part.NET>]
+
+ *) Memory leak checking (-DCRYPTO_MDEBUG) had some problems.
+ The interface is as follows:
+ Applications can use
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) aka MemCheck_start(),
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) aka MemCheck_stop();
+ "off" is now the default.
+ The library internally uses
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) aka MemCheck_off(),
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) aka MemCheck_on()
+ to disable memory-checking temporarily.
+
+ Some inconsistent states that previously were possible (and were
+ even the default) are now avoided.
+
+ -DCRYPTO_MDEBUG_TIME is new and additionally stores the current time
+ with each memory chunk allocated; this is occasionally more helpful
+ than just having a counter.
+
+ -DCRYPTO_MDEBUG_THREAD is also new and adds the thread ID.
+
+ -DCRYPTO_MDEBUG_ALL enables all of the above, plus any future
+ extensions.
+ [Bodo Moeller]
+
+ *) Introduce "mode" for SSL structures (with defaults in SSL_CTX),
+ which largely parallels "options", but is for changing API behaviour,
+ whereas "options" are about protocol behaviour.
+ Initial "mode" flags are:
+
+ SSL_MODE_ENABLE_PARTIAL_WRITE Allow SSL_write to report success when
+ a single record has been written.
+ SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER Don't insist that SSL_write
+ retries use the same buffer location.
+ (But all of the contents must be
+ copied!)
+ [Bodo Moeller]
+
+ *) Bugfix: SSL_set_options ignored its parameter, only SSL_CTX_set_options
+ worked.
+
+ *) Fix problems with no-hmac etc.
+ [Ulf Möller, pointed out by Brian Wellington <bwelling@tislabs.com>]
+
+ *) New functions RSA_get_default_method(), RSA_set_method() and
+ RSA_get_method(). These allows replacement of RSA_METHODs without having
+ to mess around with the internals of an RSA structure.
+ [Steve Henson]
+
+ *) Fix memory leaks in DSA_do_sign and DSA_is_prime.
+ Also really enable memory leak checks in openssl.c and in some
+ test programs.
+ [Chad C. Mulligan, Bodo Moeller]
+
+ *) Fix a bug in d2i_ASN1_INTEGER() and i2d_ASN1_INTEGER() which can mess
+ up the length of negative integers. This has now been simplified to just
+ store the length when it is first determined and use it later, rather
+ than trying to keep track of where data is copied and updating it to
+ point to the end.
+ [Steve Henson, reported by Brien Wheeler
+ <bwheeler@authentica-security.com>]
+
+ *) Add a new function PKCS7_signatureVerify. This allows the verification
+ of a PKCS#7 signature but with the signing certificate passed to the
+ function itself. This contrasts with PKCS7_dataVerify which assumes the
+ certificate is present in the PKCS#7 structure. This isn't always the
+ case: certificates can be omitted from a PKCS#7 structure and be
+ distributed by "out of band" means (such as a certificate database).
+ [Steve Henson]
+
+ *) Complete the PEM_* macros with DECLARE_PEM versions to replace the
+ function prototypes in pem.h, also change util/mkdef.pl to add the
+ necessary function names.
+ [Steve Henson]
+
+ *) mk1mf.pl (used by Windows builds) did not properly read the
+ options set by Configure in the top level Makefile, and Configure
+ was not even able to write more than one option correctly.
+ Fixed, now "no-idea no-rc5 -DCRYPTO_MDEBUG" etc. works as intended.
+ [Bodo Moeller]
+
+ *) New functions CONF_load_bio() and CONF_load_fp() to allow a config
+ file to be loaded from a BIO or FILE pointer. The BIO version will
+ for example allow memory BIOs to contain config info.
+ [Steve Henson]
+
+ *) New function "CRYPTO_num_locks" that returns CRYPTO_NUM_LOCKS.
+ Whoever hopes to achieve shared-library compatibility across versions
+ must use this, not the compile-time macro.
+ (Exercise 0.9.4: Which is the minimum library version required by
+ such programs?)
+ Note: All this applies only to multi-threaded programs, others don't
+ need locks.
+ [Bodo Moeller]
+
+ *) Add missing case to s3_clnt.c state machine -- one of the new SSL tests
+ through a BIO pair triggered the default case, i.e.
+ SSLerr(...,SSL_R_UNKNOWN_STATE).
+ [Bodo Moeller]
+
+ *) New "BIO pair" concept (crypto/bio/bss_bio.c) so that applications
+ can use the SSL library even if none of the specific BIOs is
+ appropriate.
+ [Bodo Moeller]
+
+ *) Fix a bug in i2d_DSAPublicKey() which meant it returned the wrong value
+ for the encoded length.
+ [Jeon KyoungHo <khjeon@sds.samsung.co.kr>]
+
+ *) Add initial documentation of the X509V3 functions.
+ [Steve Henson]
+
+ *) Add a new pair of functions PEM_write_PKCS8PrivateKey() and
+ PEM_write_bio_PKCS8PrivateKey() that are equivalent to
+ PEM_write_PrivateKey() and PEM_write_bio_PrivateKey() but use the more
+ secure PKCS#8 private key format with a high iteration count.
+ [Steve Henson]
+
+ *) Fix determination of Perl interpreter: A perl or perl5
+ _directory_ in $PATH was also accepted as the interpreter.
+ [Ralf S. Engelschall]
+
+ *) Fix demos/sign/sign.c: well there wasn't anything strictly speaking
+ wrong with it but it was very old and did things like calling
+ PEM_ASN1_read() directly and used MD5 for the hash not to mention some
+ unusual formatting.
+ [Steve Henson]
+
+ *) Fix demos/selfsign.c: it used obsolete and deleted functions, changed
+ to use the new extension code.
+ [Steve Henson]
+
+ *) Implement the PEM_read/PEM_write functions in crypto/pem/pem_all.c
+ with macros. This should make it easier to change their form, add extra
+ arguments etc. Fix a few PEM prototypes which didn't have cipher as a
+ constant.
+ [Steve Henson]
+
+ *) Add to configuration table a new entry that can specify an alternative
+ name for unistd.h (for pre-POSIX systems); we need this for NeXTstep,
+ according to Mark Crispin <MRC@Panda.COM>.
+ [Bodo Moeller]
+
+#if 0
+ *) DES CBC did not update the IV. Weird.
+ [Ben Laurie]
+#else
+ des_cbc_encrypt does not update the IV, but des_ncbc_encrypt does.
+ Changing the behaviour of the former might break existing programs --
+ where IV updating is needed, des_ncbc_encrypt can be used.
+#endif
+
+ *) When bntest is run from "make test" it drives bc to check its
+ calculations, as well as internally checking them. If an internal check
+ fails, it needs to cause bc to give a non-zero result or make test carries
+ on without noticing the failure. Fixed.
+ [Ben Laurie]
+
+ *) DES library cleanups.
+ [Ulf Möller]
+
+ *) Add support for PKCS#5 v2.0 PBE algorithms. This will permit PKCS#8 to be
+ used with any cipher unlike PKCS#5 v1.5 which can at most handle 64 bit
+ ciphers. NOTE: although the key derivation function has been verified
+ against some published test vectors it has not been extensively tested
+ yet. Added a -v2 "cipher" option to pkcs8 application to allow the use
+ of v2.0.
+ [Steve Henson]
+
+ *) Instead of "mkdir -p", which is not fully portable, use new
+ Perl script "util/mkdir-p.pl".
+ [Bodo Moeller]
+
+ *) Rewrite the way password based encryption (PBE) is handled. It used to
+ assume that the ASN1 AlgorithmIdentifier parameter was a PBEParameter
+ structure. This was true for the PKCS#5 v1.5 and PKCS#12 PBE algorithms
+ but doesn't apply to PKCS#5 v2.0 where it can be something else. Now
+ the 'parameter' field of the AlgorithmIdentifier is passed to the
+ underlying key generation function so it must do its own ASN1 parsing.
+ This has also changed the EVP_PBE_CipherInit() function which now has a
+ 'parameter' argument instead of literal salt and iteration count values
+ and the function EVP_PBE_ALGOR_CipherInit() has been deleted.
+ [Steve Henson]
+
+ *) Support for PKCS#5 v1.5 compatible password based encryption algorithms
+ and PKCS#8 functionality. New 'pkcs8' application linked to openssl.
+ Needed to change the PEM_STRING_EVP_PKEY value which was just "PRIVATE
+ KEY" because this clashed with PKCS#8 unencrypted string. Since this
+ value was just used as a "magic string" and not used directly its
+ value doesn't matter.
+ [Steve Henson]
+
+ *) Introduce some semblance of const correctness to BN. Shame C doesn't
+ support mutable.
+ [Ben Laurie]
+
+ *) "linux-sparc64" configuration (ultrapenguin).
+ [Ray Miller <ray.miller@oucs.ox.ac.uk>]
+ "linux-sparc" configuration.
+ [Christian Forster <fo@hawo.stw.uni-erlangen.de>]
+
+ *) config now generates no-xxx options for missing ciphers.
+ [Ulf Möller]
+
+ *) Support the EBCDIC character set (work in progress).
+ File ebcdic.c not yet included because it has a different license.
+ [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
+
+ *) Support BS2000/OSD-POSIX.
+ [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
+
+ *) Make callbacks for key generation use void * instead of char *.
+ [Ben Laurie]
+
+ *) Make S/MIME samples compile (not yet tested).
+ [Ben Laurie]
+
+ *) Additional typesafe stacks.
+ [Ben Laurie]
+
+ *) New configuration variants "bsdi-elf-gcc" (BSD/OS 4.x).
+ [Bodo Moeller]
+
+
+ Changes between 0.9.3 and 0.9.3a [29 May 1999]
+
+ *) New configuration variant "sco5-gcc".
+
+ *) Updated some demos.
+ [Sean O Riordain, Wade Scholine]
+
+ *) Add missing BIO_free at exit of pkcs12 application.
+ [Wu Zhigang]
+
+ *) Fix memory leak in conf.c.
+ [Steve Henson]
+
+ *) Updates for Win32 to assembler version of MD5.
+ [Steve Henson]
+
+ *) Set #! path to perl in apps/der_chop to where we found it
+ instead of using a fixed path.
+ [Bodo Moeller]
+
+ *) SHA library changes for irix64-mips4-cc.
+ [Andy Polyakov]
+
+ *) Improvements for VMS support.
+ [Richard Levitte]
+
+
+ Changes between 0.9.2b and 0.9.3 [24 May 1999]
+
+ *) Bignum library bug fix. IRIX 6 passes "make test" now!
+ This also avoids the problems with SC4.2 and unpatched SC5.
+ [Andy Polyakov <appro@fy.chalmers.se>]
+
+ *) New functions sk_num, sk_value and sk_set to replace the previous macros.
+ These are required because of the typesafe stack would otherwise break
+ existing code. If old code used a structure member which used to be STACK
+ and is now STACK_OF (for example cert in a PKCS7_SIGNED structure) with
+ sk_num or sk_value it would produce an error because the num, data members
+ are not present in STACK_OF. Now it just produces a warning. sk_set
+ replaces the old method of assigning a value to sk_value
+ (e.g. sk_value(x, i) = y) which the library used in a few cases. Any code
+ that does this will no longer work (and should use sk_set instead) but
+ this could be regarded as a "questionable" behaviour anyway.
+ [Steve Henson]
+
+ *) Fix most of the other PKCS#7 bugs. The "experimental" code can now
+ correctly handle encrypted S/MIME data.
+ [Steve Henson]
+
+ *) Change type of various DES function arguments from des_cblock
+ (which means, in function argument declarations, pointer to char)
+ to des_cblock * (meaning pointer to array with 8 char elements),
+ which allows the compiler to do more typechecking; it was like
+ that back in SSLeay, but with lots of ugly casts.
+
+ Introduce new type const_des_cblock.
+ [Bodo Moeller]
+
+ *) Reorganise the PKCS#7 library and get rid of some of the more obvious
+ problems: find RecipientInfo structure that matches recipient certificate
+ and initialise the ASN1 structures properly based on passed cipher.
+ [Steve Henson]
+
+ *) Belatedly make the BN tests actually check the results.
+ [Ben Laurie]
+
+ *) Fix the encoding and decoding of negative ASN1 INTEGERS and conversion
+ to and from BNs: it was completely broken. New compilation option
+ NEG_PUBKEY_BUG to allow for some broken certificates that encode public
+ key elements as negative integers.
+ [Steve Henson]
+
+ *) Reorganize and speed up MD5.
+ [Andy Polyakov <appro@fy.chalmers.se>]
+
+ *) VMS support.
+ [Richard Levitte <richard@levitte.org>]
+
+ *) New option -out to asn1parse to allow the parsed structure to be
+ output to a file. This is most useful when combined with the -strparse
+ option to examine the output of things like OCTET STRINGS.
+ [Steve Henson]
+
+ *) Make SSL library a little more fool-proof by not requiring any longer
+ that SSL_set_{accept,connect}_state be called before
+ SSL_{accept,connect} may be used (SSL_set_..._state is omitted
+ in many applications because usually everything *appeared* to work as
+ intended anyway -- now it really works as intended).
+ [Bodo Moeller]
+
+ *) Move openssl.cnf out of lib/.
+ [Ulf Möller]
+
+ *) Fix various things to let OpenSSL even pass ``egcc -pipe -O2 -Wall
+ -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes
+ -Wmissing-declarations -Wnested-externs -Winline'' with EGCS 1.1.2+
+ [Ralf S. Engelschall]
+
+ *) Various fixes to the EVP and PKCS#7 code. It may now be able to
+ handle PKCS#7 enveloped data properly.
+ [Sebastian Akerman <sak@parallelconsulting.com>, modified by Steve]
+
+ *) Create a duplicate of the SSL_CTX's CERT in SSL_new instead of
+ copying pointers. The cert_st handling is changed by this in
+ various ways (and thus what used to be known as ctx->default_cert
+ is now called ctx->cert, since we don't resort to s->ctx->[default_]cert
+ any longer when s->cert does not give us what we need).
+ ssl_cert_instantiate becomes obsolete by this change.
+ As soon as we've got the new code right (possibly it already is?),
+ we have solved a couple of bugs of the earlier code where s->cert
+ was used as if it could not have been shared with other SSL structures.
+
+ Note that using the SSL API in certain dirty ways now will result
+ in different behaviour than observed with earlier library versions:
+ Changing settings for an SSL_CTX *ctx after having done s = SSL_new(ctx)
+ does not influence s as it used to.
+
+ In order to clean up things more thoroughly, inside SSL_SESSION
+ we don't use CERT any longer, but a new structure SESS_CERT
+ that holds per-session data (if available); currently, this is
+ the peer's certificate chain and, for clients, the server's certificate
+ and temporary key. CERT holds only those values that can have
+ meaningful defaults in an SSL_CTX.
+ [Bodo Moeller]
+
+ *) New function X509V3_EXT_i2d() to create an X509_EXTENSION structure
+ from the internal representation. Various PKCS#7 fixes: remove some
+ evil casts and set the enc_dig_alg field properly based on the signing
+ key type.
+ [Steve Henson]
+
+ *) Allow PKCS#12 password to be set from the command line or the
+ environment. Let 'ca' get its config file name from the environment
+ variables "OPENSSL_CONF" or "SSLEAY_CONF" (for consistency with 'req'
+ and 'x509').
+ [Steve Henson]
+
+ *) Allow certificate policies extension to use an IA5STRING for the
+ organization field. This is contrary to the PKIX definition but
+ VeriSign uses it and IE5 only recognises this form. Document 'x509'
+ extension option.
+ [Steve Henson]
+
+ *) Add PEDANTIC compiler flag to allow compilation with gcc -pedantic,
+ without disallowing inline assembler and the like for non-pedantic builds.
+ [Ben Laurie]
+
+ *) Support Borland C++ builder.
+ [Janez Jere <jj@void.si>, modified by Ulf Möller]
+
+ *) Support Mingw32.
+ [Ulf Möller]
+
+ *) SHA-1 cleanups and performance enhancements.
+ [Andy Polyakov <appro@fy.chalmers.se>]
+
+ *) Sparc v8plus assembler for the bignum library.
+ [Andy Polyakov <appro@fy.chalmers.se>]
+
+ *) Accept any -xxx and +xxx compiler options in Configure.
+ [Ulf Möller]
+
+ *) Update HPUX configuration.
+ [Anonymous]
+
+ *) Add missing sk_<type>_unshift() function to safestack.h
+ [Ralf S. Engelschall]
+
+ *) New function SSL_CTX_use_certificate_chain_file that sets the
+ "extra_cert"s in addition to the certificate. (This makes sense
+ only for "PEM" format files, as chains as a whole are not
+ DER-encoded.)
+ [Bodo Moeller]
+
+ *) Support verify_depth from the SSL API.
+ x509_vfy.c had what can be considered an off-by-one-error:
+ Its depth (which was not part of the external interface)
+ was actually counting the number of certificates in a chain;
+ now it really counts the depth.
+ [Bodo Moeller]
+
+ *) Bugfix in crypto/x509/x509_cmp.c: The SSLerr macro was used
+ instead of X509err, which often resulted in confusing error
+ messages since the error codes are not globally unique
+ (e.g. an alleged error in ssl3_accept when a certificate
+ didn't match the private key).
+
+ *) New function SSL_CTX_set_session_id_context that allows to set a default
+ value (so that you don't need SSL_set_session_id_context for each
+ connection using the SSL_CTX).
+ [Bodo Moeller]
+
+ *) OAEP decoding bug fix.
+ [Ulf Möller]
+
+ *) Support INSTALL_PREFIX for package builders, as proposed by
+ David Harris.
+ [Bodo Moeller]
+
+ *) New Configure options "threads" and "no-threads". For systems
+ where the proper compiler options are known (currently Solaris
+ and Linux), "threads" is the default.
+ [Bodo Moeller]
+
+ *) New script util/mklink.pl as a faster substitute for util/mklink.sh.
+ [Bodo Moeller]
+
+ *) Install various scripts to $(OPENSSLDIR)/misc, not to
+ $(INSTALLTOP)/bin -- they shouldn't clutter directories
+ such as /usr/local/bin.
+ [Bodo Moeller]
+
+ *) "make linux-shared" to build shared libraries.
+ [Niels Poppe <niels@netbox.org>]
+
+ *) New Configure option no-<cipher> (rsa, idea, rc5, ...).
+ [Ulf Möller]
+
+ *) Add the PKCS#12 API documentation to openssl.txt. Preliminary support for
+ extension adding in x509 utility.
+ [Steve Henson]
+
+ *) Remove NOPROTO sections and error code comments.
+ [Ulf Möller]
+
+ *) Partial rewrite of the DEF file generator to now parse the ANSI
+ prototypes.
+ [Steve Henson]
+
+ *) New Configure options --prefix=DIR and --openssldir=DIR.
+ [Ulf Möller]
+
+ *) Complete rewrite of the error code script(s). It is all now handled
+ by one script at the top level which handles error code gathering,
+ header rewriting and C source file generation. It should be much better
+ than the old method: it now uses a modified version of Ulf's parser to
+ read the ANSI prototypes in all header files (thus the old K&R definitions
+ aren't needed for error creation any more) and do a better job of
+ translating function codes into names. The old 'ASN1 error code imbedded
+ in a comment' is no longer necessary and it doesn't use .err files which
+ have now been deleted. Also the error code call doesn't have to appear all
+ on one line (which resulted in some large lines...).
+ [Steve Henson]
+
+ *) Change #include filenames from <foo.h> to <openssl/foo.h>.
+ [Bodo Moeller]
+
+ *) Change behaviour of ssl2_read when facing length-0 packets: Don't return
+ 0 (which usually indicates a closed connection), but continue reading.
+ [Bodo Moeller]
+
+ *) Fix some race conditions.
+ [Bodo Moeller]
+
+ *) Add support for CRL distribution points extension. Add Certificate
+ Policies and CRL distribution points documentation.
+ [Steve Henson]
+
+ *) Move the autogenerated header file parts to crypto/opensslconf.h.
+ [Ulf Möller]
+
+ *) Fix new 56-bit DES export ciphersuites: they were using 7 bytes instead of
+ 8 of keying material. Merlin has also confirmed interop with this fix
+ between OpenSSL and Baltimore C/SSL 2.0 and J/SSL 2.0.
+ [Merlin Hughes <merlin@baltimore.ie>]
+
+ *) Fix lots of warnings.
+ [Richard Levitte <levitte@stacken.kth.se>]
+
+ *) In add_cert_dir() in crypto/x509/by_dir.c, break out of the loop if
+ the directory spec didn't end with a LIST_SEPARATOR_CHAR.
+ [Richard Levitte <levitte@stacken.kth.se>]
+
+ *) Fix problems with sizeof(long) == 8.
+ [Andy Polyakov <appro@fy.chalmers.se>]
+
+ *) Change functions to ANSI C.
+ [Ulf Möller]
+
+ *) Fix typos in error codes.
+ [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>, Ulf Möller]
+
+ *) Remove defunct assembler files from Configure.
+ [Ulf Möller]
+
+ *) SPARC v8 assembler BIGNUM implementation.
+ [Andy Polyakov <appro@fy.chalmers.se>]
+
+ *) Support for Certificate Policies extension: both print and set.
+ Various additions to support the r2i method this uses.
+ [Steve Henson]
+
+ *) A lot of constification, and fix a bug in X509_NAME_oneline() that could
+ return a const string when you are expecting an allocated buffer.
+ [Ben Laurie]
+
+ *) Add support for ASN1 types UTF8String and VISIBLESTRING, also the CHOICE
+ types DirectoryString and DisplayText.
+ [Steve Henson]
+
+ *) Add code to allow r2i extensions to access the configuration database,
+ add an LHASH database driver and add several ctx helper functions.
+ [Steve Henson]
+
+ *) Fix an evil bug in bn_expand2() which caused various BN functions to
+ fail when they extended the size of a BIGNUM.
+ [Steve Henson]
+
+ *) Various utility functions to handle SXNet extension. Modify mkdef.pl to
+ support typesafe stack.
+ [Steve Henson]
+
+ *) Fix typo in SSL_[gs]et_options().
+ [Nils Frostberg <nils@medcom.se>]
+
+ *) Delete various functions and files that belonged to the (now obsolete)
+ old X509V3 handling code.
+ [Steve Henson]
+
+ *) New Configure option "rsaref".
+ [Ulf Möller]
+
+ *) Don't auto-generate pem.h.
+ [Bodo Moeller]
+
+ *) Introduce type-safe ASN.1 SETs.
+ [Ben Laurie]
+
+ *) Convert various additional casted stacks to type-safe STACK_OF() variants.
+ [Ben Laurie, Ralf S. Engelschall, Steve Henson]
+
+ *) Introduce type-safe STACKs. This will almost certainly break lots of code
+ that links with OpenSSL (well at least cause lots of warnings), but fear
+ not: the conversion is trivial, and it eliminates loads of evil casts. A
+ few STACKed things have been converted already. Feel free to convert more.
+ In the fullness of time, I'll do away with the STACK type altogether.
+ [Ben Laurie]
+
+ *) Add `openssl ca -revoke <certfile>' facility which revokes a certificate
+ specified in <certfile> by updating the entry in the index.txt file.
+ This way one no longer has to edit the index.txt file manually for
+ revoking a certificate. The -revoke option does the gory details now.
+ [Massimiliano Pala <madwolf@openca.org>, Ralf S. Engelschall]
+
+ *) Fix `openssl crl -noout -text' combination where `-noout' killed the
+ `-text' option at all and this way the `-noout -text' combination was
+ inconsistent in `openssl crl' with the friends in `openssl x509|rsa|dsa'.
+ [Ralf S. Engelschall]
+
+ *) Make sure a corresponding plain text error message exists for the
+ X509_V_ERR_CERT_REVOKED/23 error number which can occur when a
+ verify callback function determined that a certificate was revoked.
+ [Ralf S. Engelschall]
+
+ *) Bugfix: In test/testenc, don't test "openssl <cipher>" for
+ ciphers that were excluded, e.g. by -DNO_IDEA. Also, test
+ all available cipers including rc5, which was forgotten until now.
+ In order to let the testing shell script know which algorithms
+ are available, a new (up to now undocumented) command
+ "openssl list-cipher-commands" is used.
+ [Bodo Moeller]
+
+ *) Bugfix: s_client occasionally would sleep in select() when
+ it should have checked SSL_pending() first.
+ [Bodo Moeller]
+
+ *) New functions DSA_do_sign and DSA_do_verify to provide access to
+ the raw DSA values prior to ASN.1 encoding.
+ [Ulf Möller]
+
+ *) Tweaks to Configure
+ [Niels Poppe <niels@netbox.org>]
+
+ *) Add support for PKCS#5 v2.0 ASN1 PBES2 structures. No other support,
+ yet...
+ [Steve Henson]
+
+ *) New variables $(RANLIB) and $(PERL) in the Makefiles.
+ [Ulf Möller]
+
+ *) New config option to avoid instructions that are illegal on the 80386.
+ The default code is faster, but requires at least a 486.
+ [Ulf Möller]
+
+ *) Got rid of old SSL2_CLIENT_VERSION (inconsistently used) and
+ SSL2_SERVER_VERSION (not used at all) macros, which are now the
+ same as SSL2_VERSION anyway.
+ [Bodo Moeller]
+
+ *) New "-showcerts" option for s_client.
+ [Bodo Moeller]
+
+ *) Still more PKCS#12 integration. Add pkcs12 application to openssl
+ application. Various cleanups and fixes.
+ [Steve Henson]
+
+ *) More PKCS#12 integration. Add new pkcs12 directory with Makefile.ssl and
+ modify error routines to work internally. Add error codes and PBE init
+ to library startup routines.
+ [Steve Henson]
+
+ *) Further PKCS#12 integration. Added password based encryption, PKCS#8 and
+ packing functions to asn1 and evp. Changed function names and error
+ codes along the way.
+ [Steve Henson]
+
+ *) PKCS12 integration: and so it begins... First of several patches to
+ slowly integrate PKCS#12 functionality into OpenSSL. Add PKCS#12
+ objects to objects.h
+ [Steve Henson]
+
+ *) Add a new 'indent' option to some X509V3 extension code. Initial ASN1
+ and display support for Thawte strong extranet extension.
+ [Steve Henson]
+
+ *) Add LinuxPPC support.
+ [Jeff Dubrule <igor@pobox.org>]
+
+ *) Get rid of redundant BN file bn_mulw.c, and rename bn_div64 to
+ bn_div_words in alpha.s.
+ [Hannes Reinecke <H.Reinecke@hw.ac.uk> and Ben Laurie]
+
+ *) Make sure the RSA OAEP test is skipped under -DRSAref because
+ OAEP isn't supported when OpenSSL is built with RSAref.
+ [Ulf Moeller <ulf@fitug.de>]
+
+ *) Move definitions of IS_SET/IS_SEQUENCE inside crypto/asn1/asn1.h
+ so they no longer are missing under -DNOPROTO.
+ [Soren S. Jorvang <soren@t.dk>]
+
+
+ Changes between 0.9.1c and 0.9.2b [22 Mar 1999]
+
+ *) Make SSL_get_peer_cert_chain() work in servers. Unfortunately, it still
+ doesn't work when the session is reused. Coming soon!
+ [Ben Laurie]
+
+ *) Fix a security hole, that allows sessions to be reused in the wrong
+ context thus bypassing client cert protection! All software that uses
+ client certs and session caches in multiple contexts NEEDS PATCHING to
+ allow session reuse! A fuller solution is in the works.
+ [Ben Laurie, problem pointed out by Holger Reif, Bodo Moeller (and ???)]
+
+ *) Some more source tree cleanups (removed obsolete files
+ crypto/bf/asm/bf586.pl, test/test.txt and crypto/sha/asm/f.s; changed
+ permission on "config" script to be executable) and a fix for the INSTALL
+ document.
+ [Ulf Moeller <ulf@fitug.de>]
+
+ *) Remove some legacy and erroneous uses of malloc, free instead of
+ Malloc, Free.
+ [Lennart Bang <lob@netstream.se>, with minor changes by Steve]
+
+ *) Make rsa_oaep_test return non-zero on error.
+ [Ulf Moeller <ulf@fitug.de>]
+
+ *) Add support for native Solaris shared libraries. Configure
+ solaris-sparc-sc4-pic, make, then run shlib/solaris-sc4.sh. It'd be nice
+ if someone would make that last step automatic.
+ [Matthias Loepfe <Matthias.Loepfe@AdNovum.CH>]
+
+ *) ctx_size was not built with the right compiler during "make links". Fixed.
+ [Ben Laurie]
+
+ *) Change the meaning of 'ALL' in the cipher list. It now means "everything
+ except NULL ciphers". This means the default cipher list will no longer
+ enable NULL ciphers. They need to be specifically enabled e.g. with
+ the string "DEFAULT:eNULL".
+ [Steve Henson]
+
+ *) Fix to RSA private encryption routines: if p < q then it would
+ occasionally produce an invalid result. This will only happen with
+ externally generated keys because OpenSSL (and SSLeay) ensure p > q.
+ [Steve Henson]
+
+ *) Be less restrictive and allow also `perl util/perlpath.pl
+ /path/to/bin/perl' in addition to `perl util/perlpath.pl /path/to/bin',
+ because this way one can also use an interpreter named `perl5' (which is
+ usually the name of Perl 5.xxx on platforms where an Perl 4.x is still
+ installed as `perl').
+ [Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
+
+ *) Let util/clean-depend.pl work also with older Perl 5.00x versions.
+ [Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
+
+ *) Fix Makefile.org so CC,CFLAG etc are passed to 'make links' add
+ advapi32.lib to Win32 build and change the pem test comparision
+ to fc.exe (thanks to Ulrich Kroener <kroneru@yahoo.com> for the
+ suggestion). Fix misplaced ASNI prototypes and declarations in evp.h
+ and crypto/des/ede_cbcm_enc.c.
+ [Steve Henson]
+
+ *) DES quad checksum was broken on big-endian architectures. Fixed.
+ [Ben Laurie]
+
+ *) Comment out two functions in bio.h that aren't implemented. Fix up the
+ Win32 test batch file so it (might) work again. The Win32 test batch file
+ is horrible: I feel ill....
+ [Steve Henson]
+
+ *) Move various #ifdefs around so NO_SYSLOG, NO_DIRENT etc are now selected
+ in e_os.h. Audit of header files to check ANSI and non ANSI
+ sections: 10 functions were absent from non ANSI section and not exported
+ from Windows DLLs. Fixed up libeay.num for new functions.
+ [Steve Henson]
+
+ *) Make `openssl version' output lines consistent.
+ [Ralf S. Engelschall]
+
+ *) Fix Win32 symbol export lists for BIO functions: Added
+ BIO_get_ex_new_index, BIO_get_ex_num, BIO_get_ex_data and BIO_set_ex_data
+ to ms/libeay{16,32}.def.
+ [Ralf S. Engelschall]
+
+ *) Second round of fixing the OpenSSL perl/ stuff. It now at least compiled
+ fine under Unix and passes some trivial tests I've now added. But the
+ whole stuff is horribly incomplete, so a README.1ST with a disclaimer was
+ added to make sure no one expects that this stuff really works in the
+ OpenSSL 0.9.2 release. Additionally I've started to clean the XS sources
+ up and fixed a few little bugs and inconsistencies in OpenSSL.{pm,xs} and
+ openssl_bio.xs.
+ [Ralf S. Engelschall]
+
+ *) Fix the generation of two part addresses in perl.
+ [Kenji Miyake <kenji@miyake.org>, integrated by Ben Laurie]
+
+ *) Add config entry for Linux on MIPS.
+ [John Tobey <jtobey@channel1.com>]
+
+ *) Make links whenever Configure is run, unless we are on Windoze.
+ [Ben Laurie]
+
+ *) Permit extensions to be added to CRLs using crl_section in openssl.cnf.
+ Currently only issuerAltName and AuthorityKeyIdentifier make any sense
+ in CRLs.
+ [Steve Henson]
+
+ *) Add a useful kludge to allow package maintainers to specify compiler and
+ other platforms details on the command line without having to patch the
+ Configure script everytime: One now can use ``perl Configure
+ <id>:<details>'', i.e. platform ids are allowed to have details appended
+ to them (seperated by colons). This is treated as there would be a static
+ pre-configured entry in Configure's %table under key <id> with value
+ <details> and ``perl Configure <id>'' is called. So, when you want to
+ perform a quick test-compile under FreeBSD 3.1 with pgcc and without
+ assembler stuff you can use ``perl Configure "FreeBSD-elf:pgcc:-O6:::"''
+ now, which overrides the FreeBSD-elf entry on-the-fly.
+ [Ralf S. Engelschall]
+
+ *) Disable new TLS1 ciphersuites by default: they aren't official yet.
+ [Ben Laurie]
+
+ *) Allow DSO flags like -fpic, -fPIC, -KPIC etc. to be specified
+ on the `perl Configure ...' command line. This way one can compile
+ OpenSSL libraries with Position Independent Code (PIC) which is needed
+ for linking it into DSOs.
+ [Ralf S. Engelschall]
+
+ *) Remarkably, export ciphers were totally broken and no-one had noticed!
+ Fixed.
+ [Ben Laurie]
+
+ *) Cleaned up the LICENSE document: The official contact for any license
+ questions now is the OpenSSL core team under openssl-core@openssl.org.
+ And add a paragraph about the dual-license situation to make sure people
+ recognize that _BOTH_ the OpenSSL license _AND_ the SSLeay license apply
+ to the OpenSSL toolkit.
+ [Ralf S. Engelschall]
+
+ *) General source tree makefile cleanups: Made `making xxx in yyy...'
+ display consistent in the source tree and replaced `/bin/rm' by `rm'.
+ Additonally cleaned up the `make links' target: Remove unnecessary
+ semicolons, subsequent redundant removes, inline point.sh into mklink.sh
+ to speed processing and no longer clutter the display with confusing
+ stuff. Instead only the actually done links are displayed.
+ [Ralf S. Engelschall]
+
+ *) Permit null encryption ciphersuites, used for authentication only. It used
+ to be necessary to set the preprocessor define SSL_ALLOW_ENULL to do this.
+ It is now necessary to set SSL_FORBID_ENULL to prevent the use of null
+ encryption.
+ [Ben Laurie]
+
+ *) Add a bunch of fixes to the PKCS#7 stuff. It used to sometimes reorder
+ signed attributes when verifying signatures (this would break them),
+ the detached data encoding was wrong and public keys obtained using
+ X509_get_pubkey() weren't freed.
+ [Steve Henson]
+
+ *) Add text documentation for the BUFFER functions. Also added a work around
+ to a Win95 console bug. This was triggered by the password read stuff: the
+ last character typed gets carried over to the next fread(). If you were
+ generating a new cert request using 'req' for example then the last
+ character of the passphrase would be CR which would then enter the first
+ field as blank.
+ [Steve Henson]
+
+ *) Added the new `Includes OpenSSL Cryptography Software' button as
+ doc/openssl_button.{gif,html} which is similar in style to the old SSLeay
+ button and can be used by applications based on OpenSSL to show the
+ relationship to the OpenSSL project.
+ [Ralf S. Engelschall]
+
+ *) Remove confusing variables in function signatures in files
+ ssl/ssl_lib.c and ssl/ssl.h.
+ [Lennart Bong <lob@kulthea.stacken.kth.se>]
+
+ *) Don't install bss_file.c under PREFIX/include/
+ [Lennart Bong <lob@kulthea.stacken.kth.se>]
+
+ *) Get the Win32 compile working again. Modify mkdef.pl so it can handle
+ functions that return function pointers and has support for NT specific
+ stuff. Fix mk1mf.pl and VC-32.pl to support NT differences also. Various
+ #ifdef WIN32 and WINNTs sprinkled about the place and some changes from
+ unsigned to signed types: this was killing the Win32 compile.
+ [Steve Henson]
+
+ *) Add new certificate file to stack functions,
+ SSL_add_dir_cert_subjects_to_stack() and
+ SSL_add_file_cert_subjects_to_stack(). These largely supplant
+ SSL_load_client_CA_file(), and can be used to add multiple certs easily
+ to a stack (usually this is then handed to SSL_CTX_set_client_CA_list()).
+ This means that Apache-SSL and similar packages don't have to mess around
+ to add as many CAs as they want to the preferred list.
+ [Ben Laurie]
+
+ *) Experiment with doxygen documentation. Currently only partially applied to
+ ssl/ssl_lib.c.
+ See http://www.stack.nl/~dimitri/doxygen/index.html, and run doxygen with
+ openssl.doxy as the configuration file.
+ [Ben Laurie]
+
+ *) Get rid of remaining C++-style comments which strict C compilers hate.
+ [Ralf S. Engelschall, pointed out by Carlos Amengual]
+
+ *) Changed BN_RECURSION in bn_mont.c to BN_RECURSION_MONT so it is not
+ compiled in by default: it has problems with large keys.
+ [Steve Henson]
+
+ *) Add a bunch of SSL_xxx() functions for configuring the temporary RSA and
+ DH private keys and/or callback functions which directly correspond to
+ their SSL_CTX_xxx() counterparts but work on a per-connection basis. This
+ is needed for applications which have to configure certificates on a
+ per-connection basis (e.g. Apache+mod_ssl) instead of a per-context basis
+ (e.g. s_server).
+ For the RSA certificate situation is makes no difference, but
+ for the DSA certificate situation this fixes the "no shared cipher"
+ problem where the OpenSSL cipher selection procedure failed because the
+ temporary keys were not overtaken from the context and the API provided
+ no way to reconfigure them.
+ The new functions now let applications reconfigure the stuff and they
+ are in detail: SSL_need_tmp_RSA, SSL_set_tmp_rsa, SSL_set_tmp_dh,
+ SSL_set_tmp_rsa_callback and SSL_set_tmp_dh_callback. Additionally a new
+ non-public-API function ssl_cert_instantiate() is used as a helper
+ function and also to reduce code redundancy inside ssl_rsa.c.
+ [Ralf S. Engelschall]
+
+ *) Move s_server -dcert and -dkey options out of the undocumented feature
+ area because they are useful for the DSA situation and should be
+ recognized by the users.
+ [Ralf S. Engelschall]
+
+ *) Fix the cipher decision scheme for export ciphers: the export bits are
+ *not* within SSL_MKEY_MASK or SSL_AUTH_MASK, they are within
+ SSL_EXP_MASK. So, the original variable has to be used instead of the
+ already masked variable.
+ [Richard Levitte <levitte@stacken.kth.se>]
+
+ *) Fix 'port' variable from `int' to `unsigned int' in crypto/bio/b_sock.c
+ [Richard Levitte <levitte@stacken.kth.se>]
+
+ *) Change type of another md_len variable in pk7_doit.c:PKCS7_dataFinal()
+ from `int' to `unsigned int' because it's a length and initialized by
+ EVP_DigestFinal() which expects an `unsigned int *'.
+ [Richard Levitte <levitte@stacken.kth.se>]
+
+ *) Don't hard-code path to Perl interpreter on shebang line of Configure
+ script. Instead use the usual Shell->Perl transition trick.
+ [Ralf S. Engelschall]
+
+ *) Make `openssl x509 -noout -modulus' functional also for DSA certificates
+ (in addition to RSA certificates) to match the behaviour of `openssl dsa
+ -noout -modulus' as it's already the case for `openssl rsa -noout
+ -modulus'. For RSA the -modulus is the real "modulus" while for DSA
+ currently the public key is printed (a decision which was already done by
+ `openssl dsa -modulus' in the past) which serves a similar purpose.
+ Additionally the NO_RSA no longer completely removes the whole -modulus
+ option; it now only avoids using the RSA stuff. Same applies to NO_DSA
+ now, too.
+ [Ralf S. Engelschall]
+
+ *) Add Arne Ansper's reliable BIO - this is an encrypted, block-digested
+ BIO. See the source (crypto/evp/bio_ok.c) for more info.
+ [Arne Ansper <arne@ats.cyber.ee>]
+
+ *) Dump the old yucky req code that tried (and failed) to allow raw OIDs
+ to be added. Now both 'req' and 'ca' can use new objects defined in the
+ config file.
+ [Steve Henson]
+
+ *) Add cool BIO that does syslog (or event log on NT).
+ [Arne Ansper <arne@ats.cyber.ee>, integrated by Ben Laurie]
+
+ *) Add support for new TLS ciphersuites, TLS_RSA_EXPORT56_WITH_RC4_56_MD5,
+ TLS_RSA_EXPORT56_WITH_RC2_CBC_56_MD5 and
+ TLS_RSA_EXPORT56_WITH_DES_CBC_SHA, as specified in "56-bit Export Cipher
+ Suites For TLS", draft-ietf-tls-56-bit-ciphersuites-00.txt.
+ [Ben Laurie]
+
+ *) Add preliminary config info for new extension code.
+ [Steve Henson]
+
+ *) Make RSA_NO_PADDING really use no padding.
+ [Ulf Moeller <ulf@fitug.de>]
+
+ *) Generate errors when private/public key check is done.
+ [Ben Laurie]
+
+ *) Overhaul for 'crl' utility. New function X509_CRL_print. Partial support
+ for some CRL extensions and new objects added.
+ [Steve Henson]
+
+ *) Really fix the ASN1 IMPLICIT bug this time... Partial support for private
+ key usage extension and fuller support for authority key id.
+ [Steve Henson]
+
+ *) Add OAEP encryption for the OpenSSL crypto library. OAEP is the improved
+ padding method for RSA, which is recommended for new applications in PKCS
+ #1 v2.0 (RFC 2437, October 1998).
+ OAEP (Optimal Asymmetric Encryption Padding) has better theoretical
+ foundations than the ad-hoc padding used in PKCS #1 v1.5. It is secure
+ against Bleichbacher's attack on RSA.
+ [Ulf Moeller <ulf@fitug.de>, reformatted, corrected and integrated by
+ Ben Laurie]
+
+ *) Updates to the new SSL compression code
+ [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
+
+ *) Fix so that the version number in the master secret, when passed
+ via RSA, checks that if TLS was proposed, but we roll back to SSLv3
+ (because the server will not accept higher), that the version number
+ is 0x03,0x01, not 0x03,0x00
+ [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
+
+ *) Run extensive memory leak checks on SSL apps. Fixed *lots* of memory
+ leaks in ssl/ relating to new X509_get_pubkey() behaviour. Also fixes
+ in apps/ and an unrelated leak in crypto/dsa/dsa_vrf.c
+ [Steve Henson]
+
+ *) Support for RAW extensions where an arbitrary extension can be
+ created by including its DER encoding. See apps/openssl.cnf for
+ an example.
+ [Steve Henson]
+
+ *) Make sure latest Perl versions don't interpret some generated C array
+ code as Perl array code in the crypto/err/err_genc.pl script.
+ [Lars Weber <3weber@informatik.uni-hamburg.de>]
+
+ *) Modify ms/do_ms.bat to not generate assembly language makefiles since
+ not many people have the assembler. Various Win32 compilation fixes and
+ update to the INSTALL.W32 file with (hopefully) more accurate Win32
+ build instructions.
+ [Steve Henson]
+
+ *) Modify configure script 'Configure' to automatically create crypto/date.h
+ file under Win32 and also build pem.h from pem.org. New script
+ util/mkfiles.pl to create the MINFO file on environments that can't do a
+ 'make files': perl util/mkfiles.pl >MINFO should work.
+ [Steve Henson]
+
+ *) Major rework of DES function declarations, in the pursuit of correctness
+ and purity. As a result, many evil casts evaporated, and some weirdness,
+ too. You may find this causes warnings in your code. Zapping your evil
+ casts will probably fix them. Mostly.
+ [Ben Laurie]
+
+ *) Fix for a typo in asn1.h. Bug fix to object creation script
+ obj_dat.pl. It considered a zero in an object definition to mean
+ "end of object": none of the objects in objects.h have any zeros
+ so it wasn't spotted.
+ [Steve Henson, reported by Erwann ABALEA <eabalea@certplus.com>]
+
+ *) Add support for Triple DES Cipher Block Chaining with Output Feedback
+ Masking (CBCM). In the absence of test vectors, the best I have been able
+ to do is check that the decrypt undoes the encrypt, so far. Send me test
+ vectors if you have them.
+ [Ben Laurie]
+
+ *) Correct calculation of key length for export ciphers (too much space was
+ allocated for null ciphers). This has not been tested!
+ [Ben Laurie]
+
+ *) Modifications to the mkdef.pl for Win32 DEF file creation. The usage
+ message is now correct (it understands "crypto" and "ssl" on its
+ command line). There is also now an "update" option. This will update
+ the util/ssleay.num and util/libeay.num files with any new functions.
+ If you do a:
+ perl util/mkdef.pl crypto ssl update
+ it will update them.
+ [Steve Henson]
+
+ *) Overhauled the Perl interface (perl/*):
+ - ported BN stuff to OpenSSL's different BN library
+ - made the perl/ source tree CVS-aware
+ - renamed the package from SSLeay to OpenSSL (the files still contain
+ their history because I've copied them in the repository)
+ - removed obsolete files (the test scripts will be replaced
+ by better Test::Harness variants in the future)
+ [Ralf S. Engelschall]
+
+ *) First cut for a very conservative source tree cleanup:
+ 1. merge various obsolete readme texts into doc/ssleay.txt
+ where we collect the old documents and readme texts.
+ 2. remove the first part of files where I'm already sure that we no
+ longer need them because of three reasons: either they are just temporary
+ files which were left by Eric or they are preserved original files where
+ I've verified that the diff is also available in the CVS via "cvs diff
+ -rSSLeay_0_8_1b" or they were renamed (as it was definitely the case for
+ the crypto/md/ stuff).
+ [Ralf S. Engelschall]
+
+ *) More extension code. Incomplete support for subject and issuer alt
+ name, issuer and authority key id. Change the i2v function parameters
+ and add an extra 'crl' parameter in the X509V3_CTX structure: guess
+ what that's for :-) Fix to ASN1 macro which messed up
+ IMPLICIT tag and add f_enum.c which adds a2i, i2a for ENUMERATED.
+ [Steve Henson]
+
+ *) Preliminary support for ENUMERATED type. This is largely copied from the
+ INTEGER code.
+ [Steve Henson]
+
+ *) Add new function, EVP_MD_CTX_copy() to replace frequent use of memcpy.
+ [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
+
+ *) Make sure `make rehash' target really finds the `openssl' program.
+ [Ralf S. Engelschall, Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
+
+ *) Squeeze another 7% of speed out of MD5 assembler, at least on a P2. I'd
+ like to hear about it if this slows down other processors.
+ [Ben Laurie]
+
+ *) Add CygWin32 platform information to Configure script.
+ [Alan Batie <batie@aahz.jf.intel.com>]
+
+ *) Fixed ms/32all.bat script: `no_asm' -> `no-asm'
+ [Rainer W. Gerling <gerling@mpg-gv.mpg.de>]
+
+ *) New program nseq to manipulate netscape certificate sequences
+ [Steve Henson]
+
+ *) Modify crl2pkcs7 so it supports multiple -certfile arguments. Fix a
+ few typos.
+ [Steve Henson]
+
+ *) Fixes to BN code. Previously the default was to define BN_RECURSION
+ but the BN code had some problems that would cause failures when
+ doing certificate verification and some other functions.
+ [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
+
+ *) Add ASN1 and PEM code to support netscape certificate sequences.
+ [Steve Henson]
+
+ *) Add ASN1 and PEM code to support netscape certificate sequences.
+ [Steve Henson]
+
+ *) Add several PKIX and private extended key usage OIDs.
+ [Steve Henson]
+
+ *) Modify the 'ca' program to handle the new extension code. Modify
+ openssl.cnf for new extension format, add comments.
+ [Steve Henson]
+
+ *) More X509 V3 changes. Fix typo in v3_bitstr.c. Add support to 'req'
+ and add a sample to openssl.cnf so req -x509 now adds appropriate
+ CA extensions.
+ [Steve Henson]
+
+ *) Continued X509 V3 changes. Add to other makefiles, integrate with the
+ error code, add initial support to X509_print() and x509 application.
+ [Steve Henson]
+
+ *) Takes a deep breath and start addding X509 V3 extension support code. Add
+ files in crypto/x509v3. Move original stuff to crypto/x509v3/old. All this
+ stuff is currently isolated and isn't even compiled yet.
+ [Steve Henson]
+
+ *) Continuing patches for GeneralizedTime. Fix up certificate and CRL
+ ASN1 to use ASN1_TIME and modify print routines to use ASN1_TIME_print.
+ Removed the versions check from X509 routines when loading extensions:
+ this allows certain broken certificates that don't set the version
+ properly to be processed.
+ [Steve Henson]
+
+ *) Deal with irritating shit to do with dependencies, in YAAHW (Yet Another
+ Ad Hoc Way) - Makefile.ssls now all contain local dependencies, which
+ can still be regenerated with "make depend".
+ [Ben Laurie]
+
+ *) Spelling mistake in C version of CAST-128.
+ [Ben Laurie, reported by Jeremy Hylton <jeremy@cnri.reston.va.us>]
+
+ *) Changes to the error generation code. The perl script err-code.pl
+ now reads in the old error codes and retains the old numbers, only
+ adding new ones if necessary. It also only changes the .err files if new
+ codes are added. The makefiles have been modified to only insert errors
+ when needed (to avoid needlessly modifying header files). This is done
+ by only inserting errors if the .err file is newer than the auto generated
+ C file. To rebuild all the error codes from scratch (the old behaviour)
+ either modify crypto/Makefile.ssl to pass the -regen flag to err_code.pl
+ or delete all the .err files.
+ [Steve Henson]
+
+ *) CAST-128 was incorrectly implemented for short keys. The C version has
+ been fixed, but is untested. The assembler versions are also fixed, but
+ new assembler HAS NOT BEEN GENERATED FOR WIN32 - the Makefile needs fixing
+ to regenerate it if needed.
+ [Ben Laurie, reported (with fix for C version) by Jun-ichiro itojun
+ Hagino <itojun@kame.net>]
+
+ *) File was opened incorrectly in randfile.c.
+ [Ulf Möller <ulf@fitug.de>]
+
+ *) Beginning of support for GeneralizedTime. d2i, i2d, check and print
+ functions. Also ASN1_TIME suite which is a CHOICE of UTCTime or
+ GeneralizedTime. ASN1_TIME is the proper type used in certificates et
+ al: it's just almost always a UTCTime. Note this patch adds new error
+ codes so do a "make errors" if there are problems.
+ [Steve Henson]
+
+ *) Correct Linux 1 recognition in config.
+ [Ulf Möller <ulf@fitug.de>]
+
+ *) Remove pointless MD5 hash when using DSA keys in ca.
+ [Anonymous <nobody@replay.com>]
+
+ *) Generate an error if given an empty string as a cert directory. Also
+ generate an error if handed NULL (previously returned 0 to indicate an
+ error, but didn't set one).
+ [Ben Laurie, reported by Anonymous <nobody@replay.com>]
+
+ *) Add prototypes to SSL methods. Make SSL_write's buffer const, at last.
+ [Ben Laurie]
+
+ *) Fix the dummy function BN_ref_mod_exp() in rsaref.c to have the correct
+ parameters. This was causing a warning which killed off the Win32 compile.
+ [Steve Henson]
+
+ *) Remove C++ style comments from crypto/bn/bn_local.h.
+ [Neil Costigan <neil.costigan@celocom.com>]
+
+ *) The function OBJ_txt2nid was broken. It was supposed to return a nid
+ based on a text string, looking up short and long names and finally
+ "dot" format. The "dot" format stuff didn't work. Added new function
+ OBJ_txt2obj to do the same but return an ASN1_OBJECT and rewrote
+ OBJ_txt2nid to use it. OBJ_txt2obj can also return objects even if the
+ OID is not part of the table.
+ [Steve Henson]
+
+ *) Add prototypes to X509 lookup/verify methods, fixing a bug in
+ X509_LOOKUP_by_alias().
+ [Ben Laurie]
+
+ *) Sort openssl functions by name.
+ [Ben Laurie]
+
+ *) Get the gendsa program working (hopefully) and add it to app list. Remove
+ encryption from sample DSA keys (in case anyone is interested the password
+ was "1234").
+ [Steve Henson]
+
+ *) Make _all_ *_free functions accept a NULL pointer.
+ [Frans Heymans <fheymans@isaserver.be>]
+
+ *) If a DH key is generated in s3_srvr.c, don't blow it by trying to use
+ NULL pointers.
+ [Anonymous <nobody@replay.com>]
+
+ *) s_server should send the CAfile as acceptable CAs, not its own cert.
+ [Bodo Moeller <3moeller@informatik.uni-hamburg.de>]
+
+ *) Don't blow it for numeric -newkey arguments to apps/req.
+ [Bodo Moeller <3moeller@informatik.uni-hamburg.de>]
+
+ *) Temp key "for export" tests were wrong in s3_srvr.c.
+ [Anonymous <nobody@replay.com>]
+
+ *) Add prototype for temp key callback functions
+ SSL_CTX_set_tmp_{rsa,dh}_callback().
+ [Ben Laurie]
+
+ *) Make DH_free() tolerate being passed a NULL pointer (like RSA_free() and
+ DSA_free()). Make X509_PUBKEY_set() check for errors in d2i_PublicKey().
+ [Steve Henson]
+
+ *) X509_name_add_entry() freed the wrong thing after an error.
+ [Arne Ansper <arne@ats.cyber.ee>]
+
+ *) rsa_eay.c would attempt to free a NULL context.
+ [Arne Ansper <arne@ats.cyber.ee>]
+
+ *) BIO_s_socket() had a broken should_retry() on Windoze.
+ [Arne Ansper <arne@ats.cyber.ee>]
+
+ *) BIO_f_buffer() didn't pass on BIO_CTRL_FLUSH.
+ [Arne Ansper <arne@ats.cyber.ee>]
+
+ *) Make sure the already existing X509_STORE->depth variable is initialized
+ in X509_STORE_new(), but document the fact that this variable is still
+ unused in the certificate verification process.
+ [Ralf S. Engelschall]
+
+ *) Fix the various library and apps files to free up pkeys obtained from
+ X509_PUBKEY_get() et al. Also allow x509.c to handle netscape extensions.
+ [Steve Henson]
+
+ *) Fix reference counting in X509_PUBKEY_get(). This makes
+ demos/maurice/example2.c work, amongst others, probably.
+ [Steve Henson and Ben Laurie]
+
+ *) First cut of a cleanup for apps/. First the `ssleay' program is now named
+ `openssl' and second, the shortcut symlinks for the `openssl <command>'
+ are no longer created. This way we have a single and consistent command
+ line interface `openssl <command>', similar to `cvs <command>'.
+ [Ralf S. Engelschall, Paul Sutton and Ben Laurie]
+
+ *) ca.c: move test for DSA keys inside #ifndef NO_DSA. Make pubkey
+ BIT STRING wrapper always have zero unused bits.
+ [Steve Henson]
+
+ *) Add CA.pl, perl version of CA.sh, add extended key usage OID.
+ [Steve Henson]
+
+ *) Make the top-level INSTALL documentation easier to understand.
+ [Paul Sutton]
+
+ *) Makefiles updated to exit if an error occurs in a sub-directory
+ make (including if user presses ^C) [Paul Sutton]
+
+ *) Make Montgomery context stuff explicit in RSA data structure.
+ [Ben Laurie]
+
+ *) Fix build order of pem and err to allow for generated pem.h.
+ [Ben Laurie]
+
+ *) Fix renumbering bug in X509_NAME_delete_entry().
+ [Ben Laurie]
+
+ *) Enhanced the err-ins.pl script so it makes the error library number
+ global and can add a library name. This is needed for external ASN1 and
+ other error libraries.
+ [Steve Henson]
+
+ *) Fixed sk_insert which never worked properly.
+ [Steve Henson]
+
+ *) Fix ASN1 macros so they can handle indefinite length construted
+ EXPLICIT tags. Some non standard certificates use these: they can now
+ be read in.
+ [Steve Henson]
+
+ *) Merged the various old/obsolete SSLeay documentation files (doc/xxx.doc)
+ into a single doc/ssleay.txt bundle. This way the information is still
+ preserved but no longer messes up this directory. Now it's new room for
+ the new set of documenation files.
+ [Ralf S. Engelschall]
+
+ *) SETs were incorrectly DER encoded. This was a major pain, because they
+ shared code with SEQUENCEs, which aren't coded the same. This means that
+ almost everything to do with SETs or SEQUENCEs has either changed name or
+ number of arguments.
+ [Ben Laurie, based on a partial fix by GP Jayan <gp@nsj.co.jp>]
+
+ *) Fix test data to work with the above.
+ [Ben Laurie]
+
+ *) Fix the RSA header declarations that hid a bug I fixed in 0.9.0b but
+ was already fixed by Eric for 0.9.1 it seems.
+ [Ben Laurie - pointed out by Ulf Möller <ulf@fitug.de>]
+
+ *) Autodetect FreeBSD3.
+ [Ben Laurie]
+
+ *) Fix various bugs in Configure. This affects the following platforms:
+ nextstep
+ ncr-scde
+ unixware-2.0
+ unixware-2.0-pentium
+ sco5-cc.
+ [Ben Laurie]
+
+ *) Eliminate generated files from CVS. Reorder tests to regenerate files
+ before they are needed.
+ [Ben Laurie]
+
+ *) Generate Makefile.ssl from Makefile.org (to keep CVS happy).
+ [Ben Laurie]
+
+
+ Changes between 0.9.1b and 0.9.1c [23-Dec-1998]
+
+ *) Added OPENSSL_VERSION_NUMBER to crypto/crypto.h and
+ changed SSLeay to OpenSSL in version strings.
+ [Ralf S. Engelschall]
+
+ *) Some fixups to the top-level documents.
+ [Paul Sutton]
+
+ *) Fixed the nasty bug where rsaref.h was not found under compile-time
+ because the symlink to include/ was missing.
+ [Ralf S. Engelschall]
+
+ *) Incorporated the popular no-RSA/DSA-only patches
+ which allow to compile a RSA-free SSLeay.
+ [Andrew Cooke / Interrader Ldt., Ralf S. Engelschall]
+
+ *) Fixed nasty rehash problem under `make -f Makefile.ssl links'
+ when "ssleay" is still not found.
+ [Ralf S. Engelschall]
+
+ *) Added more platforms to Configure: Cray T3E, HPUX 11,
+ [Ralf S. Engelschall, Beckmann <beckman@acl.lanl.gov>]
+
+ *) Updated the README file.
+ [Ralf S. Engelschall]
+
+ *) Added various .cvsignore files in the CVS repository subdirs
+ to make a "cvs update" really silent.
+ [Ralf S. Engelschall]
+
+ *) Recompiled the error-definition header files and added
+ missing symbols to the Win32 linker tables.
+ [Ralf S. Engelschall]
+
+ *) Cleaned up the top-level documents;
+ o new files: CHANGES and LICENSE
+ o merged VERSION, HISTORY* and README* files a CHANGES.SSLeay
+ o merged COPYRIGHT into LICENSE
+ o removed obsolete TODO file
+ o renamed MICROSOFT to INSTALL.W32
+ [Ralf S. Engelschall]
+
+ *) Removed dummy files from the 0.9.1b source tree:
+ crypto/asn1/x crypto/bio/cd crypto/bio/fg crypto/bio/grep crypto/bio/vi
+ crypto/bn/asm/......add.c crypto/bn/asm/a.out crypto/dsa/f crypto/md5/f
+ crypto/pem/gmon.out crypto/perlasm/f crypto/pkcs7/build crypto/rsa/f
+ crypto/sha/asm/f crypto/threads/f ms/zzz ssl/f ssl/f.mak test/f
+ util/f.mak util/pl/f util/pl/f.mak crypto/bf/bf_locl.old apps/f
+ [Ralf S. Engelschall]
+
+ *) Added various platform portability fixes.
+ [Mark J. Cox]
+
+ *) The Genesis of the OpenSSL rpject:
+ We start with the latest (unreleased) SSLeay version 0.9.1b which Eric A.
+ Young and Tim J. Hudson created while they were working for C2Net until
+ summer 1998.
+ [The OpenSSL Project]
+
+
+ Changes between 0.9.0b and 0.9.1b [not released]
+
+ *) Updated a few CA certificates under certs/
+ [Eric A. Young]
+
+ *) Changed some BIGNUM api stuff.
+ [Eric A. Young]
+
+ *) Various platform ports: OpenBSD, Ultrix, IRIX 64bit, NetBSD,
+ DGUX x86, Linux Alpha, etc.
+ [Eric A. Young]
+
+ *) New COMP library [crypto/comp/] for SSL Record Layer Compression:
+ RLE (dummy implemented) and ZLIB (really implemented when ZLIB is
+ available).
+ [Eric A. Young]
+
+ *) Add -strparse option to asn1pars program which parses nested
+ binary structures
+ [Dr Stephen Henson <shenson@bigfoot.com>]
+
+ *) Added "oid_file" to ssleay.cnf for "ca" and "req" programs.
+ [Eric A. Young]
+
+ *) DSA fix for "ca" program.
+ [Eric A. Young]
+
+ *) Added "-genkey" option to "dsaparam" program.
+ [Eric A. Young]
+
+ *) Added RIPE MD160 (rmd160) message digest.
+ [Eric A. Young]
+
+ *) Added -a (all) option to "ssleay version" command.
+ [Eric A. Young]
+
+ *) Added PLATFORM define which is the id given to Configure.
+ [Eric A. Young]
+
+ *) Added MemCheck_XXXX functions to crypto/mem.c for memory checking.
+ [Eric A. Young]
+
+ *) Extended the ASN.1 parser routines.
+ [Eric A. Young]
+
+ *) Extended BIO routines to support REUSEADDR, seek, tell, etc.
+ [Eric A. Young]
+
+ *) Added a BN_CTX to the BN library.
+ [Eric A. Young]
+
+ *) Fixed the weak key values in DES library
+ [Eric A. Young]
+
+ *) Changed API in EVP library for cipher aliases.
+ [Eric A. Young]
+
+ *) Added support for RC2/64bit cipher.
+ [Eric A. Young]
+
+ *) Converted the lhash library to the crypto/mem.c functions.
+ [Eric A. Young]
+
+ *) Added more recognized ASN.1 object ids.
+ [Eric A. Young]
+
+ *) Added more RSA padding checks for SSL/TLS.
+ [Eric A. Young]
+
+ *) Added BIO proxy/filter functionality.
+ [Eric A. Young]
+
+ *) Added extra_certs to SSL_CTX which can be used
+ send extra CA certificates to the client in the CA cert chain sending
+ process. It can be configured with SSL_CTX_add_extra_chain_cert().
+ [Eric A. Young]
+
+ *) Now Fortezza is denied in the authentication phase because
+ this is key exchange mechanism is not supported by SSLeay at all.
+ [Eric A. Young]
+
+ *) Additional PKCS1 checks.
+ [Eric A. Young]
+
+ *) Support the string "TLSv1" for all TLS v1 ciphers.
+ [Eric A. Young]
+
+ *) Added function SSL_get_ex_data_X509_STORE_CTX_idx() which gives the
+ ex_data index of the SSL context in the X509_STORE_CTX ex_data.
+ [Eric A. Young]
+
+ *) Fixed a few memory leaks.
+ [Eric A. Young]
+
+ *) Fixed various code and comment typos.
+ [Eric A. Young]
+
+ *) A minor bug in ssl/s3_clnt.c where there would always be 4 0
+ bytes sent in the client random.
+ [Edward Bishop <ebishop@spyglass.com>]
+
diff --git a/openssl/FAQ b/openssl/FAQ
index b34e1091c..0e008cbdd 100644
--- a/openssl/FAQ
+++ b/openssl/FAQ
@@ -1,1025 +1,1025 @@
-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?
-
-===============================================================================
-
-[MISC] ========================================================================
-
-* Which is the current version of OpenSSL?
-
-The current version is available from <URL: http://www.openssl.org>.
-OpenSSL 1.0.0d was released on Feb 8th, 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().
-
-
-===============================================================================
+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?
+
+===============================================================================
+
+[MISC] ========================================================================
+
+* Which is the current version of OpenSSL?
+
+The current version is available from <URL: http://www.openssl.org>.
+OpenSSL 1.0.0d was released on Feb 8th, 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().
+
+
+===============================================================================
diff --git a/openssl/LICENSE b/openssl/LICENSE
index 5cb670496..e47d101f1 100644
--- a/openssl/LICENSE
+++ b/openssl/LICENSE
@@ -1,127 +1,127 @@
-
- LICENSE ISSUES
- ==============
-
- The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
- the OpenSSL License and the original SSLeay license apply to the toolkit.
- See below for the actual license texts. Actually both licenses are BSD-style
- Open Source licenses. In case of any license issues related to OpenSSL
- please contact openssl-core@openssl.org.
-
- OpenSSL License
- ---------------
-
-/* ====================================================================
- * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
- Original SSLeay License
- -----------------------
-
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
+
+ LICENSE ISSUES
+ ==============
+
+ The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+ the OpenSSL License and the original SSLeay license apply to the toolkit.
+ See below for the actual license texts. Actually both licenses are BSD-style
+ Open Source licenses. In case of any license issues related to OpenSSL
+ please contact openssl-core@openssl.org.
+
+ OpenSSL License
+ ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
diff --git a/openssl/NEWS b/openssl/NEWS
index 2bf07a2c3..a9c9b7803 100644
--- a/openssl/NEWS
+++ b/openssl/NEWS
@@ -1,588 +1,588 @@
-
- NEWS
- ====
-
- This file gives a brief overview of the major changes between each OpenSSL
- release. For more details please read the CHANGES file.
-
- Major changes between OpenSSL 1.0.0c and OpenSSL 1.0.0d:
-
- o Fix for security issue CVE-2011-0014
-
- Major changes between OpenSSL 1.0.0b and OpenSSL 1.0.0c:
-
- o Fix for security issue CVE-2010-4180
- o Fix for CVE-2010-4252
- o Fix mishandling of absent EC point format extension.
- o Fix various platform compilation issues.
- o Corrected fix for security issue CVE-2010-3864.
-
- Major changes between OpenSSL 1.0.0a and OpenSSL 1.0.0b:
-
- o Fix for security issue CVE-2010-3864.
- o Fix for CVE-2010-2939
- o Fix WIN32 build system for GOST ENGINE.
-
- Major changes between OpenSSL 1.0.0 and OpenSSL 1.0.0a:
-
- o Fix for security issue CVE-2010-1633.
- o GOST MAC and CFB fixes.
-
- Major changes between OpenSSL 0.9.8n and OpenSSL 1.0.0:
-
- o RFC3280 path validation: sufficient to process PKITS tests.
- o Integrated support for PVK files and keyblobs.
- o Change default private key format to PKCS#8.
- o CMS support: able to process all examples in RFC4134
- o Streaming ASN1 encode support for PKCS#7 and CMS.
- o Multiple signer and signer add support for PKCS#7 and CMS.
- o ASN1 printing support.
- o Whirlpool hash algorithm added.
- o RFC3161 time stamp support.
- o New generalised public key API supporting ENGINE based algorithms.
- o New generalised public key API utilities.
- o New ENGINE supporting GOST algorithms.
- o SSL/TLS GOST ciphersuite support.
- o PKCS#7 and CMS GOST support.
- o RFC4279 PSK ciphersuite support.
- o Supported points format extension for ECC ciphersuites.
- o ecdsa-with-SHA224/256/384/512 signature types.
- o dsa-with-SHA224 and dsa-with-SHA256 signature types.
- o Opaque PRF Input TLS extension support.
- o Updated time routines to avoid OS limitations.
-
- Major changes between OpenSSL 0.9.8q and OpenSSL 0.9.8r:
-
- o Fix for security issue CVE-2011-0014
-
- Major changes between OpenSSL 0.9.8p and OpenSSL 0.9.8q:
-
- o Fix for security issue CVE-2010-4180
- o Fix for CVE-2010-4252
-
- Major changes between OpenSSL 0.9.8o and OpenSSL 0.9.8p:
-
- o Fix for security issue CVE-2010-3864.
-
- Major changes between OpenSSL 0.9.8n and OpenSSL 0.9.8o:
-
- o Fix for security issue CVE-2010-0742.
- o Various DTLS fixes.
- o Recognise SHA2 certificates if only SSL algorithms added.
- o Fix for no-rc4 compilation.
- o Chil ENGINE unload workaround.
-
- Major changes between OpenSSL 0.9.8m and OpenSSL 0.9.8n:
-
- o CFB cipher definition fixes.
- o Fix security issues CVE-2010-0740 and CVE-2010-0433.
-
- Major changes between OpenSSL 0.9.8l and OpenSSL 0.9.8m:
-
- o Cipher definition fixes.
- o Workaround for slow RAND_poll() on some WIN32 versions.
- o Remove MD2 from algorithm tables.
- o SPKAC handling fixes.
- o Support for RFC5746 TLS renegotiation extension.
- o Compression memory leak fixed.
- o Compression session resumption fixed.
- o Ticket and SNI coexistence fixes.
- o Many fixes to DTLS handling.
-
- Major changes between OpenSSL 0.9.8k and OpenSSL 0.9.8l:
-
- o Temporary work around for CVE-2009-3555: disable renegotiation.
-
- Major changes between OpenSSL 0.9.8j and OpenSSL 0.9.8k:
-
- o Fix various build issues.
- o Fix security issues (CVE-2009-0590, CVE-2009-0591, CVE-2009-0789)
-
- Major changes between OpenSSL 0.9.8i and OpenSSL 0.9.8j:
-
- o Fix security issue (CVE-2008-5077)
- o Merge FIPS 140-2 branch code.
-
- Major changes between OpenSSL 0.9.8g and OpenSSL 0.9.8h:
-
- o CryptoAPI ENGINE support.
- o Various precautionary measures.
- o Fix for bugs affecting certificate request creation.
- o Support for local machine keyset attribute in PKCS#12 files.
-
- Major changes between OpenSSL 0.9.8f and OpenSSL 0.9.8g:
-
- o Backport of CMS functionality to 0.9.8.
- o Fixes for bugs introduced with 0.9.8f.
-
- Major changes between OpenSSL 0.9.8e and OpenSSL 0.9.8f:
-
- o Add gcc 4.2 support.
- o Add support for AES and SSE2 assembly lanugauge optimization
- for VC++ build.
- o Support for RFC4507bis and server name extensions if explicitly
- selected at compile time.
- o DTLS improvements.
- o RFC4507bis support.
- o TLS Extensions support.
-
- Major changes between OpenSSL 0.9.8d and OpenSSL 0.9.8e:
-
- o Various ciphersuite selection fixes.
- o RFC3779 support.
-
- Major changes between OpenSSL 0.9.8c and OpenSSL 0.9.8d:
-
- o Introduce limits to prevent malicious key DoS (CVE-2006-2940)
- o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343)
- o Changes to ciphersuite selection algorithm
-
- Major changes between OpenSSL 0.9.8b and OpenSSL 0.9.8c:
-
- o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339
- o New cipher Camellia
-
- Major changes between OpenSSL 0.9.8a and OpenSSL 0.9.8b:
-
- o Cipher string fixes.
- o Fixes for VC++ 2005.
- o Updated ECC cipher suite support.
- o New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free().
- o Zlib compression usage fixes.
- o Built in dynamic engine compilation support on Win32.
- o Fixes auto dynamic engine loading in Win32.
-
- Major changes between OpenSSL 0.9.8 and OpenSSL 0.9.8a:
-
- o Fix potential SSL 2.0 rollback, CVE-2005-2969
- o Extended Windows CE support
-
- Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.8:
-
- o Major work on the BIGNUM library for higher efficiency and to
- make operations more streamlined and less contradictory. This
- is the result of a major audit of the BIGNUM library.
- o Addition of BIGNUM functions for fields GF(2^m) and NIST
- curves, to support the Elliptic Crypto functions.
- o Major work on Elliptic Crypto; ECDH and ECDSA added, including
- the use through EVP, X509 and ENGINE.
- o New ASN.1 mini-compiler that's usable through the OpenSSL
- configuration file.
- o Added support for ASN.1 indefinite length constructed encoding.
- o New PKCS#12 'medium level' API to manipulate PKCS#12 files.
- o Complete rework of shared library construction and linking
- programs with shared or static libraries, through a separate
- Makefile.shared.
- o Rework of the passing of parameters from one Makefile to another.
- o Changed ENGINE framework to load dynamic engine modules
- automatically from specifically given directories.
- o New structure and ASN.1 functions for CertificatePair.
- o Changed the ZLIB compression method to be stateful.
- o Changed the key-generation and primality testing "progress"
- mechanism to take a structure that contains the ticker
- function and an argument.
- o New engine module: GMP (performs private key exponentiation).
- o New engine module: VIA PadLOck ACE extension in VIA C3
- Nehemiah processors.
- o Added support for IPv6 addresses in certificate extensions.
- See RFC 1884, section 2.2.
- o Added support for certificate policy mappings, policy
- constraints and name constraints.
- o Added support for multi-valued AVAs in the OpenSSL
- configuration file.
- o Added support for multiple certificates with the same subject
- in the 'openssl ca' index file.
- o Make it possible to create self-signed certificates using
- 'openssl ca -selfsign'.
- o Make it possible to generate a serial number file with
- 'openssl ca -create_serial'.
- o New binary search functions with extended functionality.
- o New BUF functions.
- o New STORE structure and library to provide an interface to all
- sorts of data repositories. Supports storage of public and
- private keys, certificates, CRLs, numbers and arbitrary blobs.
- This library is unfortunately unfinished and unused withing
- OpenSSL.
- o New control functions for the error stack.
- o Changed the PKCS#7 library to support one-pass S/MIME
- processing.
- o Added the possibility to compile without old deprecated
- functionality with the OPENSSL_NO_DEPRECATED macro or the
- 'no-deprecated' argument to the config and Configure scripts.
- o Constification of all ASN.1 conversion functions, and other
- affected functions.
- o Improved platform support for PowerPC.
- o New FIPS 180-2 algorithms (SHA-224, -256, -384 and -512).
- o New X509_VERIFY_PARAM structure to support parametrisation
- of X.509 path validation.
- o Major overhaul of RC4 performance on Intel P4, IA-64 and
- AMD64.
- o Changed the Configure script to have some algorithms disabled
- by default. Those can be explicitely enabled with the new
- argument form 'enable-xxx'.
- o Change the default digest in 'openssl' commands from MD5 to
- SHA-1.
- o Added support for DTLS.
- o New BIGNUM blinding.
- o Added support for the RSA-PSS encryption scheme
- o Added support for the RSA X.931 padding.
- o Added support for BSD sockets on NetWare.
- o Added support for files larger than 2GB.
- o Added initial support for Win64.
- o Added alternate pkg-config files.
-
- Major changes between OpenSSL 0.9.7l and OpenSSL 0.9.7m:
-
- o FIPS 1.1.1 module linking.
- o Various ciphersuite selection fixes.
-
- Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l:
-
- o Introduce limits to prevent malicious key DoS (CVE-2006-2940)
- o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343)
-
- Major changes between OpenSSL 0.9.7j and OpenSSL 0.9.7k:
-
- o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339
-
- Major changes between OpenSSL 0.9.7i and OpenSSL 0.9.7j:
-
- o Visual C++ 2005 fixes.
- o Update Windows build system for FIPS.
-
- Major changes between OpenSSL 0.9.7h and OpenSSL 0.9.7i:
-
- o Give EVP_MAX_MD_SIZE it's old value, except for a FIPS build.
-
- Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.7h:
-
- o Fix SSL 2.0 Rollback, CVE-2005-2969
- o Allow use of fixed-length exponent on DSA signing
- o Default fixed-window RSA, DSA, DH private-key operations
-
- Major changes between OpenSSL 0.9.7f and OpenSSL 0.9.7g:
-
- o More compilation issues fixed.
- o Adaptation to more modern Kerberos API.
- o Enhanced or corrected configuration for Solaris64, Mingw and Cygwin.
- o Enhanced x86_64 assembler BIGNUM module.
- o More constification.
- o Added processing of proxy certificates (RFC 3820).
-
- Major changes between OpenSSL 0.9.7e and OpenSSL 0.9.7f:
-
- o Several compilation issues fixed.
- o Many memory allocation failure checks added.
- o Improved comparison of X509 Name type.
- o Mandatory basic checks on certificates.
- o Performance improvements.
-
- Major changes between OpenSSL 0.9.7d and OpenSSL 0.9.7e:
-
- o Fix race condition in CRL checking code.
- o Fixes to PKCS#7 (S/MIME) code.
-
- Major changes between OpenSSL 0.9.7c and OpenSSL 0.9.7d:
-
- o Security: Fix Kerberos ciphersuite SSL/TLS handshaking bug
- o Security: Fix null-pointer assignment in do_change_cipher_spec()
- o Allow multiple active certificates with same subject in CA index
- o Multiple X509 verification fixes
- o Speed up HMAC and other operations
-
- Major changes between OpenSSL 0.9.7b and OpenSSL 0.9.7c:
-
- o Security: fix various ASN1 parsing bugs.
- o New -ignore_err option to OCSP utility.
- o Various interop and bug fixes in S/MIME code.
- o SSL/TLS protocol fix for unrequested client certificates.
-
- Major changes between OpenSSL 0.9.7a and OpenSSL 0.9.7b:
-
- o Security: counter the Klima-Pokorny-Rosa extension of
- Bleichbacher's attack
- o Security: make RSA blinding default.
- o Configuration: Irix fixes, AIX fixes, better mingw support.
- o Support for new platforms: linux-ia64-ecc.
- o Build: shared library support fixes.
- o ASN.1: treat domainComponent correctly.
- o Documentation: fixes and additions.
-
- Major changes between OpenSSL 0.9.7 and OpenSSL 0.9.7a:
-
- o Security: Important security related bugfixes.
- o Enhanced compatibility with MIT Kerberos.
- o Can be built without the ENGINE framework.
- o IA32 assembler enhancements.
- o Support for new platforms: FreeBSD/IA64 and FreeBSD/Sparc64.
- o Configuration: the no-err option now works properly.
- o SSL/TLS: now handles manual certificate chain building.
- o SSL/TLS: certain session ID malfunctions corrected.
-
- Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.7:
-
- o New library section OCSP.
- o Complete rewrite of ASN1 code.
- o CRL checking in verify code and openssl utility.
- o Extension copying in 'ca' utility.
- o Flexible display options in 'ca' utility.
- o Provisional support for international characters with UTF8.
- o Support for external crypto devices ('engine') is no longer
- a separate distribution.
- o New elliptic curve library section.
- o New AES (Rijndael) library section.
- o Support for new platforms: Windows CE, Tandem OSS, A/UX, AIX 64-bit,
- Linux x86_64, Linux 64-bit on Sparc v9
- o Extended support for some platforms: VxWorks
- o Enhanced support for shared libraries.
- o Now only builds PIC code when shared library support is requested.
- o Support for pkg-config.
- o Lots of new manuals.
- o Makes symbolic links to or copies of manuals to cover all described
- functions.
- o Change DES API to clean up the namespace (some applications link also
- against libdes providing similar functions having the same name).
- Provide macros for backward compatibility (will be removed in the
- future).
- o Unify handling of cryptographic algorithms (software and engine)
- to be available via EVP routines for asymmetric and symmetric ciphers.
- o NCONF: new configuration handling routines.
- o Change API to use more 'const' modifiers to improve error checking
- and help optimizers.
- o Finally remove references to RSAref.
- o Reworked parts of the BIGNUM code.
- o Support for new engines: Broadcom ubsec, Accelerated Encryption
- Processing, IBM 4758.
- o A few new engines added in the demos area.
- o Extended and corrected OID (object identifier) table.
- o PRNG: query at more locations for a random device, automatic query for
- EGD style random sources at several locations.
- o SSL/TLS: allow optional cipher choice according to server's preference.
- o SSL/TLS: allow server to explicitly set new session ids.
- o SSL/TLS: support Kerberos cipher suites (RFC2712).
- Only supports MIT Kerberos for now.
- o SSL/TLS: allow more precise control of renegotiations and sessions.
- o SSL/TLS: add callback to retrieve SSL/TLS messages.
- o SSL/TLS: support AES cipher suites (RFC3268).
-
- Major changes between OpenSSL 0.9.6j and OpenSSL 0.9.6k:
-
- o Security: fix various ASN1 parsing bugs.
- o SSL/TLS protocol fix for unrequested client certificates.
-
- Major changes between OpenSSL 0.9.6i and OpenSSL 0.9.6j:
-
- o Security: counter the Klima-Pokorny-Rosa extension of
- Bleichbacher's attack
- o Security: make RSA blinding default.
- o Build: shared library support fixes.
-
- Major changes between OpenSSL 0.9.6h and OpenSSL 0.9.6i:
-
- o Important security related bugfixes.
-
- Major changes between OpenSSL 0.9.6g and OpenSSL 0.9.6h:
-
- o New configuration targets for Tandem OSS and A/UX.
- o New OIDs for Microsoft attributes.
- o Better handling of SSL session caching.
- o Better comparison of distinguished names.
- o Better handling of shared libraries in a mixed GNU/non-GNU environment.
- o Support assembler code with Borland C.
- o Fixes for length problems.
- o Fixes for uninitialised variables.
- o Fixes for memory leaks, some unusual crashes and some race conditions.
- o Fixes for smaller building problems.
- o Updates of manuals, FAQ and other instructive documents.
-
- Major changes between OpenSSL 0.9.6f and OpenSSL 0.9.6g:
-
- o Important building fixes on Unix.
-
- Major changes between OpenSSL 0.9.6e and OpenSSL 0.9.6f:
-
- o Various important bugfixes.
-
- Major changes between OpenSSL 0.9.6d and OpenSSL 0.9.6e:
-
- o Important security related bugfixes.
- o Various SSL/TLS library bugfixes.
-
- Major changes between OpenSSL 0.9.6c and OpenSSL 0.9.6d:
-
- o Various SSL/TLS library bugfixes.
- o Fix DH parameter generation for 'non-standard' generators.
-
- Major changes between OpenSSL 0.9.6b and OpenSSL 0.9.6c:
-
- o Various SSL/TLS library bugfixes.
- o BIGNUM library fixes.
- o RSA OAEP and random number generation fixes.
- o Object identifiers corrected and added.
- o Add assembler BN routines for IA64.
- o Add support for OS/390 Unix, UnixWare with gcc, OpenUNIX 8,
- MIPS Linux; shared library support for Irix, HP-UX.
- o Add crypto accelerator support for AEP, Baltimore SureWare,
- Broadcom and Cryptographic Appliance's keyserver
- [in 0.9.6c-engine release].
-
- Major changes between OpenSSL 0.9.6a and OpenSSL 0.9.6b:
-
- o Security fix: PRNG improvements.
- o Security fix: RSA OAEP check.
- o Security fix: Reinsert and fix countermeasure to Bleichbacher's
- attack.
- o MIPS bug fix in BIGNUM.
- o Bug fix in "openssl enc".
- o Bug fix in X.509 printing routine.
- o Bug fix in DSA verification routine and DSA S/MIME verification.
- o Bug fix to make PRNG thread-safe.
- o Bug fix in RAND_file_name().
- o Bug fix in compatibility mode trust settings.
- o Bug fix in blowfish EVP.
- o Increase default size for BIO buffering filter.
- o Compatibility fixes in some scripts.
-
- Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.6a:
-
- o Security fix: change behavior of OpenSSL to avoid using
- environment variables when running as root.
- o Security fix: check the result of RSA-CRT to reduce the
- possibility of deducing the private key from an incorrectly
- calculated signature.
- o Security fix: prevent Bleichenbacher's DSA attack.
- o Security fix: Zero the premaster secret after deriving the
- master secret in DH ciphersuites.
- o Reimplement SSL_peek(), which had various problems.
- o Compatibility fix: the function des_encrypt() renamed to
- des_encrypt1() to avoid clashes with some Unixen libc.
- o Bug fixes for Win32, HP/UX and Irix.
- o Bug fixes in BIGNUM, SSL, PKCS#7, PKCS#12, X.509, CONF and
- memory checking routines.
- o Bug fixes for RSA operations in threaded environments.
- o Bug fixes in misc. openssl applications.
- o Remove a few potential memory leaks.
- o Add tighter checks of BIGNUM routines.
- o Shared library support has been reworked for generality.
- o More documentation.
- o New function BN_rand_range().
- o Add "-rand" option to openssl s_client and s_server.
-
- Major changes between OpenSSL 0.9.5a and OpenSSL 0.9.6:
-
- o Some documentation for BIO and SSL libraries.
- o Enhanced chain verification using key identifiers.
- o New sign and verify options to 'dgst' application.
- o Support for DER and PEM encoded messages in 'smime' application.
- o New 'rsautl' application, low level RSA utility.
- o MD4 now included.
- o Bugfix for SSL rollback padding check.
- o Support for external crypto devices [1].
- o Enhanced EVP interface.
-
- [1] The support for external crypto devices is currently a separate
- distribution. See the file README.ENGINE.
-
- Major changes between OpenSSL 0.9.5 and OpenSSL 0.9.5a:
-
- o Bug fixes for Win32, SuSE Linux, NeXTSTEP and FreeBSD 2.2.8
- o Shared library support for HPUX and Solaris-gcc
- o Support of Linux/IA64
- o Assembler support for Mingw32
- o New 'rand' application
- o New way to check for existence of algorithms from scripts
-
- Major changes between OpenSSL 0.9.4 and OpenSSL 0.9.5:
-
- o S/MIME support in new 'smime' command
- o Documentation for the OpenSSL command line application
- o Automation of 'req' application
- o Fixes to make s_client, s_server work under Windows
- o Support for multiple fieldnames in SPKACs
- o New SPKAC command line utilty and associated library functions
- o Options to allow passwords to be obtained from various sources
- o New public key PEM format and options to handle it
- o Many other fixes and enhancements to command line utilities
- o Usable certificate chain verification
- o Certificate purpose checking
- o Certificate trust settings
- o Support of authority information access extension
- o Extensions in certificate requests
- o Simplified X509 name and attribute routines
- o Initial (incomplete) support for international character sets
- o New DH_METHOD, DSA_METHOD and enhanced RSA_METHOD
- o Read only memory BIOs and simplified creation function
- o TLS/SSL protocol bugfixes: Accept TLS 'client hello' in SSL 3.0
- record; allow fragmentation and interleaving of handshake and other
- data
- o TLS/SSL code now "tolerates" MS SGC
- o Work around for Netscape client certificate hang bug
- o RSA_NULL option that removes RSA patent code but keeps other
- RSA functionality
- o Memory leak detection now allows applications to add extra information
- via a per-thread stack
- o PRNG robustness improved
- o EGD support
- o BIGNUM library bug fixes
- o Faster DSA parameter generation
- o Enhanced support for Alpha Linux
- o Experimental MacOS support
-
- Major changes between OpenSSL 0.9.3 and OpenSSL 0.9.4:
-
- o Transparent support for PKCS#8 format private keys: these are used
- by several software packages and are more secure than the standard
- form
- o PKCS#5 v2.0 implementation
- o Password callbacks have a new void * argument for application data
- o Avoid various memory leaks
- o New pipe-like BIO that allows using the SSL library when actual I/O
- must be handled by the application (BIO pair)
-
- Major changes between OpenSSL 0.9.2b and OpenSSL 0.9.3:
- o Lots of enhancements and cleanups to the Configuration mechanism
- o RSA OEAP related fixes
- o Added `openssl ca -revoke' option for revoking a certificate
- o Source cleanups: const correctness, type-safe stacks and ASN.1 SETs
- o Source tree cleanups: removed lots of obsolete files
- o Thawte SXNet, certificate policies and CRL distribution points
- extension support
- o Preliminary (experimental) S/MIME support
- o Support for ASN.1 UTF8String and VisibleString
- o Full integration of PKCS#12 code
- o Sparc assembler bignum implementation, optimized hash functions
- o Option to disable selected ciphers
-
- Major changes between OpenSSL 0.9.1c and OpenSSL 0.9.2b:
- o Fixed a security hole related to session resumption
- o Fixed RSA encryption routines for the p < q case
- o "ALL" in cipher lists now means "everything except NULL ciphers"
- o Support for Triple-DES CBCM cipher
- o Support of Optimal Asymmetric Encryption Padding (OAEP) for RSA
- o First support for new TLSv1 ciphers
- o Added a few new BIOs (syslog BIO, reliable BIO)
- o Extended support for DSA certificate/keys.
- o Extended support for Certificate Signing Requests (CSR)
- o Initial support for X.509v3 extensions
- o Extended support for compression inside the SSL record layer
- o Overhauled Win32 builds
- o Cleanups and fixes to the Big Number (BN) library
- o Support for ASN.1 GeneralizedTime
- o Splitted ASN.1 SETs from SEQUENCEs
- o ASN1 and PEM support for Netscape Certificate Sequences
- o Overhauled Perl interface
- o Lots of source tree cleanups.
- o Lots of memory leak fixes.
- o Lots of bug fixes.
-
- Major changes between SSLeay 0.9.0b and OpenSSL 0.9.1c:
- o Integration of the popular NO_RSA/NO_DSA patches
- o Initial support for compression inside the SSL record layer
- o Added BIO proxy and filtering functionality
- o Extended Big Number (BN) library
- o Added RIPE MD160 message digest
- o Addeed support for RC2/64bit cipher
- o Extended ASN.1 parser routines
- o Adjustations of the source tree for CVS
- o Support for various new platforms
-
+
+ NEWS
+ ====
+
+ This file gives a brief overview of the major changes between each OpenSSL
+ release. For more details please read the CHANGES file.
+
+ Major changes between OpenSSL 1.0.0c and OpenSSL 1.0.0d:
+
+ o Fix for security issue CVE-2011-0014
+
+ Major changes between OpenSSL 1.0.0b and OpenSSL 1.0.0c:
+
+ o Fix for security issue CVE-2010-4180
+ o Fix for CVE-2010-4252
+ o Fix mishandling of absent EC point format extension.
+ o Fix various platform compilation issues.
+ o Corrected fix for security issue CVE-2010-3864.
+
+ Major changes between OpenSSL 1.0.0a and OpenSSL 1.0.0b:
+
+ o Fix for security issue CVE-2010-3864.
+ o Fix for CVE-2010-2939
+ o Fix WIN32 build system for GOST ENGINE.
+
+ Major changes between OpenSSL 1.0.0 and OpenSSL 1.0.0a:
+
+ o Fix for security issue CVE-2010-1633.
+ o GOST MAC and CFB fixes.
+
+ Major changes between OpenSSL 0.9.8n and OpenSSL 1.0.0:
+
+ o RFC3280 path validation: sufficient to process PKITS tests.
+ o Integrated support for PVK files and keyblobs.
+ o Change default private key format to PKCS#8.
+ o CMS support: able to process all examples in RFC4134
+ o Streaming ASN1 encode support for PKCS#7 and CMS.
+ o Multiple signer and signer add support for PKCS#7 and CMS.
+ o ASN1 printing support.
+ o Whirlpool hash algorithm added.
+ o RFC3161 time stamp support.
+ o New generalised public key API supporting ENGINE based algorithms.
+ o New generalised public key API utilities.
+ o New ENGINE supporting GOST algorithms.
+ o SSL/TLS GOST ciphersuite support.
+ o PKCS#7 and CMS GOST support.
+ o RFC4279 PSK ciphersuite support.
+ o Supported points format extension for ECC ciphersuites.
+ o ecdsa-with-SHA224/256/384/512 signature types.
+ o dsa-with-SHA224 and dsa-with-SHA256 signature types.
+ o Opaque PRF Input TLS extension support.
+ o Updated time routines to avoid OS limitations.
+
+ Major changes between OpenSSL 0.9.8q and OpenSSL 0.9.8r:
+
+ o Fix for security issue CVE-2011-0014
+
+ Major changes between OpenSSL 0.9.8p and OpenSSL 0.9.8q:
+
+ o Fix for security issue CVE-2010-4180
+ o Fix for CVE-2010-4252
+
+ Major changes between OpenSSL 0.9.8o and OpenSSL 0.9.8p:
+
+ o Fix for security issue CVE-2010-3864.
+
+ Major changes between OpenSSL 0.9.8n and OpenSSL 0.9.8o:
+
+ o Fix for security issue CVE-2010-0742.
+ o Various DTLS fixes.
+ o Recognise SHA2 certificates if only SSL algorithms added.
+ o Fix for no-rc4 compilation.
+ o Chil ENGINE unload workaround.
+
+ Major changes between OpenSSL 0.9.8m and OpenSSL 0.9.8n:
+
+ o CFB cipher definition fixes.
+ o Fix security issues CVE-2010-0740 and CVE-2010-0433.
+
+ Major changes between OpenSSL 0.9.8l and OpenSSL 0.9.8m:
+
+ o Cipher definition fixes.
+ o Workaround for slow RAND_poll() on some WIN32 versions.
+ o Remove MD2 from algorithm tables.
+ o SPKAC handling fixes.
+ o Support for RFC5746 TLS renegotiation extension.
+ o Compression memory leak fixed.
+ o Compression session resumption fixed.
+ o Ticket and SNI coexistence fixes.
+ o Many fixes to DTLS handling.
+
+ Major changes between OpenSSL 0.9.8k and OpenSSL 0.9.8l:
+
+ o Temporary work around for CVE-2009-3555: disable renegotiation.
+
+ Major changes between OpenSSL 0.9.8j and OpenSSL 0.9.8k:
+
+ o Fix various build issues.
+ o Fix security issues (CVE-2009-0590, CVE-2009-0591, CVE-2009-0789)
+
+ Major changes between OpenSSL 0.9.8i and OpenSSL 0.9.8j:
+
+ o Fix security issue (CVE-2008-5077)
+ o Merge FIPS 140-2 branch code.
+
+ Major changes between OpenSSL 0.9.8g and OpenSSL 0.9.8h:
+
+ o CryptoAPI ENGINE support.
+ o Various precautionary measures.
+ o Fix for bugs affecting certificate request creation.
+ o Support for local machine keyset attribute in PKCS#12 files.
+
+ Major changes between OpenSSL 0.9.8f and OpenSSL 0.9.8g:
+
+ o Backport of CMS functionality to 0.9.8.
+ o Fixes for bugs introduced with 0.9.8f.
+
+ Major changes between OpenSSL 0.9.8e and OpenSSL 0.9.8f:
+
+ o Add gcc 4.2 support.
+ o Add support for AES and SSE2 assembly lanugauge optimization
+ for VC++ build.
+ o Support for RFC4507bis and server name extensions if explicitly
+ selected at compile time.
+ o DTLS improvements.
+ o RFC4507bis support.
+ o TLS Extensions support.
+
+ Major changes between OpenSSL 0.9.8d and OpenSSL 0.9.8e:
+
+ o Various ciphersuite selection fixes.
+ o RFC3779 support.
+
+ Major changes between OpenSSL 0.9.8c and OpenSSL 0.9.8d:
+
+ o Introduce limits to prevent malicious key DoS (CVE-2006-2940)
+ o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343)
+ o Changes to ciphersuite selection algorithm
+
+ Major changes between OpenSSL 0.9.8b and OpenSSL 0.9.8c:
+
+ o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339
+ o New cipher Camellia
+
+ Major changes between OpenSSL 0.9.8a and OpenSSL 0.9.8b:
+
+ o Cipher string fixes.
+ o Fixes for VC++ 2005.
+ o Updated ECC cipher suite support.
+ o New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free().
+ o Zlib compression usage fixes.
+ o Built in dynamic engine compilation support on Win32.
+ o Fixes auto dynamic engine loading in Win32.
+
+ Major changes between OpenSSL 0.9.8 and OpenSSL 0.9.8a:
+
+ o Fix potential SSL 2.0 rollback, CVE-2005-2969
+ o Extended Windows CE support
+
+ Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.8:
+
+ o Major work on the BIGNUM library for higher efficiency and to
+ make operations more streamlined and less contradictory. This
+ is the result of a major audit of the BIGNUM library.
+ o Addition of BIGNUM functions for fields GF(2^m) and NIST
+ curves, to support the Elliptic Crypto functions.
+ o Major work on Elliptic Crypto; ECDH and ECDSA added, including
+ the use through EVP, X509 and ENGINE.
+ o New ASN.1 mini-compiler that's usable through the OpenSSL
+ configuration file.
+ o Added support for ASN.1 indefinite length constructed encoding.
+ o New PKCS#12 'medium level' API to manipulate PKCS#12 files.
+ o Complete rework of shared library construction and linking
+ programs with shared or static libraries, through a separate
+ Makefile.shared.
+ o Rework of the passing of parameters from one Makefile to another.
+ o Changed ENGINE framework to load dynamic engine modules
+ automatically from specifically given directories.
+ o New structure and ASN.1 functions for CertificatePair.
+ o Changed the ZLIB compression method to be stateful.
+ o Changed the key-generation and primality testing "progress"
+ mechanism to take a structure that contains the ticker
+ function and an argument.
+ o New engine module: GMP (performs private key exponentiation).
+ o New engine module: VIA PadLOck ACE extension in VIA C3
+ Nehemiah processors.
+ o Added support for IPv6 addresses in certificate extensions.
+ See RFC 1884, section 2.2.
+ o Added support for certificate policy mappings, policy
+ constraints and name constraints.
+ o Added support for multi-valued AVAs in the OpenSSL
+ configuration file.
+ o Added support for multiple certificates with the same subject
+ in the 'openssl ca' index file.
+ o Make it possible to create self-signed certificates using
+ 'openssl ca -selfsign'.
+ o Make it possible to generate a serial number file with
+ 'openssl ca -create_serial'.
+ o New binary search functions with extended functionality.
+ o New BUF functions.
+ o New STORE structure and library to provide an interface to all
+ sorts of data repositories. Supports storage of public and
+ private keys, certificates, CRLs, numbers and arbitrary blobs.
+ This library is unfortunately unfinished and unused withing
+ OpenSSL.
+ o New control functions for the error stack.
+ o Changed the PKCS#7 library to support one-pass S/MIME
+ processing.
+ o Added the possibility to compile without old deprecated
+ functionality with the OPENSSL_NO_DEPRECATED macro or the
+ 'no-deprecated' argument to the config and Configure scripts.
+ o Constification of all ASN.1 conversion functions, and other
+ affected functions.
+ o Improved platform support for PowerPC.
+ o New FIPS 180-2 algorithms (SHA-224, -256, -384 and -512).
+ o New X509_VERIFY_PARAM structure to support parametrisation
+ of X.509 path validation.
+ o Major overhaul of RC4 performance on Intel P4, IA-64 and
+ AMD64.
+ o Changed the Configure script to have some algorithms disabled
+ by default. Those can be explicitely enabled with the new
+ argument form 'enable-xxx'.
+ o Change the default digest in 'openssl' commands from MD5 to
+ SHA-1.
+ o Added support for DTLS.
+ o New BIGNUM blinding.
+ o Added support for the RSA-PSS encryption scheme
+ o Added support for the RSA X.931 padding.
+ o Added support for BSD sockets on NetWare.
+ o Added support for files larger than 2GB.
+ o Added initial support for Win64.
+ o Added alternate pkg-config files.
+
+ Major changes between OpenSSL 0.9.7l and OpenSSL 0.9.7m:
+
+ o FIPS 1.1.1 module linking.
+ o Various ciphersuite selection fixes.
+
+ Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l:
+
+ o Introduce limits to prevent malicious key DoS (CVE-2006-2940)
+ o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343)
+
+ Major changes between OpenSSL 0.9.7j and OpenSSL 0.9.7k:
+
+ o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339
+
+ Major changes between OpenSSL 0.9.7i and OpenSSL 0.9.7j:
+
+ o Visual C++ 2005 fixes.
+ o Update Windows build system for FIPS.
+
+ Major changes between OpenSSL 0.9.7h and OpenSSL 0.9.7i:
+
+ o Give EVP_MAX_MD_SIZE it's old value, except for a FIPS build.
+
+ Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.7h:
+
+ o Fix SSL 2.0 Rollback, CVE-2005-2969
+ o Allow use of fixed-length exponent on DSA signing
+ o Default fixed-window RSA, DSA, DH private-key operations
+
+ Major changes between OpenSSL 0.9.7f and OpenSSL 0.9.7g:
+
+ o More compilation issues fixed.
+ o Adaptation to more modern Kerberos API.
+ o Enhanced or corrected configuration for Solaris64, Mingw and Cygwin.
+ o Enhanced x86_64 assembler BIGNUM module.
+ o More constification.
+ o Added processing of proxy certificates (RFC 3820).
+
+ Major changes between OpenSSL 0.9.7e and OpenSSL 0.9.7f:
+
+ o Several compilation issues fixed.
+ o Many memory allocation failure checks added.
+ o Improved comparison of X509 Name type.
+ o Mandatory basic checks on certificates.
+ o Performance improvements.
+
+ Major changes between OpenSSL 0.9.7d and OpenSSL 0.9.7e:
+
+ o Fix race condition in CRL checking code.
+ o Fixes to PKCS#7 (S/MIME) code.
+
+ Major changes between OpenSSL 0.9.7c and OpenSSL 0.9.7d:
+
+ o Security: Fix Kerberos ciphersuite SSL/TLS handshaking bug
+ o Security: Fix null-pointer assignment in do_change_cipher_spec()
+ o Allow multiple active certificates with same subject in CA index
+ o Multiple X509 verification fixes
+ o Speed up HMAC and other operations
+
+ Major changes between OpenSSL 0.9.7b and OpenSSL 0.9.7c:
+
+ o Security: fix various ASN1 parsing bugs.
+ o New -ignore_err option to OCSP utility.
+ o Various interop and bug fixes in S/MIME code.
+ o SSL/TLS protocol fix for unrequested client certificates.
+
+ Major changes between OpenSSL 0.9.7a and OpenSSL 0.9.7b:
+
+ o Security: counter the Klima-Pokorny-Rosa extension of
+ Bleichbacher's attack
+ o Security: make RSA blinding default.
+ o Configuration: Irix fixes, AIX fixes, better mingw support.
+ o Support for new platforms: linux-ia64-ecc.
+ o Build: shared library support fixes.
+ o ASN.1: treat domainComponent correctly.
+ o Documentation: fixes and additions.
+
+ Major changes between OpenSSL 0.9.7 and OpenSSL 0.9.7a:
+
+ o Security: Important security related bugfixes.
+ o Enhanced compatibility with MIT Kerberos.
+ o Can be built without the ENGINE framework.
+ o IA32 assembler enhancements.
+ o Support for new platforms: FreeBSD/IA64 and FreeBSD/Sparc64.
+ o Configuration: the no-err option now works properly.
+ o SSL/TLS: now handles manual certificate chain building.
+ o SSL/TLS: certain session ID malfunctions corrected.
+
+ Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.7:
+
+ o New library section OCSP.
+ o Complete rewrite of ASN1 code.
+ o CRL checking in verify code and openssl utility.
+ o Extension copying in 'ca' utility.
+ o Flexible display options in 'ca' utility.
+ o Provisional support for international characters with UTF8.
+ o Support for external crypto devices ('engine') is no longer
+ a separate distribution.
+ o New elliptic curve library section.
+ o New AES (Rijndael) library section.
+ o Support for new platforms: Windows CE, Tandem OSS, A/UX, AIX 64-bit,
+ Linux x86_64, Linux 64-bit on Sparc v9
+ o Extended support for some platforms: VxWorks
+ o Enhanced support for shared libraries.
+ o Now only builds PIC code when shared library support is requested.
+ o Support for pkg-config.
+ o Lots of new manuals.
+ o Makes symbolic links to or copies of manuals to cover all described
+ functions.
+ o Change DES API to clean up the namespace (some applications link also
+ against libdes providing similar functions having the same name).
+ Provide macros for backward compatibility (will be removed in the
+ future).
+ o Unify handling of cryptographic algorithms (software and engine)
+ to be available via EVP routines for asymmetric and symmetric ciphers.
+ o NCONF: new configuration handling routines.
+ o Change API to use more 'const' modifiers to improve error checking
+ and help optimizers.
+ o Finally remove references to RSAref.
+ o Reworked parts of the BIGNUM code.
+ o Support for new engines: Broadcom ubsec, Accelerated Encryption
+ Processing, IBM 4758.
+ o A few new engines added in the demos area.
+ o Extended and corrected OID (object identifier) table.
+ o PRNG: query at more locations for a random device, automatic query for
+ EGD style random sources at several locations.
+ o SSL/TLS: allow optional cipher choice according to server's preference.
+ o SSL/TLS: allow server to explicitly set new session ids.
+ o SSL/TLS: support Kerberos cipher suites (RFC2712).
+ Only supports MIT Kerberos for now.
+ o SSL/TLS: allow more precise control of renegotiations and sessions.
+ o SSL/TLS: add callback to retrieve SSL/TLS messages.
+ o SSL/TLS: support AES cipher suites (RFC3268).
+
+ Major changes between OpenSSL 0.9.6j and OpenSSL 0.9.6k:
+
+ o Security: fix various ASN1 parsing bugs.
+ o SSL/TLS protocol fix for unrequested client certificates.
+
+ Major changes between OpenSSL 0.9.6i and OpenSSL 0.9.6j:
+
+ o Security: counter the Klima-Pokorny-Rosa extension of
+ Bleichbacher's attack
+ o Security: make RSA blinding default.
+ o Build: shared library support fixes.
+
+ Major changes between OpenSSL 0.9.6h and OpenSSL 0.9.6i:
+
+ o Important security related bugfixes.
+
+ Major changes between OpenSSL 0.9.6g and OpenSSL 0.9.6h:
+
+ o New configuration targets for Tandem OSS and A/UX.
+ o New OIDs for Microsoft attributes.
+ o Better handling of SSL session caching.
+ o Better comparison of distinguished names.
+ o Better handling of shared libraries in a mixed GNU/non-GNU environment.
+ o Support assembler code with Borland C.
+ o Fixes for length problems.
+ o Fixes for uninitialised variables.
+ o Fixes for memory leaks, some unusual crashes and some race conditions.
+ o Fixes for smaller building problems.
+ o Updates of manuals, FAQ and other instructive documents.
+
+ Major changes between OpenSSL 0.9.6f and OpenSSL 0.9.6g:
+
+ o Important building fixes on Unix.
+
+ Major changes between OpenSSL 0.9.6e and OpenSSL 0.9.6f:
+
+ o Various important bugfixes.
+
+ Major changes between OpenSSL 0.9.6d and OpenSSL 0.9.6e:
+
+ o Important security related bugfixes.
+ o Various SSL/TLS library bugfixes.
+
+ Major changes between OpenSSL 0.9.6c and OpenSSL 0.9.6d:
+
+ o Various SSL/TLS library bugfixes.
+ o Fix DH parameter generation for 'non-standard' generators.
+
+ Major changes between OpenSSL 0.9.6b and OpenSSL 0.9.6c:
+
+ o Various SSL/TLS library bugfixes.
+ o BIGNUM library fixes.
+ o RSA OAEP and random number generation fixes.
+ o Object identifiers corrected and added.
+ o Add assembler BN routines for IA64.
+ o Add support for OS/390 Unix, UnixWare with gcc, OpenUNIX 8,
+ MIPS Linux; shared library support for Irix, HP-UX.
+ o Add crypto accelerator support for AEP, Baltimore SureWare,
+ Broadcom and Cryptographic Appliance's keyserver
+ [in 0.9.6c-engine release].
+
+ Major changes between OpenSSL 0.9.6a and OpenSSL 0.9.6b:
+
+ o Security fix: PRNG improvements.
+ o Security fix: RSA OAEP check.
+ o Security fix: Reinsert and fix countermeasure to Bleichbacher's
+ attack.
+ o MIPS bug fix in BIGNUM.
+ o Bug fix in "openssl enc".
+ o Bug fix in X.509 printing routine.
+ o Bug fix in DSA verification routine and DSA S/MIME verification.
+ o Bug fix to make PRNG thread-safe.
+ o Bug fix in RAND_file_name().
+ o Bug fix in compatibility mode trust settings.
+ o Bug fix in blowfish EVP.
+ o Increase default size for BIO buffering filter.
+ o Compatibility fixes in some scripts.
+
+ Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.6a:
+
+ o Security fix: change behavior of OpenSSL to avoid using
+ environment variables when running as root.
+ o Security fix: check the result of RSA-CRT to reduce the
+ possibility of deducing the private key from an incorrectly
+ calculated signature.
+ o Security fix: prevent Bleichenbacher's DSA attack.
+ o Security fix: Zero the premaster secret after deriving the
+ master secret in DH ciphersuites.
+ o Reimplement SSL_peek(), which had various problems.
+ o Compatibility fix: the function des_encrypt() renamed to
+ des_encrypt1() to avoid clashes with some Unixen libc.
+ o Bug fixes for Win32, HP/UX and Irix.
+ o Bug fixes in BIGNUM, SSL, PKCS#7, PKCS#12, X.509, CONF and
+ memory checking routines.
+ o Bug fixes for RSA operations in threaded environments.
+ o Bug fixes in misc. openssl applications.
+ o Remove a few potential memory leaks.
+ o Add tighter checks of BIGNUM routines.
+ o Shared library support has been reworked for generality.
+ o More documentation.
+ o New function BN_rand_range().
+ o Add "-rand" option to openssl s_client and s_server.
+
+ Major changes between OpenSSL 0.9.5a and OpenSSL 0.9.6:
+
+ o Some documentation for BIO and SSL libraries.
+ o Enhanced chain verification using key identifiers.
+ o New sign and verify options to 'dgst' application.
+ o Support for DER and PEM encoded messages in 'smime' application.
+ o New 'rsautl' application, low level RSA utility.
+ o MD4 now included.
+ o Bugfix for SSL rollback padding check.
+ o Support for external crypto devices [1].
+ o Enhanced EVP interface.
+
+ [1] The support for external crypto devices is currently a separate
+ distribution. See the file README.ENGINE.
+
+ Major changes between OpenSSL 0.9.5 and OpenSSL 0.9.5a:
+
+ o Bug fixes for Win32, SuSE Linux, NeXTSTEP and FreeBSD 2.2.8
+ o Shared library support for HPUX and Solaris-gcc
+ o Support of Linux/IA64
+ o Assembler support for Mingw32
+ o New 'rand' application
+ o New way to check for existence of algorithms from scripts
+
+ Major changes between OpenSSL 0.9.4 and OpenSSL 0.9.5:
+
+ o S/MIME support in new 'smime' command
+ o Documentation for the OpenSSL command line application
+ o Automation of 'req' application
+ o Fixes to make s_client, s_server work under Windows
+ o Support for multiple fieldnames in SPKACs
+ o New SPKAC command line utilty and associated library functions
+ o Options to allow passwords to be obtained from various sources
+ o New public key PEM format and options to handle it
+ o Many other fixes and enhancements to command line utilities
+ o Usable certificate chain verification
+ o Certificate purpose checking
+ o Certificate trust settings
+ o Support of authority information access extension
+ o Extensions in certificate requests
+ o Simplified X509 name and attribute routines
+ o Initial (incomplete) support for international character sets
+ o New DH_METHOD, DSA_METHOD and enhanced RSA_METHOD
+ o Read only memory BIOs and simplified creation function
+ o TLS/SSL protocol bugfixes: Accept TLS 'client hello' in SSL 3.0
+ record; allow fragmentation and interleaving of handshake and other
+ data
+ o TLS/SSL code now "tolerates" MS SGC
+ o Work around for Netscape client certificate hang bug
+ o RSA_NULL option that removes RSA patent code but keeps other
+ RSA functionality
+ o Memory leak detection now allows applications to add extra information
+ via a per-thread stack
+ o PRNG robustness improved
+ o EGD support
+ o BIGNUM library bug fixes
+ o Faster DSA parameter generation
+ o Enhanced support for Alpha Linux
+ o Experimental MacOS support
+
+ Major changes between OpenSSL 0.9.3 and OpenSSL 0.9.4:
+
+ o Transparent support for PKCS#8 format private keys: these are used
+ by several software packages and are more secure than the standard
+ form
+ o PKCS#5 v2.0 implementation
+ o Password callbacks have a new void * argument for application data
+ o Avoid various memory leaks
+ o New pipe-like BIO that allows using the SSL library when actual I/O
+ must be handled by the application (BIO pair)
+
+ Major changes between OpenSSL 0.9.2b and OpenSSL 0.9.3:
+ o Lots of enhancements and cleanups to the Configuration mechanism
+ o RSA OEAP related fixes
+ o Added `openssl ca -revoke' option for revoking a certificate
+ o Source cleanups: const correctness, type-safe stacks and ASN.1 SETs
+ o Source tree cleanups: removed lots of obsolete files
+ o Thawte SXNet, certificate policies and CRL distribution points
+ extension support
+ o Preliminary (experimental) S/MIME support
+ o Support for ASN.1 UTF8String and VisibleString
+ o Full integration of PKCS#12 code
+ o Sparc assembler bignum implementation, optimized hash functions
+ o Option to disable selected ciphers
+
+ Major changes between OpenSSL 0.9.1c and OpenSSL 0.9.2b:
+ o Fixed a security hole related to session resumption
+ o Fixed RSA encryption routines for the p < q case
+ o "ALL" in cipher lists now means "everything except NULL ciphers"
+ o Support for Triple-DES CBCM cipher
+ o Support of Optimal Asymmetric Encryption Padding (OAEP) for RSA
+ o First support for new TLSv1 ciphers
+ o Added a few new BIOs (syslog BIO, reliable BIO)
+ o Extended support for DSA certificate/keys.
+ o Extended support for Certificate Signing Requests (CSR)
+ o Initial support for X.509v3 extensions
+ o Extended support for compression inside the SSL record layer
+ o Overhauled Win32 builds
+ o Cleanups and fixes to the Big Number (BN) library
+ o Support for ASN.1 GeneralizedTime
+ o Splitted ASN.1 SETs from SEQUENCEs
+ o ASN1 and PEM support for Netscape Certificate Sequences
+ o Overhauled Perl interface
+ o Lots of source tree cleanups.
+ o Lots of memory leak fixes.
+ o Lots of bug fixes.
+
+ Major changes between SSLeay 0.9.0b and OpenSSL 0.9.1c:
+ o Integration of the popular NO_RSA/NO_DSA patches
+ o Initial support for compression inside the SSL record layer
+ o Added BIO proxy and filtering functionality
+ o Extended Big Number (BN) library
+ o Added RIPE MD160 message digest
+ o Addeed support for RC2/64bit cipher
+ o Extended ASN.1 parser routines
+ o Adjustations of the source tree for CVS
+ o Support for various new platforms
+
diff --git a/openssl/README b/openssl/README
index 7809cb3c4..e3858eab8 100644
--- a/openssl/README
+++ b/openssl/README
@@ -1,218 +1,218 @@
-
- OpenSSL 1.0.0d
-
- Copyright (c) 1998-2011 The OpenSSL Project
- Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
- All rights reserved.
-
- DESCRIPTION
- -----------
-
- The OpenSSL Project is a collaborative effort to develop a robust,
- commercial-grade, fully featured, and Open Source toolkit implementing the
- Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
- protocols as well as a full-strength general purpose cryptography library.
- The project is managed by a worldwide community of volunteers that use the
- Internet to communicate, plan, and develop the OpenSSL toolkit and its
- related documentation.
-
- OpenSSL is based on the excellent SSLeay library developed from Eric A. Young
- and Tim J. Hudson. The OpenSSL toolkit is licensed under a dual-license (the
- OpenSSL license plus the SSLeay license) situation, which basically means
- that you are free to get and use it for commercial and non-commercial
- purposes as long as you fulfill the conditions of both licenses.
-
- OVERVIEW
- --------
-
- The OpenSSL toolkit includes:
-
- libssl.a:
- Implementation of SSLv2, SSLv3, TLSv1 and the required code to support
- both SSLv2, SSLv3 and TLSv1 in the one server and client.
-
- libcrypto.a:
- General encryption and X.509 v1/v3 stuff needed by SSL/TLS but not
- actually logically part of it. It includes routines for the following:
-
- Ciphers
- libdes - EAY's libdes DES encryption package which was floating
- around the net for a few years, and was then relicensed by
- him as part of SSLeay. It includes 15 'modes/variations'
- of DES (1, 2 and 3 key versions of ecb, cbc, cfb and ofb;
- pcbc and a more general form of cfb and ofb) including desx
- in cbc mode, a fast crypt(3), and routines to read
- passwords from the keyboard.
- RC4 encryption,
- RC2 encryption - 4 different modes, ecb, cbc, cfb and ofb.
- Blowfish encryption - 4 different modes, ecb, cbc, cfb and ofb.
- IDEA encryption - 4 different modes, ecb, cbc, cfb and ofb.
-
- Digests
- MD5 and MD2 message digest algorithms, fast implementations,
- SHA (SHA-0) and SHA-1 message digest algorithms,
- MDC2 message digest. A DES based hash that is popular on smart cards.
-
- Public Key
- RSA encryption/decryption/generation.
- There is no limit on the number of bits.
- DSA encryption/decryption/generation.
- There is no limit on the number of bits.
- Diffie-Hellman key-exchange/key generation.
- There is no limit on the number of bits.
-
- X.509v3 certificates
- X509 encoding/decoding into/from binary ASN1 and a PEM
- based ASCII-binary encoding which supports encryption with a
- private key. Program to generate RSA and DSA certificate
- requests and to generate RSA and DSA certificates.
-
- Systems
- The normal digital envelope routines and base64 encoding. Higher
- level access to ciphers and digests by name. New ciphers can be
- loaded at run time. The BIO io system which is a simple non-blocking
- IO abstraction. Current methods supported are file descriptors,
- sockets, socket accept, socket connect, memory buffer, buffering, SSL
- client/server, file pointer, encryption, digest, non-blocking testing
- and null.
-
- Data structures
- A dynamically growing hashing system
- A simple stack.
- A Configuration loader that uses a format similar to MS .ini files.
-
- openssl:
- A command line tool that can be used for:
- Creation of RSA, DH and DSA key parameters
- Creation of X.509 certificates, CSRs and CRLs
- Calculation of Message Digests
- Encryption and Decryption with Ciphers
- SSL/TLS Client and Server Tests
- Handling of S/MIME signed or encrypted mail
-
-
- PATENTS
- -------
-
- Various companies hold various patents for various algorithms in various
- locations around the world. _YOU_ are responsible for ensuring that your use
- of any algorithms is legal by checking if there are any patents in your
- country. The file contains some of the patents that we know about or are
- rumored to exist. This is not a definitive list.
-
- RSA Security holds software patents on the RC5 algorithm. If you
- intend to use this cipher, you must contact RSA Security for
- licensing conditions. Their web page is http://www.rsasecurity.com/.
-
- RC4 is a trademark of RSA Security, so use of this label should perhaps
- only be used with RSA Security's permission.
-
- The IDEA algorithm is patented by Ascom in Austria, France, Germany, Italy,
- Japan, the Netherlands, Spain, Sweden, Switzerland, UK and the USA. They
- should be contacted if that algorithm is to be used; their web page is
- http://www.ascom.ch/.
-
- NTT and Mitsubishi have patents and pending patents on the Camellia
- algorithm, but allow use at no charge without requiring an explicit
- licensing agreement: http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
-
- INSTALLATION
- ------------
-
- To install this package under a Unix derivative, read the INSTALL file. For
- a Win32 platform, read the INSTALL.W32 file. For OpenVMS systems, read
- INSTALL.VMS.
-
- Read the documentation in the doc/ directory. It is quite rough, but it
- lists the functions; you will probably have to look at the code to work out
- how to use them. Look at the example programs.
-
- PROBLEMS
- --------
-
- For some platforms, there are some known problems that may affect the user
- or application author. We try to collect those in doc/PROBLEMS, with current
- thoughts on how they should be solved in a future of OpenSSL.
-
- SUPPORT
- -------
-
- See the OpenSSL website www.openssl.org for details of how to obtain
- commercial technical support.
-
- If you have any problems with OpenSSL then please take the following steps
- first:
-
- - Download the current snapshot from ftp://ftp.openssl.org/snapshot/
- to see if the problem has already been addressed
- - Remove ASM versions of libraries
- - Remove compiler optimisation flags
-
- If you wish to report a bug then please include the following information in
- any bug report:
-
- - On Unix systems:
- Self-test report generated by 'make report'
- - On other systems:
- OpenSSL version: output of 'openssl version -a'
- OS Name, Version, Hardware platform
- Compiler Details (name, version)
- - Application Details (name, version)
- - Problem Description (steps that will reproduce the problem, if known)
- - Stack Traceback (if the application dumps core)
-
- Report the bug to the OpenSSL project via the Request Tracker
- (http://www.openssl.org/support/rt.html) by mail to:
-
- openssl-bugs@openssl.org
-
- Note that the request tracker should NOT be used for general assistance
- or support queries. Just because something doesn't work the way you expect
- does not mean it is necessarily a bug in OpenSSL.
-
- Note that mail to openssl-bugs@openssl.org is recorded in the publicly
- readable request tracker database and is forwarded to a public
- mailing list. Confidential mail may be sent to openssl-security@openssl.org
- (PGP key available from the key servers).
-
- HOW TO CONTRIBUTE TO OpenSSL
- ----------------------------
-
- Development is coordinated on the openssl-dev mailing list (see
- http://www.openssl.org for information on subscribing). If you
- would like to submit a patch, send it to openssl-bugs@openssl.org with
- the string "[PATCH]" in the subject. Please be sure to include a
- textual explanation of what your patch does.
-
- If you are unsure as to whether a feature will be useful for the general
- OpenSSL community please discuss it on the openssl-dev mailing list first.
- Someone may be already working on the same thing or there may be a good
- reason as to why that feature isn't implemented.
-
- Patches should be as up to date as possible, preferably relative to the
- current CVS or the last snapshot. They should follow the coding style of
- OpenSSL and compile without warnings. Some of the core team developer targets
- can be used for testing purposes, (debug-steve64, debug-geoff etc). OpenSSL
- compiles on many varied platforms: try to ensure you only use portable
- features.
-
- Note: For legal reasons, contributions from the US can be accepted only
- if a TSU notification and a copy of the patch are sent to crypt@bis.doc.gov
- (formerly BXA) with a copy to the ENC Encryption Request Coordinator;
- please take some time to look at
- http://www.bis.doc.gov/Encryption/PubAvailEncSourceCodeNofify.html [sic]
- and
- http://w3.access.gpo.gov/bis/ear/pdf/740.pdf (EAR Section 740.13(e))
- for the details. If "your encryption source code is too large to serve as
- an email attachment", they are glad to receive it by fax instead; hope you
- have a cheap long-distance plan.
-
- Our preferred format for changes is "diff -u" output. You might
- generate it like this:
-
- # cd openssl-work
- # [your changes]
- # ./Configure dist; make clean
- # cd ..
- # diff -ur openssl-orig openssl-work > mydiffs.patch
-
+
+ OpenSSL 1.0.0d
+
+ Copyright (c) 1998-2011 The OpenSSL Project
+ Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
+ All rights reserved.
+
+ DESCRIPTION
+ -----------
+
+ The OpenSSL Project is a collaborative effort to develop a robust,
+ commercial-grade, fully featured, and Open Source toolkit implementing the
+ Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
+ protocols as well as a full-strength general purpose cryptography library.
+ The project is managed by a worldwide community of volunteers that use the
+ Internet to communicate, plan, and develop the OpenSSL toolkit and its
+ related documentation.
+
+ OpenSSL is based on the excellent SSLeay library developed from Eric A. Young
+ and Tim J. Hudson. The OpenSSL toolkit is licensed under a dual-license (the
+ OpenSSL license plus the SSLeay license) situation, which basically means
+ that you are free to get and use it for commercial and non-commercial
+ purposes as long as you fulfill the conditions of both licenses.
+
+ OVERVIEW
+ --------
+
+ The OpenSSL toolkit includes:
+
+ libssl.a:
+ Implementation of SSLv2, SSLv3, TLSv1 and the required code to support
+ both SSLv2, SSLv3 and TLSv1 in the one server and client.
+
+ libcrypto.a:
+ General encryption and X.509 v1/v3 stuff needed by SSL/TLS but not
+ actually logically part of it. It includes routines for the following:
+
+ Ciphers
+ libdes - EAY's libdes DES encryption package which was floating
+ around the net for a few years, and was then relicensed by
+ him as part of SSLeay. It includes 15 'modes/variations'
+ of DES (1, 2 and 3 key versions of ecb, cbc, cfb and ofb;
+ pcbc and a more general form of cfb and ofb) including desx
+ in cbc mode, a fast crypt(3), and routines to read
+ passwords from the keyboard.
+ RC4 encryption,
+ RC2 encryption - 4 different modes, ecb, cbc, cfb and ofb.
+ Blowfish encryption - 4 different modes, ecb, cbc, cfb and ofb.
+ IDEA encryption - 4 different modes, ecb, cbc, cfb and ofb.
+
+ Digests
+ MD5 and MD2 message digest algorithms, fast implementations,
+ SHA (SHA-0) and SHA-1 message digest algorithms,
+ MDC2 message digest. A DES based hash that is popular on smart cards.
+
+ Public Key
+ RSA encryption/decryption/generation.
+ There is no limit on the number of bits.
+ DSA encryption/decryption/generation.
+ There is no limit on the number of bits.
+ Diffie-Hellman key-exchange/key generation.
+ There is no limit on the number of bits.
+
+ X.509v3 certificates
+ X509 encoding/decoding into/from binary ASN1 and a PEM
+ based ASCII-binary encoding which supports encryption with a
+ private key. Program to generate RSA and DSA certificate
+ requests and to generate RSA and DSA certificates.
+
+ Systems
+ The normal digital envelope routines and base64 encoding. Higher
+ level access to ciphers and digests by name. New ciphers can be
+ loaded at run time. The BIO io system which is a simple non-blocking
+ IO abstraction. Current methods supported are file descriptors,
+ sockets, socket accept, socket connect, memory buffer, buffering, SSL
+ client/server, file pointer, encryption, digest, non-blocking testing
+ and null.
+
+ Data structures
+ A dynamically growing hashing system
+ A simple stack.
+ A Configuration loader that uses a format similar to MS .ini files.
+
+ openssl:
+ A command line tool that can be used for:
+ Creation of RSA, DH and DSA key parameters
+ Creation of X.509 certificates, CSRs and CRLs
+ Calculation of Message Digests
+ Encryption and Decryption with Ciphers
+ SSL/TLS Client and Server Tests
+ Handling of S/MIME signed or encrypted mail
+
+
+ PATENTS
+ -------
+
+ Various companies hold various patents for various algorithms in various
+ locations around the world. _YOU_ are responsible for ensuring that your use
+ of any algorithms is legal by checking if there are any patents in your
+ country. The file contains some of the patents that we know about or are
+ rumored to exist. This is not a definitive list.
+
+ RSA Security holds software patents on the RC5 algorithm. If you
+ intend to use this cipher, you must contact RSA Security for
+ licensing conditions. Their web page is http://www.rsasecurity.com/.
+
+ RC4 is a trademark of RSA Security, so use of this label should perhaps
+ only be used with RSA Security's permission.
+
+ The IDEA algorithm is patented by Ascom in Austria, France, Germany, Italy,
+ Japan, the Netherlands, Spain, Sweden, Switzerland, UK and the USA. They
+ should be contacted if that algorithm is to be used; their web page is
+ http://www.ascom.ch/.
+
+ NTT and Mitsubishi have patents and pending patents on the Camellia
+ algorithm, but allow use at no charge without requiring an explicit
+ licensing agreement: http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
+
+ INSTALLATION
+ ------------
+
+ To install this package under a Unix derivative, read the INSTALL file. For
+ a Win32 platform, read the INSTALL.W32 file. For OpenVMS systems, read
+ INSTALL.VMS.
+
+ Read the documentation in the doc/ directory. It is quite rough, but it
+ lists the functions; you will probably have to look at the code to work out
+ how to use them. Look at the example programs.
+
+ PROBLEMS
+ --------
+
+ For some platforms, there are some known problems that may affect the user
+ or application author. We try to collect those in doc/PROBLEMS, with current
+ thoughts on how they should be solved in a future of OpenSSL.
+
+ SUPPORT
+ -------
+
+ See the OpenSSL website www.openssl.org for details of how to obtain
+ commercial technical support.
+
+ If you have any problems with OpenSSL then please take the following steps
+ first:
+
+ - Download the current snapshot from ftp://ftp.openssl.org/snapshot/
+ to see if the problem has already been addressed
+ - Remove ASM versions of libraries
+ - Remove compiler optimisation flags
+
+ If you wish to report a bug then please include the following information in
+ any bug report:
+
+ - On Unix systems:
+ Self-test report generated by 'make report'
+ - On other systems:
+ OpenSSL version: output of 'openssl version -a'
+ OS Name, Version, Hardware platform
+ Compiler Details (name, version)
+ - Application Details (name, version)
+ - Problem Description (steps that will reproduce the problem, if known)
+ - Stack Traceback (if the application dumps core)
+
+ Report the bug to the OpenSSL project via the Request Tracker
+ (http://www.openssl.org/support/rt.html) by mail to:
+
+ openssl-bugs@openssl.org
+
+ Note that the request tracker should NOT be used for general assistance
+ or support queries. Just because something doesn't work the way you expect
+ does not mean it is necessarily a bug in OpenSSL.
+
+ Note that mail to openssl-bugs@openssl.org is recorded in the publicly
+ readable request tracker database and is forwarded to a public
+ mailing list. Confidential mail may be sent to openssl-security@openssl.org
+ (PGP key available from the key servers).
+
+ HOW TO CONTRIBUTE TO OpenSSL
+ ----------------------------
+
+ Development is coordinated on the openssl-dev mailing list (see
+ http://www.openssl.org for information on subscribing). If you
+ would like to submit a patch, send it to openssl-bugs@openssl.org with
+ the string "[PATCH]" in the subject. Please be sure to include a
+ textual explanation of what your patch does.
+
+ If you are unsure as to whether a feature will be useful for the general
+ OpenSSL community please discuss it on the openssl-dev mailing list first.
+ Someone may be already working on the same thing or there may be a good
+ reason as to why that feature isn't implemented.
+
+ Patches should be as up to date as possible, preferably relative to the
+ current CVS or the last snapshot. They should follow the coding style of
+ OpenSSL and compile without warnings. Some of the core team developer targets
+ can be used for testing purposes, (debug-steve64, debug-geoff etc). OpenSSL
+ compiles on many varied platforms: try to ensure you only use portable
+ features.
+
+ Note: For legal reasons, contributions from the US can be accepted only
+ if a TSU notification and a copy of the patch are sent to crypt@bis.doc.gov
+ (formerly BXA) with a copy to the ENC Encryption Request Coordinator;
+ please take some time to look at
+ http://www.bis.doc.gov/Encryption/PubAvailEncSourceCodeNofify.html [sic]
+ and
+ http://w3.access.gpo.gov/bis/ear/pdf/740.pdf (EAR Section 740.13(e))
+ for the details. If "your encryption source code is too large to serve as
+ an email attachment", they are glad to receive it by fax instead; hope you
+ have a cheap long-distance plan.
+
+ Our preferred format for changes is "diff -u" output. You might
+ generate it like this:
+
+ # cd openssl-work
+ # [your changes]
+ # ./Configure dist; make clean
+ # cd ..
+ # diff -ur openssl-orig openssl-work > mydiffs.patch
+
diff --git a/openssl/VMS/mkshared.com b/openssl/VMS/mkshared.com
index 99a3da250..2f9167eea 100644
--- a/openssl/VMS/mkshared.com
+++ b/openssl/VMS/mkshared.com
@@ -1,390 +1,390 @@
-$! MKSHARED.COM -- script to created shareable images on VMS
-$!
-$! No command line parameters. This should be run at the start of the source
-$! tree (the same directory where one finds INSTALL.VMS).
-$!
-$! Input: [.UTIL]LIBEAY.NUM,[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB
-$! [.UTIL]SSLEAY.NUM,[.xxx.EXE.SSL]LIBSSL.OLB
-$! Output: [.xxx.EXE.CRYPTO]LIBCRYPTO.OPT,.MAP,.EXE
-$! [.xxx.EXE.SSL]LIBSSL.OPT,.MAP,.EXE
-$!
-$! So far, tests have only been made on VMS for Alpha. VAX will come in time.
-$! ===========================================================================
-$
-$! ----- Prepare info for processing: version number and file info
-$ gosub read_version_info
-$ if libver .eqs. ""
-$ then
-$ write sys$error "ERROR: Couldn't find any library version info..."
-$ exit
-$ endif
-$
-$ if (f$getsyi("cpu").lt.128)
-$ then
-$ arch := VAX
-$ else
-$ arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
-$ if (arch .eqs. "") then arch = "UNK"
-$ endif
-$
-$ if arch .nes. "VAX"
-$ then
-$ arch_vax = 0
-$ libid = "Crypto"
-$ libnum = "[.UTIL]LIBEAY.NUM"
-$ libdir = "[.''ARCH'.EXE.CRYPTO]"
-$ libolb = "''libdir'LIBCRYPTO.OLB"
-$ libopt = "''libdir'LIBCRYPTO.OPT"
-$ libmap = "''libdir'LIBCRYPTO.MAP"
-$ libgoal= "''libdir'LIBCRYPTO.EXE"
-$ libref = ""
-$ if f$search(libdir+libolb) .nes. "" then gosub create_nonvax_shr
-$ libid = "SSL"
-$ libnum = "[.UTIL]SSLEAY.NUM"
-$ libdir = "[.''ARCH'.EXE.SSL]"
-$ libolb = "''libdir'LIBSSL.OLB"
-$ libopt = "''libdir'LIBSSL.OPT"
-$ libmap = "''libdir'LIBSSL.MAP"
-$ libgoal= "''libdir'LIBSSL.EXE"
-$ libref = "[.''ARCH'.EXE.CRYPTO]LIBCRYPTO.EXE"
-$ if f$search(libdir+libolb) .nes. "" then gosub create_nonvax_shr
-$ arch_vax = 0
-$ libid = "Crypto"
-$ libnum = "[.UTIL]LIBEAY.NUM"
-$ libdir = "[.''ARCH'.EXE.CRYPTO]"
-$ libolb = "''libdir'LIBCRYPTO32.OLB"
-$ libopt = "''libdir'LIBCRYPTO32.OPT"
-$ libmap = "''libdir'LIBCRYPTO32.MAP"
-$ libgoal= "''libdir'LIBCRYPTO32.EXE"
-$ libref = ""
-$ if f$search(libdir+libolb) .nes. "" then gosub create_nonvax_shr
-$ libid = "SSL"
-$ libnum = "[.UTIL]SSLEAY.NUM"
-$ libdir = "[.''ARCH'.EXE.SSL]"
-$ libolb = "''libdir'LIBSSL32.OLB"
-$ libopt = "''libdir'LIBSSL32.OPT"
-$ libmap = "''libdir'LIBSSL32.MAP"
-$ libgoal= "''libdir'LIBSSL32.EXE"
-$ libref = "[.''ARCH'.EXE.CRYPTO]LIBCRYPTO32.EXE"
-$ if f$search(libdir+libolb) .nes. "" then gosub create_nonvax_shr
-$ else
-$ arch_vax = 1
-$ libtit = "CRYPTO_TRANSFER_VECTOR"
-$ libid = "Crypto"
-$ libnum = "[.UTIL]LIBEAY.NUM"
-$ libdir = "[.''ARCH'.EXE.CRYPTO]"
-$ libmar = "''libdir'LIBCRYPTO.MAR"
-$ libolb = "''libdir'LIBCRYPTO.OLB"
-$ libopt = "''libdir'LIBCRYPTO.OPT"
-$ libobj = "''libdir'LIBCRYPTO.OBJ"
-$ libmap = "''libdir'LIBCRYPTO.MAP"
-$ libgoal= "''libdir'LIBCRYPTO.EXE"
-$ libref = ""
-$ libvec = "LIBCRYPTO"
-$ if f$search(libdir+libolb) .nes. "" then gosub create_vax_shr
-$ libtit = "SSL_TRANSFER_VECTOR"
-$ libid = "SSL"
-$ libnum = "[.UTIL]SSLEAY.NUM"
-$ libdir = "[.''ARCH'.EXE.SSL]"
-$ libmar = "''libdir'LIBSSL.MAR"
-$ libolb = "''libdir'LIBSSL.OLB"
-$ libopt = "''libdir'LIBSSL.OPT"
-$ libobj = "''libdir'LIBSSL.OBJ"
-$ libmap = "''libdir'LIBSSL.MAP"
-$ libgoal= "''libdir'LIBSSL.EXE"
-$ libref = "[.''ARCH'.EXE.CRYPTO]LIBCRYPTO.EXE"
-$ libvec = "LIBSSL"
-$ if f$search(libdir+libolb) .nes. "" then gosub create_vax_shr
-$ endif
-$ exit
-$
-$! ----- Subroutines to build the shareable libraries
-$! For each supported architecture, there's a main shareable library
-$! creator, which is called from the main code above.
-$! The creator will define a number of variables to tell the next levels of
-$! subroutines what routines to use to write to the option files, call the
-$! main processor, read_func_num, and when that is done, it will write version
-$! data at the end of the .opt file, close it, and link the library.
-$!
-$! read_func_num reads through a .num file and calls the writer routine for
-$! each line. It's also responsible for checking that order is properly kept
-$! in the .num file, check that each line applies to VMS and the architecture,
-$! and to fill in "holes" with dummy entries.
-$!
-$! The creator routines depend on the following variables:
-$! libnum The name of the .num file to use as input
-$! libolb The name of the object library to build from
-$! libid The identification string of the shareable library
-$! libopt The name of the .opt file to write
-$! libtit The title of the assembler transfer vector file (VAX only)
-$! libmar The name of the assembler transfer vector file (VAX only)
-$! libmap The name of the map file to write
-$! libgoal The name of the shareable library to write
-$! libref The name of a shareable library to link in
-$!
-$! read_func_num depends on the following variables from the creator:
-$! libwriter The name of the writer routine to call for each .num file line
-$! -----
-$
-$! ----- Subroutines for non-VAX
-$! -----
-$! The creator routine
-$ create_nonvax_shr:
-$ open/write opt 'libopt'
-$ write opt "identification=""",libid," ",libverstr,""""
-$ write opt libolb,"/lib"
-$ if libref .nes. "" then write opt libref,"/SHARE"
-$ write opt "SYMBOL_VECTOR=(-"
-$ libfirstentry := true
-$ libwrch := opt
-$ libwriter := write_nonvax_transfer_entry
-$ textcount = 0
-$ gosub read_func_num
-$ write opt ")"
-$ write opt "GSMATCH=",libvmatch,",",libver
-$ close opt
-$ link/map='libmap'/full/share='libgoal' 'libopt'/option
-$ return
-$
-$! The record writer routine
-$ write_nonvax_transfer_entry:
-$ if libentry .eqs. ".dummy" then return
-$ if info_kind .eqs. "VARIABLE"
-$ then
-$ pr:=DATA
-$ else
-$ pr:=PROCEDURE
-$ endif
-$ textcount_this = f$length(pr) + f$length(libentry) + 5
-$ if textcount + textcount_this .gt. 1024
-$ then
-$ write opt ")"
-$ write opt "SYMBOL_VECTOR=(-"
-$ textcount = 16
-$ libfirstentry := true
-$ endif
-$ if libfirstentry
-$ then
-$ write 'libwrch' " ",libentry,"=",pr," -"
-$ else
-$ write 'libwrch' " ,",libentry,"=",pr," -"
-$ endif
-$ libfirstentry := false
-$ textcount = textcount + textcount_this
-$ return
-$
-$! ----- Subroutines for VAX
-$! -----
-$! The creator routine
-$ create_vax_shr:
-$ open/write mar 'libmar'
-$ type sys$input:/out=mar:
-;
-; Transfer vector for VAX shareable image
-;
-$ write mar " .TITLE ",libtit
-$ write mar " .IDENT /",libid,"/"
-$ type sys$input:/out=mar:
-;
-; Define macro to assist in building transfer vector entries. Each entry
-; should take no more than 8 bytes.
-;
- .MACRO FTRANSFER_ENTRY routine
- .ALIGN QUAD
- .TRANSFER routine
- .MASK routine
- JMP routine+2
- .ENDM FTRANSFER_ENTRY
-;
-; Place entries in own program section.
-;
-$ write mar " .PSECT $$",libvec,",QUAD,PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT"
-$ write mar libvec,"_xfer:"
-$ libwrch := mar
-$ libwriter := write_vax_ftransfer_entry
-$ gosub read_func_num
-$ type sys$input:/out=mar:
-;
-; Allocate extra storage at end of vector to allow for expansion.
-;
-$ write mar " .BLKB 32768-<.-",libvec,"_xfer> ; 64 pages total."
-$! libwriter := write_vax_vtransfer_entry
-$! gosub read_func_num
-$ write mar " .END"
-$ close mar
-$ open/write opt 'libopt'
-$ write opt "identification=""",libid," ",libverstr,""""
-$ write opt libobj
-$ write opt libolb,"/lib"
-$ if libref .nes. "" then write opt libref,"/SHARE"
-$ type sys$input:/out=opt:
-!
-! Ensure transfer vector is at beginning of image
-!
-CLUSTER=FIRST
-$ write opt "COLLECT=FIRST,$$",libvec
-$ write opt "GSMATCH=",libvmatch,",",libver
-$ type sys$input:/out=opt:
-!
-! make psects nonshareable so image can be installed.
-!
-PSECT_ATTR=$CHAR_STRING_CONSTANTS,NOWRT
-$ libwrch := opt
-$ libwriter := write_vax_psect_attr
-$ gosub read_func_num
-$ close opt
-$ macro/obj='libobj' 'libmar'
-$ link/map='libmap'/full/share='libgoal' 'libopt'/option
-$ return
-$
-$! The record writer routine for VAX functions
-$ write_vax_ftransfer_entry:
-$ if info_kind .nes. "FUNCTION" then return
-$ if libentry .eqs ".dummy"
-$ then
-$ write 'libwrch' " .BLKB 8" ! Dummy is zeroes...
-$ else
-$ write 'libwrch' " FTRANSFER_ENTRY ",libentry
-$ endif
-$ return
-$! The record writer routine for VAX variables (should never happen!)
-$ write_vax_psect_attr:
-$ if info_kind .nes. "VARIABLE" then return
-$ if libentry .eqs ".dummy" then return
-$ write 'libwrch' "PSECT_ATTR=",libentry,",NOSHR"
-$ return
-$
-$! ----- Common subroutines
-$! -----
-$! The .num file reader. This one has great responsability.
-$ read_func_num:
-$ open libnum 'libnum'
-$ goto read_nums
-$
-$ read_nums:
-$ libentrynum=0
-$ liblastentry:=false
-$ entrycount=0
-$ loop:
-$ read/end=loop_end/err=loop_end libnum line
-$ entrynum=f$int(f$element(1," ",f$edit(line,"COMPRESS,TRIM")))
-$ entryinfo=f$element(2," ",f$edit(line,"COMPRESS,TRIM"))
-$ curentry=f$element(0," ",f$edit(line,"COMPRESS,TRIM"))
-$ info_exist=f$element(0,":",entryinfo)
-$ info_platforms=","+f$element(1,":",entryinfo)+","
-$ info_kind=f$element(2,":",entryinfo)
-$ info_algorithms=","+f$element(3,":",entryinfo)+","
-$ if info_exist .eqs. "NOEXIST" then goto loop
-$ truesum = 0
-$ falsesum = 0
-$ negatives = 1
-$ plat_i = 0
-$ loop1:
-$ plat_entry = f$element(plat_i,",",info_platforms)
-$ plat_i = plat_i + 1
-$ if plat_entry .eqs. "" then goto loop1
-$ if plat_entry .nes. ","
-$ then
-$ if f$extract(0,1,plat_entry) .nes. "!" then negatives = 0
-$ if f$getsyi("CPU") .lt. 128
-$ then
-$ if plat_entry .eqs. "EXPORT_VAR_AS_FUNCTION" then -
-$ truesum = truesum + 1
-$ if plat_entry .eqs. "!EXPORT_VAR_AS_FUNCTION" then -
-$ falsesum = falsesum + 1
-$ endif
-$!
-$ if ((plat_entry .eqs. "VMS") .or. -
- (arch_vax .and. (plat_entry .eqs. "VMSVAX"))) then -
- truesum = truesum + 1
-$!
-$ if ((plat_entry .eqs. "!VMS") .or. -
- (arch_vax .and. (plat_entry .eqs. "!VMSVAX"))) then -
- falsesum = falsesum + 1
-$!
-$ goto loop1
-$ endif
-$ endloop1:
-$!DEBUG!$ if info_platforms - "EXPORT_VAR_AS_FUNCTION" .nes. info_platforms
-$!DEBUG!$ then
-$!DEBUG!$ write sys$output line
-$!DEBUG!$ write sys$output " truesum = ",truesum,-
-$!DEBUG! ", negatives = ",negatives,", falsesum = ",falsesum
-$!DEBUG!$ endif
-$ if falsesum .ne. 0 then goto loop
-$ if truesum+negatives .eq. 0 then goto loop
-$ alg_i = 0
-$ loop2:
-$ alg_entry = f$element(alg_i,",",info_algorithms)
-$ alg_i = alg_i + 1
-$ if alg_entry .eqs. "" then goto loop2
-$ if alg_entry .nes. ","
-$ then
-$ if alg_entry .eqs. "KRB5" then goto loop ! Special for now
-$ if alg_entry .eqs. "STATIC_ENGINE" then goto loop ! Special for now
-$ if f$trnlnm("OPENSSL_NO_"+alg_entry) .nes. "" then goto loop
-$ goto loop2
-$ endif
-$ endloop2:
-$ if info_platforms - "EXPORT_VAR_AS_FUNCTION" .nes. info_platforms
-$ then
-$!DEBUG!$ write sys$output curentry," ; ",entrynum," ; ",entryinfo
-$ endif
-$ redo:
-$ next:=loop
-$ tolibentry=curentry
-$ if libentrynum .ne. entrynum
-$ then
-$ entrycount=entrycount+1
-$ if entrycount .lt. entrynum
-$ then
-$!DEBUG!$ write sys$output "Info: entrycount: ''entrycount', entrynum: ''entrynum' => 0"
-$ tolibentry=".dummy"
-$ next:=redo
-$ endif
-$ if entrycount .gt. entrynum
-$ then
-$ write sys$error "Decreasing library entry numbers! Can't continue"
-$ write sys$error """",line,""""
-$ close libnum
-$ return
-$ endif
-$ libentry=tolibentry
-$!DEBUG!$ write sys$output entrycount," ",libentry," ",entryinfo
-$ if libentry .nes. "" .and. libwriter .nes. "" then gosub 'libwriter'
-$ else
-$ write sys$error "Info: ""''curentry'"" is an alias for ""''libentry'"". Overriding..."
-$ endif
-$ libentrynum=entrycount
-$ goto 'next'
-$ loop_end:
-$ close libnum
-$ return
-$
-$! The version number reader
-$ read_version_info:
-$ libver = ""
-$ open/read vf [.CRYPTO]OPENSSLV.H
-$ loop_rvi:
-$ read/err=endloop_rvi/end=endloop_rvi vf rvi_line
-$ if rvi_line - "SHLIB_VERSION_NUMBER """ .eqs. rvi_line then -
- goto loop_rvi
-$ libverstr = f$element(1,"""",rvi_line)
-$ libvmajor = f$element(0,".",libverstr)
-$ libvminor = f$element(1,".",libverstr)
-$ libvedit = f$element(2,".",libverstr)
-$ libvpatch = f$cvui(0,8,f$extract(1,1,libvedit)+"@")-f$cvui(0,8,"@")
-$ libvedit = f$extract(0,1,libvedit)
-$ libver = f$string(f$int(libvmajor)*100)+","+-
- f$string(f$int(libvminor)*100+f$int(libvedit)*10+f$int(libvpatch))
-$ if libvmajor .eqs. "0"
-$ then
-$ libvmatch = "EQUAL"
-$ else
-$ ! Starting with the 1.0 release, backward compatibility should be
-$ ! kept, so switch over to the following
-$ libvmatch = "LEQUAL"
-$ endif
-$ endloop_rvi:
-$ close vf
-$ return
+$! MKSHARED.COM -- script to created shareable images on VMS
+$!
+$! No command line parameters. This should be run at the start of the source
+$! tree (the same directory where one finds INSTALL.VMS).
+$!
+$! Input: [.UTIL]LIBEAY.NUM,[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB
+$! [.UTIL]SSLEAY.NUM,[.xxx.EXE.SSL]LIBSSL.OLB
+$! Output: [.xxx.EXE.CRYPTO]LIBCRYPTO.OPT,.MAP,.EXE
+$! [.xxx.EXE.SSL]LIBSSL.OPT,.MAP,.EXE
+$!
+$! So far, tests have only been made on VMS for Alpha. VAX will come in time.
+$! ===========================================================================
+$
+$! ----- Prepare info for processing: version number and file info
+$ gosub read_version_info
+$ if libver .eqs. ""
+$ then
+$ write sys$error "ERROR: Couldn't find any library version info..."
+$ exit
+$ endif
+$
+$ if (f$getsyi("cpu").lt.128)
+$ then
+$ arch := VAX
+$ else
+$ arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if (arch .eqs. "") then arch = "UNK"
+$ endif
+$
+$ if arch .nes. "VAX"
+$ then
+$ arch_vax = 0
+$ libid = "Crypto"
+$ libnum = "[.UTIL]LIBEAY.NUM"
+$ libdir = "[.''ARCH'.EXE.CRYPTO]"
+$ libolb = "''libdir'LIBCRYPTO.OLB"
+$ libopt = "''libdir'LIBCRYPTO.OPT"
+$ libmap = "''libdir'LIBCRYPTO.MAP"
+$ libgoal= "''libdir'LIBCRYPTO.EXE"
+$ libref = ""
+$ if f$search(libdir+libolb) .nes. "" then gosub create_nonvax_shr
+$ libid = "SSL"
+$ libnum = "[.UTIL]SSLEAY.NUM"
+$ libdir = "[.''ARCH'.EXE.SSL]"
+$ libolb = "''libdir'LIBSSL.OLB"
+$ libopt = "''libdir'LIBSSL.OPT"
+$ libmap = "''libdir'LIBSSL.MAP"
+$ libgoal= "''libdir'LIBSSL.EXE"
+$ libref = "[.''ARCH'.EXE.CRYPTO]LIBCRYPTO.EXE"
+$ if f$search(libdir+libolb) .nes. "" then gosub create_nonvax_shr
+$ arch_vax = 0
+$ libid = "Crypto"
+$ libnum = "[.UTIL]LIBEAY.NUM"
+$ libdir = "[.''ARCH'.EXE.CRYPTO]"
+$ libolb = "''libdir'LIBCRYPTO32.OLB"
+$ libopt = "''libdir'LIBCRYPTO32.OPT"
+$ libmap = "''libdir'LIBCRYPTO32.MAP"
+$ libgoal= "''libdir'LIBCRYPTO32.EXE"
+$ libref = ""
+$ if f$search(libdir+libolb) .nes. "" then gosub create_nonvax_shr
+$ libid = "SSL"
+$ libnum = "[.UTIL]SSLEAY.NUM"
+$ libdir = "[.''ARCH'.EXE.SSL]"
+$ libolb = "''libdir'LIBSSL32.OLB"
+$ libopt = "''libdir'LIBSSL32.OPT"
+$ libmap = "''libdir'LIBSSL32.MAP"
+$ libgoal= "''libdir'LIBSSL32.EXE"
+$ libref = "[.''ARCH'.EXE.CRYPTO]LIBCRYPTO32.EXE"
+$ if f$search(libdir+libolb) .nes. "" then gosub create_nonvax_shr
+$ else
+$ arch_vax = 1
+$ libtit = "CRYPTO_TRANSFER_VECTOR"
+$ libid = "Crypto"
+$ libnum = "[.UTIL]LIBEAY.NUM"
+$ libdir = "[.''ARCH'.EXE.CRYPTO]"
+$ libmar = "''libdir'LIBCRYPTO.MAR"
+$ libolb = "''libdir'LIBCRYPTO.OLB"
+$ libopt = "''libdir'LIBCRYPTO.OPT"
+$ libobj = "''libdir'LIBCRYPTO.OBJ"
+$ libmap = "''libdir'LIBCRYPTO.MAP"
+$ libgoal= "''libdir'LIBCRYPTO.EXE"
+$ libref = ""
+$ libvec = "LIBCRYPTO"
+$ if f$search(libdir+libolb) .nes. "" then gosub create_vax_shr
+$ libtit = "SSL_TRANSFER_VECTOR"
+$ libid = "SSL"
+$ libnum = "[.UTIL]SSLEAY.NUM"
+$ libdir = "[.''ARCH'.EXE.SSL]"
+$ libmar = "''libdir'LIBSSL.MAR"
+$ libolb = "''libdir'LIBSSL.OLB"
+$ libopt = "''libdir'LIBSSL.OPT"
+$ libobj = "''libdir'LIBSSL.OBJ"
+$ libmap = "''libdir'LIBSSL.MAP"
+$ libgoal= "''libdir'LIBSSL.EXE"
+$ libref = "[.''ARCH'.EXE.CRYPTO]LIBCRYPTO.EXE"
+$ libvec = "LIBSSL"
+$ if f$search(libdir+libolb) .nes. "" then gosub create_vax_shr
+$ endif
+$ exit
+$
+$! ----- Subroutines to build the shareable libraries
+$! For each supported architecture, there's a main shareable library
+$! creator, which is called from the main code above.
+$! The creator will define a number of variables to tell the next levels of
+$! subroutines what routines to use to write to the option files, call the
+$! main processor, read_func_num, and when that is done, it will write version
+$! data at the end of the .opt file, close it, and link the library.
+$!
+$! read_func_num reads through a .num file and calls the writer routine for
+$! each line. It's also responsible for checking that order is properly kept
+$! in the .num file, check that each line applies to VMS and the architecture,
+$! and to fill in "holes" with dummy entries.
+$!
+$! The creator routines depend on the following variables:
+$! libnum The name of the .num file to use as input
+$! libolb The name of the object library to build from
+$! libid The identification string of the shareable library
+$! libopt The name of the .opt file to write
+$! libtit The title of the assembler transfer vector file (VAX only)
+$! libmar The name of the assembler transfer vector file (VAX only)
+$! libmap The name of the map file to write
+$! libgoal The name of the shareable library to write
+$! libref The name of a shareable library to link in
+$!
+$! read_func_num depends on the following variables from the creator:
+$! libwriter The name of the writer routine to call for each .num file line
+$! -----
+$
+$! ----- Subroutines for non-VAX
+$! -----
+$! The creator routine
+$ create_nonvax_shr:
+$ open/write opt 'libopt'
+$ write opt "identification=""",libid," ",libverstr,""""
+$ write opt libolb,"/lib"
+$ if libref .nes. "" then write opt libref,"/SHARE"
+$ write opt "SYMBOL_VECTOR=(-"
+$ libfirstentry := true
+$ libwrch := opt
+$ libwriter := write_nonvax_transfer_entry
+$ textcount = 0
+$ gosub read_func_num
+$ write opt ")"
+$ write opt "GSMATCH=",libvmatch,",",libver
+$ close opt
+$ link/map='libmap'/full/share='libgoal' 'libopt'/option
+$ return
+$
+$! The record writer routine
+$ write_nonvax_transfer_entry:
+$ if libentry .eqs. ".dummy" then return
+$ if info_kind .eqs. "VARIABLE"
+$ then
+$ pr:=DATA
+$ else
+$ pr:=PROCEDURE
+$ endif
+$ textcount_this = f$length(pr) + f$length(libentry) + 5
+$ if textcount + textcount_this .gt. 1024
+$ then
+$ write opt ")"
+$ write opt "SYMBOL_VECTOR=(-"
+$ textcount = 16
+$ libfirstentry := true
+$ endif
+$ if libfirstentry
+$ then
+$ write 'libwrch' " ",libentry,"=",pr," -"
+$ else
+$ write 'libwrch' " ,",libentry,"=",pr," -"
+$ endif
+$ libfirstentry := false
+$ textcount = textcount + textcount_this
+$ return
+$
+$! ----- Subroutines for VAX
+$! -----
+$! The creator routine
+$ create_vax_shr:
+$ open/write mar 'libmar'
+$ type sys$input:/out=mar:
+;
+; Transfer vector for VAX shareable image
+;
+$ write mar " .TITLE ",libtit
+$ write mar " .IDENT /",libid,"/"
+$ type sys$input:/out=mar:
+;
+; Define macro to assist in building transfer vector entries. Each entry
+; should take no more than 8 bytes.
+;
+ .MACRO FTRANSFER_ENTRY routine
+ .ALIGN QUAD
+ .TRANSFER routine
+ .MASK routine
+ JMP routine+2
+ .ENDM FTRANSFER_ENTRY
+;
+; Place entries in own program section.
+;
+$ write mar " .PSECT $$",libvec,",QUAD,PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT"
+$ write mar libvec,"_xfer:"
+$ libwrch := mar
+$ libwriter := write_vax_ftransfer_entry
+$ gosub read_func_num
+$ type sys$input:/out=mar:
+;
+; Allocate extra storage at end of vector to allow for expansion.
+;
+$ write mar " .BLKB 32768-<.-",libvec,"_xfer> ; 64 pages total."
+$! libwriter := write_vax_vtransfer_entry
+$! gosub read_func_num
+$ write mar " .END"
+$ close mar
+$ open/write opt 'libopt'
+$ write opt "identification=""",libid," ",libverstr,""""
+$ write opt libobj
+$ write opt libolb,"/lib"
+$ if libref .nes. "" then write opt libref,"/SHARE"
+$ type sys$input:/out=opt:
+!
+! Ensure transfer vector is at beginning of image
+!
+CLUSTER=FIRST
+$ write opt "COLLECT=FIRST,$$",libvec
+$ write opt "GSMATCH=",libvmatch,",",libver
+$ type sys$input:/out=opt:
+!
+! make psects nonshareable so image can be installed.
+!
+PSECT_ATTR=$CHAR_STRING_CONSTANTS,NOWRT
+$ libwrch := opt
+$ libwriter := write_vax_psect_attr
+$ gosub read_func_num
+$ close opt
+$ macro/obj='libobj' 'libmar'
+$ link/map='libmap'/full/share='libgoal' 'libopt'/option
+$ return
+$
+$! The record writer routine for VAX functions
+$ write_vax_ftransfer_entry:
+$ if info_kind .nes. "FUNCTION" then return
+$ if libentry .eqs ".dummy"
+$ then
+$ write 'libwrch' " .BLKB 8" ! Dummy is zeroes...
+$ else
+$ write 'libwrch' " FTRANSFER_ENTRY ",libentry
+$ endif
+$ return
+$! The record writer routine for VAX variables (should never happen!)
+$ write_vax_psect_attr:
+$ if info_kind .nes. "VARIABLE" then return
+$ if libentry .eqs ".dummy" then return
+$ write 'libwrch' "PSECT_ATTR=",libentry,",NOSHR"
+$ return
+$
+$! ----- Common subroutines
+$! -----
+$! The .num file reader. This one has great responsability.
+$ read_func_num:
+$ open libnum 'libnum'
+$ goto read_nums
+$
+$ read_nums:
+$ libentrynum=0
+$ liblastentry:=false
+$ entrycount=0
+$ loop:
+$ read/end=loop_end/err=loop_end libnum line
+$ entrynum=f$int(f$element(1," ",f$edit(line,"COMPRESS,TRIM")))
+$ entryinfo=f$element(2," ",f$edit(line,"COMPRESS,TRIM"))
+$ curentry=f$element(0," ",f$edit(line,"COMPRESS,TRIM"))
+$ info_exist=f$element(0,":",entryinfo)
+$ info_platforms=","+f$element(1,":",entryinfo)+","
+$ info_kind=f$element(2,":",entryinfo)
+$ info_algorithms=","+f$element(3,":",entryinfo)+","
+$ if info_exist .eqs. "NOEXIST" then goto loop
+$ truesum = 0
+$ falsesum = 0
+$ negatives = 1
+$ plat_i = 0
+$ loop1:
+$ plat_entry = f$element(plat_i,",",info_platforms)
+$ plat_i = plat_i + 1
+$ if plat_entry .eqs. "" then goto loop1
+$ if plat_entry .nes. ","
+$ then
+$ if f$extract(0,1,plat_entry) .nes. "!" then negatives = 0
+$ if f$getsyi("CPU") .lt. 128
+$ then
+$ if plat_entry .eqs. "EXPORT_VAR_AS_FUNCTION" then -
+$ truesum = truesum + 1
+$ if plat_entry .eqs. "!EXPORT_VAR_AS_FUNCTION" then -
+$ falsesum = falsesum + 1
+$ endif
+$!
+$ if ((plat_entry .eqs. "VMS") .or. -
+ (arch_vax .and. (plat_entry .eqs. "VMSVAX"))) then -
+ truesum = truesum + 1
+$!
+$ if ((plat_entry .eqs. "!VMS") .or. -
+ (arch_vax .and. (plat_entry .eqs. "!VMSVAX"))) then -
+ falsesum = falsesum + 1
+$!
+$ goto loop1
+$ endif
+$ endloop1:
+$!DEBUG!$ if info_platforms - "EXPORT_VAR_AS_FUNCTION" .nes. info_platforms
+$!DEBUG!$ then
+$!DEBUG!$ write sys$output line
+$!DEBUG!$ write sys$output " truesum = ",truesum,-
+$!DEBUG! ", negatives = ",negatives,", falsesum = ",falsesum
+$!DEBUG!$ endif
+$ if falsesum .ne. 0 then goto loop
+$ if truesum+negatives .eq. 0 then goto loop
+$ alg_i = 0
+$ loop2:
+$ alg_entry = f$element(alg_i,",",info_algorithms)
+$ alg_i = alg_i + 1
+$ if alg_entry .eqs. "" then goto loop2
+$ if alg_entry .nes. ","
+$ then
+$ if alg_entry .eqs. "KRB5" then goto loop ! Special for now
+$ if alg_entry .eqs. "STATIC_ENGINE" then goto loop ! Special for now
+$ if f$trnlnm("OPENSSL_NO_"+alg_entry) .nes. "" then goto loop
+$ goto loop2
+$ endif
+$ endloop2:
+$ if info_platforms - "EXPORT_VAR_AS_FUNCTION" .nes. info_platforms
+$ then
+$!DEBUG!$ write sys$output curentry," ; ",entrynum," ; ",entryinfo
+$ endif
+$ redo:
+$ next:=loop
+$ tolibentry=curentry
+$ if libentrynum .ne. entrynum
+$ then
+$ entrycount=entrycount+1
+$ if entrycount .lt. entrynum
+$ then
+$!DEBUG!$ write sys$output "Info: entrycount: ''entrycount', entrynum: ''entrynum' => 0"
+$ tolibentry=".dummy"
+$ next:=redo
+$ endif
+$ if entrycount .gt. entrynum
+$ then
+$ write sys$error "Decreasing library entry numbers! Can't continue"
+$ write sys$error """",line,""""
+$ close libnum
+$ return
+$ endif
+$ libentry=tolibentry
+$!DEBUG!$ write sys$output entrycount," ",libentry," ",entryinfo
+$ if libentry .nes. "" .and. libwriter .nes. "" then gosub 'libwriter'
+$ else
+$ write sys$error "Info: ""''curentry'"" is an alias for ""''libentry'"". Overriding..."
+$ endif
+$ libentrynum=entrycount
+$ goto 'next'
+$ loop_end:
+$ close libnum
+$ return
+$
+$! The version number reader
+$ read_version_info:
+$ libver = ""
+$ open/read vf [.CRYPTO]OPENSSLV.H
+$ loop_rvi:
+$ read/err=endloop_rvi/end=endloop_rvi vf rvi_line
+$ if rvi_line - "SHLIB_VERSION_NUMBER """ .eqs. rvi_line then -
+ goto loop_rvi
+$ libverstr = f$element(1,"""",rvi_line)
+$ libvmajor = f$element(0,".",libverstr)
+$ libvminor = f$element(1,".",libverstr)
+$ libvedit = f$element(2,".",libverstr)
+$ libvpatch = f$cvui(0,8,f$extract(1,1,libvedit)+"@")-f$cvui(0,8,"@")
+$ libvedit = f$extract(0,1,libvedit)
+$ libver = f$string(f$int(libvmajor)*100)+","+-
+ f$string(f$int(libvminor)*100+f$int(libvedit)*10+f$int(libvpatch))
+$ if libvmajor .eqs. "0"
+$ then
+$ libvmatch = "EQUAL"
+$ else
+$ ! Starting with the 1.0 release, backward compatibility should be
+$ ! kept, so switch over to the following
+$ libvmatch = "LEQUAL"
+$ endif
+$ endloop_rvi:
+$ close vf
+$ return
diff --git a/openssl/apps/makeapps.com b/openssl/apps/makeapps.com
index 6a7e4b4a4..7a728e6a5 100644
--- a/openssl/apps/makeapps.com
+++ b/openssl/apps/makeapps.com
@@ -1,1056 +1,1056 @@
-$!
-$! MAKEAPPS.COM
-$! Written By: Robert Byer
-$! Vice-President
-$! A-Com Computing, Inc.
-$! byer@mail.all-net.net
-$!
-$! Changes by Richard Levitte <richard@levitte.org>
-$! Zoltan Arpadffy <zoli@polarhome.com>
-$!
-$! This command files compiles and creates all the various different
-$! "application" programs for the different types of encryption for OpenSSL.
-$! The EXE's are placed in the directory [.xxx.EXE.APPS] where "xxx" denotes
-$! ALPHA, IA64 or VAX, depending on your machine architecture.
-$!
-$! It was written so it would try to determine what "C" compiler to
-$! use or you can specify which "C" compiler to use.
-$!
-$! Specify DEBUG or NODEBUG as P1 to compile with or without debugger
-$! information.
-$!
-$! Specify which compiler at P2 to try to compile under.
-$!
-$! VAXC For VAX C.
-$! DECC For DEC C.
-$! GNUC For GNU C.
-$!
-$! If you don't specify a compiler, it will try to determine which
-$! "C" compiler to use.
-$!
-$! P3, if defined, sets a TCP/IP library to use, through one of the following
-$! keywords:
-$!
-$! UCX for UCX
-$! SOCKETSHR for SOCKETSHR+NETLIB
-$! TCPIP for TCPIP (post UCX)
-$!
-$! P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
-$!
-$! P5, if defined, sets a choice of programs to compile.
-$!
-$! For 64 bit architectures (Alpha and IA64), specify the pointer size as P6.
-$! For 32 bit architectures (VAX), P6 is ignored.
-$! Currently supported values are:
-$!
-$! 32 To ge a library compiled with /POINTER_SIZE=32
-$! 64 To ge a library compiled with /POINTER_SIZE=64
-$!
-$!
-$! Define A TCP/IP Library That We Will Need To Link To.
-$! (That Is, If We Need To Link To One.)
-$!
-$ TCPIP_LIB = ""
-$!
-$! Check What Architecture We Are Using.
-$!
-$ IF (F$GETSYI("CPU").LT.128)
-$ THEN
-$!
-$! The Architecture Is VAX.
-$!
-$ ARCH = "VAX"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! The Architecture Is Alpha, IA64 or whatever comes in the future.
-$!
-$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
-$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
-$!
-$! End The Architecture Check.
-$!
-$ ENDIF
-$!
-$! Define what programs should be compiled
-$!
-$ PROGRAMS := OPENSSL
-$!
-$! Define The CRYPTO Library.
-$!
-$ CRYPTO_LIB := SYS$DISK:[-.'ARCH'.EXE.CRYPTO]LIBCRYPTO'LIB32'.OLB
-$!
-$! Define The SSL Library.
-$!
-$ SSL_LIB := SYS$DISK:[-.'ARCH'.EXE.SSL]LIBSSL'LIB32'.OLB
-$!
-$! Define The OBJ Directory.
-$!
-$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.APPS]
-$!
-$! Define The EXE Directory.
-$!
-$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.APPS]
-$!
-$! Check To Make Sure We Have Valid Command Line Parameters.
-$!
-$ GOSUB CHECK_OPTIONS
-$!
-$! Initialise logical names and such
-$!
-$ GOSUB INITIALISE
-$!
-$! Tell The User What Kind of Machine We Run On.
-$!
-$ WRITE SYS$OUTPUT "Compiling On A ",ARCH," Machine."
-$!
-$! Check To See If The OBJ Directory Exists.
-$!
-$ IF (F$PARSE(OBJ_DIR).EQS."")
-$ THEN
-$!
-$! It Dosen't Exist, So Create It.
-$!
-$ CREATE/DIRECTORY 'OBJ_DIR'
-$!
-$! End The OBJ Directory Check.
-$!
-$ ENDIF
-$!
-$! Check To See If The EXE Directory Exists.
-$!
-$ IF (F$PARSE(EXE_DIR).EQS."")
-$ THEN
-$!
-$! It Dosen't Exist, So Create It.
-$!
-$ CREATE/DIRECTORY 'EXE_DIR'
-$!
-$! End The EXE Directory Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Have The Proper Libraries.
-$!
-$ GOSUB LIB_CHECK
-$!
-$! Check To See If We Have A Linker Option File.
-$!
-$ GOSUB CHECK_OPT_FILE
-$!
-$! Define The Application Files.
-$! NOTE: Some might think this list ugly. However, it's made this way to
-$! reflect the E_OBJ variable in Makefile as closely as possible, thereby
-$! making it fairly easy to verify that the lists are the same.
-$!
-$ LIB_OPENSSL = "VERIFY,ASN1PARS,REQ,DGST,DH,DHPARAM,ENC,PASSWD,GENDH,ERRSTR,"+-
- "CA,PKCS7,CRL2P7,CRL,"+-
- "RSA,RSAUTL,DSA,DSAPARAM,EC,ECPARAM,"+-
- "X509,GENRSA,GENDSA,GENPKEY,S_SERVER,S_CLIENT,SPEED,"+-
- "S_TIME,APPS,S_CB,S_SOCKET,APP_RAND,VERSION,SESS_ID,"+-
- "CIPHERS,NSEQ,PKCS12,PKCS8,PKEY,PKEYPARAM,PKEYUTL,"+ -
- "SPKAC,SMIME,CMS,RAND,ENGINE,OCSP,PRIME,TS"
-$ TCPIP_PROGRAMS = ",,"
-$ IF COMPILER .EQS. "VAXC" THEN -
- TCPIP_PROGRAMS = ",OPENSSL,"
-$!
-$! Setup exceptional compilations
-$!
-$ COMPILEWITH_CC2 = ",S_SOCKET,S_SERVER,S_CLIENT,"
-$!
-$ PHASE := LIB
-$!
-$ RESTART:
-$!
-$! Define An App Counter And Set It To "0".
-$!
-$ APP_COUNTER = 0
-$!
-$! Top Of The App Loop.
-$!
-$ NEXT_APP:
-$!
-$! Make The Application File Name
-$!
-$ CURRENT_APP = F$EDIT(F$ELEMENT(APP_COUNTER,",",PROGRAMS),"TRIM")
-$!
-$! Create The Executable File Name.
-$!
-$ EXE_FILE = EXE_DIR + CURRENT_APP + ".EXE"
-$!
-$! Check To See If We Are At The End Of The File List.
-$!
-$ IF (CURRENT_APP.EQS.",")
-$ THEN
-$ IF (PHASE.EQS."LIB")
-$ THEN
-$ PHASE := APP
-$ GOTO RESTART
-$ ELSE
-$ GOTO APP_DONE
-$ ENDIF
-$ ENDIF
-$!
-$! Increment The Counter.
-$!
-$ APP_COUNTER = APP_COUNTER + 1
-$!
-$! Decide if we're building the object files or not.
-$!
-$ IF (PHASE.EQS."LIB")
-$ THEN
-$!
-$! Define A Library File Counter And Set It To "-1".
-$! -1 Means The Application File Name Is To Be Used.
-$!
-$ LIB_COUNTER = -1
-$!
-$! Create a .OPT file for the object files
-$!
-$ OPEN/WRITE OBJECTS 'EXE_DIR''CURRENT_APP'.OPT
-$!
-$! Top Of The File Loop.
-$!
-$ NEXT_LIB:
-$!
-$! O.K, Extract The File Name From The File List.
-$!
-$ IF LIB_COUNTER .GE. 0
-$ THEN
-$ FILE_NAME = F$EDIT(F$ELEMENT(LIB_COUNTER,",",LIB_'CURRENT_APP'),"TRIM")
-$ ELSE
-$ FILE_NAME = CURRENT_APP
-$ ENDIF
-$!
-$! Check To See If We Are At The End Of The File List.
-$!
-$ IF (FILE_NAME.EQS.",")
-$ THEN
-$ CLOSE OBJECTS
-$ GOTO NEXT_APP
-$ ENDIF
-$!
-$! Increment The Counter.
-$!
-$ LIB_COUNTER = LIB_COUNTER + 1
-$!
-$! Create The Source File Name.
-$!
-$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
-$!
-$! Create The Object File Name.
-$!
-$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
-$ ON WARNING THEN GOTO NEXT_LIB
-$!
-$! Check To See If The File We Want To Compile Actually Exists.
-$!
-$ IF (F$SEARCH(SOURCE_FILE).EQS."")
-$ THEN
-$!
-$! Tell The User That The File Dosen't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ GOTO EXIT
-$!
-$! End The File Exist Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What We Are Building.
-$!
-$ IF (PHASE.EQS."LIB")
-$ THEN
-$ WRITE SYS$OUTPUT "Compiling The ",FILE_NAME,".C File."
-$ ELSE
-$ WRITE SYS$OUTPUT "Building The ",FILE_NAME," Application Program."
-$ ENDIF
-$!
-$! Compile The File.
-$!
-$ ON ERROR THEN GOTO NEXT_LIB
-$ IF COMPILEWITH_CC2 - FILE_NAME .NES. COMPILEWITH_CC2
-$ THEN
-$ CC2/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ELSE
-$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ENDIF
-$ WRITE OBJECTS OBJECT_FILE
-$!
-$ GOTO NEXT_LIB
-$ ENDIF
-$!
-$! Check if this program works well without a TCPIP library
-$!
-$ IF TCPIP_LIB .EQS. "" .AND. TCPIP_PROGRAMS - CURRENT_APP .NES. TCPIP_PROGRAMS
-$ THEN
-$ WRITE SYS$OUTPUT CURRENT_APP," needs a TCP/IP library. Can't link. Skipping..."
-$ GOTO NEXT_APP
-$ ENDIF
-$!
-$! Link The Program.
-$! Check To See If We Are To Link With A Specific TCP/IP Library.
-$!
-$ ON WARNING THEN GOTO NEXT_APP
-$!
-$ IF (TCPIP_LIB.NES."")
-$ THEN
-$!
-$! Don't Link With The RSAREF Routines And TCP/IP Library.
-$!
-$ LINK/'DEBUGGER'/'TRACEBACK' /EXE='EXE_FILE' -
- 'EXE_DIR''CURRENT_APP'.OPT/OPTION, -
- 'SSL_LIB'/LIBRARY,'CRYPTO_LIB'/LIBRARY, -
- 'TCPIP_LIB','OPT_FILE'/OPTION
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Don't Link With The RSAREF Routines And Link With A TCP/IP Library.
-$!
-$ LINK/'DEBUGGER'/'TRACEBACK' /EXE='EXE_FILE' -
- 'EXE_DIR''CURRENT_APP'.OPT/OPTION, -
- 'SSL_LIB'/LIBRARY,'CRYPTO_LIB'/LIBRARY, -
- 'OPT_FILE'/OPTION
-$!
-$! End The TCP/IP Library Check.
-$!
-$ ENDIF
-$!
-$! Go Back And Do It Again.
-$!
-$ GOTO NEXT_APP
-$!
-$! All Done With This File.
-$!
-$ APP_DONE:
-$ EXIT:
-$!
-$! All Done, Time To Clean Up And Exit.
-$!
-$ GOSUB CLEANUP
-$ EXIT
-$!
-$! Check For The Link Option FIle.
-$!
-$ CHECK_OPT_FILE:
-$!
-$! Check To See If We Need To Make A VAX C Option File.
-$!
-$ IF (COMPILER.EQS."VAXC")
-$ THEN
-$!
-$! Check To See If We Already Have A VAX C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A VAX C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable VAX C Runtime Library.
-!
-SYS$SHARE:VAXCRTL.EXE/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The VAXC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A GNU C Option File.
-$!
-$ IF (COMPILER.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If We Already Have A GNU C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A GNU C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable C Runtime Library.
-!
-GNU_CC:[000000]GCCLIB/LIBRARY
-SYS$SHARE:VAXCRTL/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A DEC C Option File.
-$!
-$ IF (COMPILER.EQS."DECC")
-$ THEN
-$!
-$! Check To See If We Already Have A DEC C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! Figure Out If We Need An AXP Or A VAX Linker Option File.
-$!
-$ IF ARCH.EQS."VAX"
-$ THEN
-$!
-$! We Need A DEC C Linker Option File For VAX.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable DEC C Runtime Library.
-!
-SYS$SHARE:DECC$SHR.EXE/SHARE
-$EOD
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Create The non-VAX Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File For non-VAX To Link Agianst
-! The Sharable C Runtime Library.
-!
-SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
-SYS$SHARE:CMA$OPEN_RTL/SHARE
-$EOD
-$!
-$! End The DEC C Option File Check.
-$!
-$ ENDIF
-$!
-$! End The Option File Search.
-$!
-$ ENDIF
-$!
-$! End The DEC C Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What Linker Option File We Are Using.
-$!
-$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
-$!
-$! Time To RETURN.
-$!
-$ RETURN
-$!
-$! Check To See If We Have The Appropiate Libraries.
-$!
-$ LIB_CHECK:
-$!
-$! Look For The Library LIBCRYPTO.OLB.
-$!
-$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
-$ THEN
-$!
-$! Tell The User We Can't Find The LIBCRYPTO.OLB Library.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
-$ WRITE SYS$OUTPUT "We Can't Link Without It."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Since We Can't Link Without It, Exit.
-$!
-$ EXIT
-$!
-$! End The Crypto Library Check.
-$!
-$ ENDIF
-$!
-$! Look For The Library LIBSSL.OLB.
-$!
-$ IF (F$SEARCH(SSL_LIB).EQS."")
-$ THEN
-$!
-$! Tell The User We Can't Find The LIBSSL.OLB Library.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
-$ WRITE SYS$OUTPUT "Some Of The Test Programs Need To Link To It."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Since We Can't Link Without It, Exit.
-$!
-$ EXIT
-$!
-$! End The SSL Library Check.
-$!
-$ ENDIF
-$!
-$! Time To Return.
-$!
-$ RETURN
-$!
-$! Check The User's Options.
-$!
-$ CHECK_OPTIONS:
-$!
-$! Check To See If P1 Is Blank.
-$!
-$ IF (P1.EQS."NODEBUG")
-$ THEN
-$!
-$! P1 Is NODEBUG, So Compile Without Debugger Information.
-$!
-$ DEBUGGER = "NODEBUG"
-$ TRACEBACK = "NOTRACEBACK"
-$ GCC_OPTIMIZE = "OPTIMIZE"
-$ CC_OPTIMIZE = "OPTIMIZE"
-$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Check To See If We Are To Compile With Debugger Information.
-$!
-$ IF (P1.EQS."DEBUG")
-$ THEN
-$!
-$! Compile With Debugger Information.
-$!
-$ DEBUGGER = "DEBUG"
-$ TRACEBACK = "TRACEBACK"
-$ GCC_OPTIMIZE = "NOOPTIMIZE"
-$ CC_OPTIMIZE = "NOOPTIMIZE"
-$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
-$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P1 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P6 Is Blank.
-$!
-$ IF (P6.EQS."")
-$ THEN
-$ POINTER_SIZE = ""
-$ ELSE
-$!
-$! Check is P6 Is Valid
-$!
-$ IF (P6.EQS."32")
-$ THEN
-$ POINTER_SIZE = "/POINTER_SIZE=32"
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ LIB32 = ""
-$ ELSE
-$ LIB32 = "32"
-$ ENDIF
-$ ELSE
-$ IF (P6.EQS."64")
-$ THEN
-$ LIB32 = ""
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ POINTER_SIZE = "/POINTER_SIZE=32"
-$ ELSE
-$ POINTER_SIZE = "/POINTER_SIZE=64"
-$ ENDIF
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P6," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " 32 : Compile with 32 bit pointer size"
-$ WRITE SYS$OUTPUT " 64 : Compile with 64 bit pointer size"
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ GOTO TIDY
-$!
-$! End The Valid Arguement Check.
-$!
-$ ENDIF
-$ ENDIF
-$!
-$! End The P6 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P2 Is Blank.
-$!
-$ IF (P2.EQS."")
-$ THEN
-$!
-$! O.K., The User Didn't Specify A Compiler, Let's Try To
-$! Find Out Which One To Use.
-$!
-$! Check To See If We Have GNU C.
-$!
-$ IF (F$TRNLNM("GNU_CC").NES."")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ P2 = "GNUC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Check To See If We Have VAXC Or DECC.
-$!
-$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ P2 = "DECC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ P2 = "VAXC"
-$!
-$! End The VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The DECC & VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The Compiler Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Have A Option For P3.
-$!
-$ IF (P3.EQS."")
-$ THEN
-$!
-$! Find out what socket library we have available
-$!
-$ IF F$PARSE("SOCKETSHR:") .NES. ""
-$ THEN
-$!
-$! We have SOCKETSHR, and it is my opinion that it's the best to use.
-$!
-$ P3 = "SOCKETSHR"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
-$!
-$! Else, let's look for something else
-$!
-$ ELSE
-$!
-$! Like UCX (the reason to do this before Multinet is that the UCX
-$! emulation is easier to use...)
-$!
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
- .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
- .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
-$ THEN
-$!
-$! Last resort: a UCX or UCX-compatible library
-$!
-$ P3 = "UCX"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
-$!
-$! That was all...
-$!
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$!
-$! Set Up Initial CC Definitions, Possibly With User Ones
-$!
-$ CCDEFS = "MONOLITH"
-$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
-$ CCEXTRAFLAGS = ""
-$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
-$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
-$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
- CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
-$!
-$! Check To See If The User Entered A Valid Paramter.
-$!
-$ IF (P2.EQS."VAXC").OR.(P2.EQS."DECC").OR.(P2.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If The User Wanted DECC.
-$!
-$ IF (P2.EQS."DECC")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ COMPILER = "DECC"
-$!
-$! Tell The User We Are Using DECC.
-$!
-$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
-$!
-$! Use DECC...
-$!
-$ CC = "CC"
-$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
- THEN CC = "CC/DECC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89''POINTER_SIZE'" + -
- "/NOLIST/PREFIX=ALL" + -
- "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
-$!
-$! End DECC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use VAXC.
-$!
-$ IF (P2.EQS."VAXC")
-$ THEN
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ COMPILER = "VAXC"
-$!
-$! Tell The User We Are Using VAX C.
-$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
-$!
-$! Compile Using VAXC.
-$!
-$ CC = "CC"
-$ IF ARCH.NES."VAX"
-$ THEN
-$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
-$ EXIT
-$ ENDIF
-$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
-$ CCDEFS = CCDEFS + ",""VAXC"""
-$!
-$! Define <sys> As SYS$COMMON:[SYSLIB]
-$!
-$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
-$!
-$! End VAXC Check
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use GNU C.
-$!
-$ IF (P2.EQS."GNUC")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ COMPILER = "GNUC"
-$!
-$! Tell The User We Are Using GNUC.
-$!
-$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
-$!
-$! Use GNU C...
-$!
-$ IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC
-$ CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Set up default defines
-$!
-$ CCDEFS = """FLAT_INC=1""," + CCDEFS
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
-$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
-$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$ ENDIF
-$!
-$! Time to check the contents, and to make sure we get the correct library.
-$!
-$ IF P3.EQS."SOCKETSHR" .OR. P3.EQS."MULTINET" .OR. P3.EQS."UCX" -
- .OR. P3.EQS."TCPIP" .OR. P3.EQS."NONE"
-$ THEN
-$!
-$! Check to see if SOCKETSHR was chosen
-$!
-$ IF P3.EQS."SOCKETSHR"
-$ THEN
-$!
-$! Set the library to use SOCKETSHR
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT"
-$!
-$! Done with SOCKETSHR
-$!
-$ ENDIF
-$!
-$! Check to see if MULTINET was chosen
-$!
-$ IF P3.EQS."MULTINET"
-$ THEN
-$!
-$! Set the library to use UCX emulation.
-$!
-$ P3 = "UCX"
-$!
-$! Done with MULTINET
-$!
-$ ENDIF
-$!
-$! Check to see if UCX was chosen
-$!
-$ IF P3.EQS."UCX"
-$ THEN
-$!
-$! Set the library to use UCX.
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT"
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
-$ THEN
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT/OPT"
-$ ELSE
-$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
- TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT/OPT"
-$ ENDIF
-$!
-$! Done with UCX
-$!
-$ ENDIF
-$!
-$! Check to see if TCPIP (post UCX) was chosen
-$!
-$ IF P3.EQS."TCPIP"
-$ THEN
-$!
-$! Set the library to use TCPIP.
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT"
-$!
-$! Done with TCPIP
-$!
-$ ENDIF
-$!
-$! Check to see if NONE was chosen
-$!
-$ IF P3.EQS."NONE"
-$ THEN
-$!
-$! Do not use TCPIP.
-$!
-$ TCPIP_LIB = ""
-$!
-$! Done with TCPIP
-$!
-$ ENDIF
-$!
-$! Add TCP/IP type to CC definitions.
-$!
-$ CCDEFS = CCDEFS + ",TCPIP_TYPE_''P3'"
-$!
-$! Print info
-$!
-$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
-$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
-$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! Done with TCP/IP libraries
-$!
-$ ENDIF
-$!
-$! Finish up the definition of CC.
-$!
-$ IF COMPILER .EQS. "DECC"
-$ THEN
-$ IF CCDISABLEWARNINGS .NES. ""
-$ THEN
-$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
-$ ENDIF
-$ ELSE
-$ CCDISABLEWARNINGS = ""
-$ ENDIF
-$ CC2 = CC + "/DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS
-$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
-$!
-$! Show user the result
-$!
-$ WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC
-$!
-$! Special Threads For OpenVMS v7.1 Or Later
-$!
-$! Written By: Richard Levitte
-$! richard@levitte.org
-$!
-$!
-$! Check To See If We Have A Option For P4.
-$!
-$ IF (P4.EQS."")
-$ THEN
-$!
-$! Get The Version Of VMS We Are Using.
-$!
-$ ISSEVEN :=
-$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
-$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
-$!
-$! Check To See If The VMS Version Is v7.1 Or Later.
-$!
-$ IF (TMP.GE.71)
-$ THEN
-$!
-$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
-$!
-$ ISSEVEN := ,PTHREAD_USE_D4
-$!
-$! End The VMS Version Check.
-$!
-$ ENDIF
-$!
-$! End The P4 Check.
-$!
-$ ENDIF
-$!
-$! Check if the user wanted to compile just a subset of all the programs.
-$!
-$ IF P5 .NES. ""
-$ THEN
-$ PROGRAMS = P5
-$ ENDIF
-$!
-$! Time To RETURN...
-$!
-$ RETURN
-$!
-$ INITIALISE:
-$!
-$! Save old value of the logical name OPENSSL
-$!
-$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
-$!
-$! Save directory information
-$!
-$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
-$ __HERE = F$EDIT(__HERE,"UPCASE")
-$ __TOP = __HERE - "APPS]"
-$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
-$!
-$! Set up the logical name OPENSSL to point at the include directory
-$!
-$ DEFINE OPENSSL/NOLOG '__INCLUDE'
-$!
-$! Done
-$!
-$ RETURN
-$!
-$ CLEANUP:
-$!
-$! Restore the logical name OPENSSL if it had a value
-$!
-$ IF __SAVE_OPENSSL .EQS. ""
-$ THEN
-$ DEASSIGN OPENSSL
-$ ELSE
-$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
-$ ENDIF
-$!
-$! Done
-$!
-$ RETURN
+$!
+$! MAKEAPPS.COM
+$! Written By: Robert Byer
+$! Vice-President
+$! A-Com Computing, Inc.
+$! byer@mail.all-net.net
+$!
+$! Changes by Richard Levitte <richard@levitte.org>
+$! Zoltan Arpadffy <zoli@polarhome.com>
+$!
+$! This command files compiles and creates all the various different
+$! "application" programs for the different types of encryption for OpenSSL.
+$! The EXE's are placed in the directory [.xxx.EXE.APPS] where "xxx" denotes
+$! ALPHA, IA64 or VAX, depending on your machine architecture.
+$!
+$! It was written so it would try to determine what "C" compiler to
+$! use or you can specify which "C" compiler to use.
+$!
+$! Specify DEBUG or NODEBUG as P1 to compile with or without debugger
+$! information.
+$!
+$! Specify which compiler at P2 to try to compile under.
+$!
+$! VAXC For VAX C.
+$! DECC For DEC C.
+$! GNUC For GNU C.
+$!
+$! If you don't specify a compiler, it will try to determine which
+$! "C" compiler to use.
+$!
+$! P3, if defined, sets a TCP/IP library to use, through one of the following
+$! keywords:
+$!
+$! UCX for UCX
+$! SOCKETSHR for SOCKETSHR+NETLIB
+$! TCPIP for TCPIP (post UCX)
+$!
+$! P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$! P5, if defined, sets a choice of programs to compile.
+$!
+$! For 64 bit architectures (Alpha and IA64), specify the pointer size as P6.
+$! For 32 bit architectures (VAX), P6 is ignored.
+$! Currently supported values are:
+$!
+$! 32 To ge a library compiled with /POINTER_SIZE=32
+$! 64 To ge a library compiled with /POINTER_SIZE=64
+$!
+$!
+$! Define A TCP/IP Library That We Will Need To Link To.
+$! (That Is, If We Need To Link To One.)
+$!
+$ TCPIP_LIB = ""
+$!
+$! Check What Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$! The Architecture Is VAX.
+$!
+$ ARCH = "VAX"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$! Define what programs should be compiled
+$!
+$ PROGRAMS := OPENSSL
+$!
+$! Define The CRYPTO Library.
+$!
+$ CRYPTO_LIB := SYS$DISK:[-.'ARCH'.EXE.CRYPTO]LIBCRYPTO'LIB32'.OLB
+$!
+$! Define The SSL Library.
+$!
+$ SSL_LIB := SYS$DISK:[-.'ARCH'.EXE.SSL]LIBSSL'LIB32'.OLB
+$!
+$! Define The OBJ Directory.
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.APPS]
+$!
+$! Define The EXE Directory.
+$!
+$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.APPS]
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Initialise logical names and such
+$!
+$ GOSUB INITIALISE
+$!
+$! Tell The User What Kind of Machine We Run On.
+$!
+$ WRITE SYS$OUTPUT "Compiling On A ",ARCH," Machine."
+$!
+$! Check To See If The OBJ Directory Exists.
+$!
+$ IF (F$PARSE(OBJ_DIR).EQS."")
+$ THEN
+$!
+$! It Dosen't Exist, So Create It.
+$!
+$ CREATE/DIRECTORY 'OBJ_DIR'
+$!
+$! End The OBJ Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If The EXE Directory Exists.
+$!
+$ IF (F$PARSE(EXE_DIR).EQS."")
+$ THEN
+$!
+$! It Dosen't Exist, So Create It.
+$!
+$ CREATE/DIRECTORY 'EXE_DIR'
+$!
+$! End The EXE Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Define The Application Files.
+$! NOTE: Some might think this list ugly. However, it's made this way to
+$! reflect the E_OBJ variable in Makefile as closely as possible, thereby
+$! making it fairly easy to verify that the lists are the same.
+$!
+$ LIB_OPENSSL = "VERIFY,ASN1PARS,REQ,DGST,DH,DHPARAM,ENC,PASSWD,GENDH,ERRSTR,"+-
+ "CA,PKCS7,CRL2P7,CRL,"+-
+ "RSA,RSAUTL,DSA,DSAPARAM,EC,ECPARAM,"+-
+ "X509,GENRSA,GENDSA,GENPKEY,S_SERVER,S_CLIENT,SPEED,"+-
+ "S_TIME,APPS,S_CB,S_SOCKET,APP_RAND,VERSION,SESS_ID,"+-
+ "CIPHERS,NSEQ,PKCS12,PKCS8,PKEY,PKEYPARAM,PKEYUTL,"+ -
+ "SPKAC,SMIME,CMS,RAND,ENGINE,OCSP,PRIME,TS"
+$ TCPIP_PROGRAMS = ",,"
+$ IF COMPILER .EQS. "VAXC" THEN -
+ TCPIP_PROGRAMS = ",OPENSSL,"
+$!
+$! Setup exceptional compilations
+$!
+$ COMPILEWITH_CC2 = ",S_SOCKET,S_SERVER,S_CLIENT,"
+$!
+$ PHASE := LIB
+$!
+$ RESTART:
+$!
+$! Define An App Counter And Set It To "0".
+$!
+$ APP_COUNTER = 0
+$!
+$! Top Of The App Loop.
+$!
+$ NEXT_APP:
+$!
+$! Make The Application File Name
+$!
+$ CURRENT_APP = F$EDIT(F$ELEMENT(APP_COUNTER,",",PROGRAMS),"TRIM")
+$!
+$! Create The Executable File Name.
+$!
+$ EXE_FILE = EXE_DIR + CURRENT_APP + ".EXE"
+$!
+$! Check To See If We Are At The End Of The File List.
+$!
+$ IF (CURRENT_APP.EQS.",")
+$ THEN
+$ IF (PHASE.EQS."LIB")
+$ THEN
+$ PHASE := APP
+$ GOTO RESTART
+$ ELSE
+$ GOTO APP_DONE
+$ ENDIF
+$ ENDIF
+$!
+$! Increment The Counter.
+$!
+$ APP_COUNTER = APP_COUNTER + 1
+$!
+$! Decide if we're building the object files or not.
+$!
+$ IF (PHASE.EQS."LIB")
+$ THEN
+$!
+$! Define A Library File Counter And Set It To "-1".
+$! -1 Means The Application File Name Is To Be Used.
+$!
+$ LIB_COUNTER = -1
+$!
+$! Create a .OPT file for the object files
+$!
+$ OPEN/WRITE OBJECTS 'EXE_DIR''CURRENT_APP'.OPT
+$!
+$! Top Of The File Loop.
+$!
+$ NEXT_LIB:
+$!
+$! O.K, Extract The File Name From The File List.
+$!
+$ IF LIB_COUNTER .GE. 0
+$ THEN
+$ FILE_NAME = F$EDIT(F$ELEMENT(LIB_COUNTER,",",LIB_'CURRENT_APP'),"TRIM")
+$ ELSE
+$ FILE_NAME = CURRENT_APP
+$ ENDIF
+$!
+$! Check To See If We Are At The End Of The File List.
+$!
+$ IF (FILE_NAME.EQS.",")
+$ THEN
+$ CLOSE OBJECTS
+$ GOTO NEXT_APP
+$ ENDIF
+$!
+$! Increment The Counter.
+$!
+$ LIB_COUNTER = LIB_COUNTER + 1
+$!
+$! Create The Source File Name.
+$!
+$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
+$!
+$! Create The Object File Name.
+$!
+$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
+$ ON WARNING THEN GOTO NEXT_LIB
+$!
+$! Check To See If The File We Want To Compile Actually Exists.
+$!
+$ IF (F$SEARCH(SOURCE_FILE).EQS."")
+$ THEN
+$!
+$! Tell The User That The File Dosen't Exist.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Exit The Build.
+$!
+$ GOTO EXIT
+$!
+$! End The File Exist Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What We Are Building.
+$!
+$ IF (PHASE.EQS."LIB")
+$ THEN
+$ WRITE SYS$OUTPUT "Compiling The ",FILE_NAME,".C File."
+$ ELSE
+$ WRITE SYS$OUTPUT "Building The ",FILE_NAME," Application Program."
+$ ENDIF
+$!
+$! Compile The File.
+$!
+$ ON ERROR THEN GOTO NEXT_LIB
+$ IF COMPILEWITH_CC2 - FILE_NAME .NES. COMPILEWITH_CC2
+$ THEN
+$ CC2/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ELSE
+$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ENDIF
+$ WRITE OBJECTS OBJECT_FILE
+$!
+$ GOTO NEXT_LIB
+$ ENDIF
+$!
+$! Check if this program works well without a TCPIP library
+$!
+$ IF TCPIP_LIB .EQS. "" .AND. TCPIP_PROGRAMS - CURRENT_APP .NES. TCPIP_PROGRAMS
+$ THEN
+$ WRITE SYS$OUTPUT CURRENT_APP," needs a TCP/IP library. Can't link. Skipping..."
+$ GOTO NEXT_APP
+$ ENDIF
+$!
+$! Link The Program.
+$! Check To See If We Are To Link With A Specific TCP/IP Library.
+$!
+$ ON WARNING THEN GOTO NEXT_APP
+$!
+$ IF (TCPIP_LIB.NES."")
+$ THEN
+$!
+$! Don't Link With The RSAREF Routines And TCP/IP Library.
+$!
+$ LINK/'DEBUGGER'/'TRACEBACK' /EXE='EXE_FILE' -
+ 'EXE_DIR''CURRENT_APP'.OPT/OPTION, -
+ 'SSL_LIB'/LIBRARY,'CRYPTO_LIB'/LIBRARY, -
+ 'TCPIP_LIB','OPT_FILE'/OPTION
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Don't Link With The RSAREF Routines And Link With A TCP/IP Library.
+$!
+$ LINK/'DEBUGGER'/'TRACEBACK' /EXE='EXE_FILE' -
+ 'EXE_DIR''CURRENT_APP'.OPT/OPTION, -
+ 'SSL_LIB'/LIBRARY,'CRYPTO_LIB'/LIBRARY, -
+ 'OPT_FILE'/OPTION
+$!
+$! End The TCP/IP Library Check.
+$!
+$ ENDIF
+$!
+$! Go Back And Do It Again.
+$!
+$ GOTO NEXT_APP
+$!
+$! All Done With This File.
+$!
+$ APP_DONE:
+$ EXIT:
+$!
+$! All Done, Time To Clean Up And Exit.
+$!
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$! Check To See If We Already Have A VAX C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A VAX C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE/SHARE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If We Already Have A GNU C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A GNU C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB/LIBRARY
+SYS$SHARE:VAXCRTL/SHARE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$! Check To See If We Already Have A DEC C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! Figure Out If We Need An AXP Or A VAX Linker Option File.
+$!
+$ IF ARCH.EQS."VAX"
+$ THEN
+$!
+$! We Need A DEC C Linker Option File For VAX.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE/SHARE
+$EOD
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Create The non-VAX Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Agianst
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
+SYS$SHARE:CMA$OPEN_RTL/SHARE
+$EOD
+$!
+$! End The DEC C Option File Check.
+$!
+$ ENDIF
+$!
+$! End The Option File Search.
+$!
+$ ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check To See If We Have The Appropiate Libraries.
+$!
+$ LIB_CHECK:
+$!
+$! Look For The Library LIBCRYPTO.OLB.
+$!
+$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
+$ THEN
+$!
+$! Tell The User We Can't Find The LIBCRYPTO.OLB Library.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
+$ WRITE SYS$OUTPUT "We Can't Link Without It."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Since We Can't Link Without It, Exit.
+$!
+$ EXIT
+$!
+$! End The Crypto Library Check.
+$!
+$ ENDIF
+$!
+$! Look For The Library LIBSSL.OLB.
+$!
+$ IF (F$SEARCH(SSL_LIB).EQS."")
+$ THEN
+$!
+$! Tell The User We Can't Find The LIBSSL.OLB Library.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
+$ WRITE SYS$OUTPUT "Some Of The Test Programs Need To Link To It."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Since We Can't Link Without It, Exit.
+$!
+$ EXIT
+$!
+$! End The SSL Library Check.
+$!
+$ ENDIF
+$!
+$! Time To Return.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."NODEBUG")
+$ THEN
+$!
+$! P1 Is NODEBUG, So Compile Without Debugger Information.
+$!
+$ DEBUGGER = "NODEBUG"
+$ TRACEBACK = "NOTRACEBACK"
+$ GCC_OPTIMIZE = "OPTIMIZE"
+$ CC_OPTIMIZE = "OPTIMIZE"
+$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Check To See If We Are To Compile With Debugger Information.
+$!
+$ IF (P1.EQS."DEBUG")
+$ THEN
+$!
+$! Compile With Debugger Information.
+$!
+$ DEBUGGER = "DEBUG"
+$ TRACEBACK = "TRACEBACK"
+$ GCC_OPTIMIZE = "NOOPTIMIZE"
+$ CC_OPTIMIZE = "NOOPTIMIZE"
+$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
+$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P6 Is Blank.
+$!
+$ IF (P6.EQS."")
+$ THEN
+$ POINTER_SIZE = ""
+$ ELSE
+$!
+$! Check is P6 Is Valid
+$!
+$ IF (P6.EQS."32")
+$ THEN
+$ POINTER_SIZE = "/POINTER_SIZE=32"
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ LIB32 = ""
+$ ELSE
+$ LIB32 = "32"
+$ ENDIF
+$ ELSE
+$ IF (P6.EQS."64")
+$ THEN
+$ LIB32 = ""
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ POINTER_SIZE = "/POINTER_SIZE=32"
+$ ELSE
+$ POINTER_SIZE = "/POINTER_SIZE=64"
+$ ENDIF
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P6," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " 32 : Compile with 32 bit pointer size"
+$ WRITE SYS$OUTPUT " 64 : Compile with 64 bit pointer size"
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ GOTO TIDY
+$!
+$! End The Valid Arguement Check.
+$!
+$ ENDIF
+$ ENDIF
+$!
+$! End The P6 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P2 Is Blank.
+$!
+$ IF (P2.EQS."")
+$ THEN
+$!
+$! O.K., The User Didn't Specify A Compiler, Let's Try To
+$! Find Out Which One To Use.
+$!
+$! Check To See If We Have GNU C.
+$!
+$ IF (F$TRNLNM("GNU_CC").NES."")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ P2 = "GNUC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Check To See If We Have VAXC Or DECC.
+$!
+$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ P2 = "DECC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ P2 = "VAXC"
+$!
+$! End The VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The DECC & VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For P3.
+$!
+$ IF (P3.EQS."")
+$ THEN
+$!
+$! Find out what socket library we have available
+$!
+$ IF F$PARSE("SOCKETSHR:") .NES. ""
+$ THEN
+$!
+$! We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$ P3 = "SOCKETSHR"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$! Else, let's look for something else
+$!
+$ ELSE
+$!
+$! Like UCX (the reason to do this before Multinet is that the UCX
+$! emulation is easier to use...)
+$!
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+ .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+ .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$ THEN
+$!
+$! Last resort: a UCX or UCX-compatible library
+$!
+$ P3 = "UCX"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$! That was all...
+$!
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "MONOLITH"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+ CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If The User Entered A Valid Paramter.
+$!
+$ IF (P2.EQS."VAXC").OR.(P2.EQS."DECC").OR.(P2.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If The User Wanted DECC.
+$!
+$ IF (P2.EQS."DECC")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ COMPILER = "DECC"
+$!
+$! Tell The User We Are Using DECC.
+$!
+$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$! Use DECC...
+$!
+$ CC = "CC"
+$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+ THEN CC = "CC/DECC"
+$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89''POINTER_SIZE'" + -
+ "/NOLIST/PREFIX=ALL" + -
+ "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
+$!
+$! End DECC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use VAXC.
+$!
+$ IF (P2.EQS."VAXC")
+$ THEN
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ COMPILER = "VAXC"
+$!
+$! Tell The User We Are Using VAX C.
+$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$! Compile Using VAXC.
+$!
+$ CC = "CC"
+$ IF ARCH.NES."VAX"
+$ THEN
+$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
+$ EXIT
+$ ENDIF
+$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
+$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
+$ CCDEFS = CCDEFS + ",""VAXC"""
+$!
+$! Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
+$!
+$! End VAXC Check
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use GNU C.
+$!
+$ IF (P2.EQS."GNUC")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ COMPILER = "GNUC"
+$!
+$! Tell The User We Are Using GNUC.
+$!
+$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$! Use GNU C...
+$!
+$ IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC
+$ CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Set up default defines
+$!
+$ CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
+$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
+$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$ ENDIF
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF P3.EQS."SOCKETSHR" .OR. P3.EQS."MULTINET" .OR. P3.EQS."UCX" -
+ .OR. P3.EQS."TCPIP" .OR. P3.EQS."NONE"
+$ THEN
+$!
+$! Check to see if SOCKETSHR was chosen
+$!
+$ IF P3.EQS."SOCKETSHR"
+$ THEN
+$!
+$! Set the library to use SOCKETSHR
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT"
+$!
+$! Done with SOCKETSHR
+$!
+$ ENDIF
+$!
+$! Check to see if MULTINET was chosen
+$!
+$ IF P3.EQS."MULTINET"
+$ THEN
+$!
+$! Set the library to use UCX emulation.
+$!
+$ P3 = "UCX"
+$!
+$! Done with MULTINET
+$!
+$ ENDIF
+$!
+$! Check to see if UCX was chosen
+$!
+$ IF P3.EQS."UCX"
+$ THEN
+$!
+$! Set the library to use UCX.
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT"
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$ THEN
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT/OPT"
+$ ELSE
+$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT/OPT"
+$ ENDIF
+$!
+$! Done with UCX
+$!
+$ ENDIF
+$!
+$! Check to see if TCPIP (post UCX) was chosen
+$!
+$ IF P3.EQS."TCPIP"
+$ THEN
+$!
+$! Set the library to use TCPIP.
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT"
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Check to see if NONE was chosen
+$!
+$ IF P3.EQS."NONE"
+$ THEN
+$!
+$! Do not use TCPIP.
+$!
+$ TCPIP_LIB = ""
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Add TCP/IP type to CC definitions.
+$!
+$ CCDEFS = CCDEFS + ",TCPIP_TYPE_''P3'"
+$!
+$! Print info
+$!
+$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
+$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
+$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Finish up the definition of CC.
+$!
+$ IF COMPILER .EQS. "DECC"
+$ THEN
+$ IF CCDISABLEWARNINGS .NES. ""
+$ THEN
+$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$ ENDIF
+$ ELSE
+$ CCDISABLEWARNINGS = ""
+$ ENDIF
+$ CC2 = CC + "/DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS
+$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$!
+$! Show user the result
+$!
+$ WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By: Richard Levitte
+$! richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P4.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$! Get The Version Of VMS We Are Using.
+$!
+$ ISSEVEN :=
+$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$! Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$ IF (TMP.GE.71)
+$ THEN
+$!
+$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$ ISSEVEN := ,PTHREAD_USE_D4
+$!
+$! End The VMS Version Check.
+$!
+$ ENDIF
+$!
+$! End The P4 Check.
+$!
+$ ENDIF
+$!
+$! Check if the user wanted to compile just a subset of all the programs.
+$!
+$ IF P5 .NES. ""
+$ THEN
+$ PROGRAMS = P5
+$ ENDIF
+$!
+$! Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "APPS]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL/NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the logical name OPENSSL if it had a value
+$!
+$ IF __SAVE_OPENSSL .EQS. ""
+$ THEN
+$ DEASSIGN OPENSSL
+$ ELSE
+$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
+$ ENDIF
+$!
+$! Done
+$!
+$ RETURN
diff --git a/openssl/crypto/asn1/a_strex.c b/openssl/crypto/asn1/a_strex.c
index d9172e055..264ebf239 100644
--- a/openssl/crypto/asn1/a_strex.c
+++ b/openssl/crypto/asn1/a_strex.c
@@ -1,574 +1,574 @@
-/* a_strex.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2000.
- */
-/* ====================================================================
- * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "cryptlib.h"
-#include <openssl/crypto.h>
-#include <openssl/x509.h>
-#include <openssl/asn1.h>
-
-#include "charmap.h"
-
-/* ASN1_STRING_print_ex() and X509_NAME_print_ex().
- * Enhanced string and name printing routines handling
- * multibyte characters, RFC2253 and a host of other
- * options.
- */
-
-
-#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
-
-#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
- ASN1_STRFLGS_ESC_QUOTE | \
- ASN1_STRFLGS_ESC_CTRL | \
- ASN1_STRFLGS_ESC_MSB)
-
-
-/* Three IO functions for sending data to memory, a BIO and
- * and a FILE pointer.
- */
-#if 0 /* never used */
-static int send_mem_chars(void *arg, const void *buf, int len)
-{
- unsigned char **out = arg;
- if(!out) return 1;
- memcpy(*out, buf, len);
- *out += len;
- return 1;
-}
-#endif
-
-static int send_bio_chars(void *arg, const void *buf, int len)
-{
- if(!arg) return 1;
- if(BIO_write(arg, buf, len) != len) return 0;
- return 1;
-}
-
-static int send_fp_chars(void *arg, const void *buf, int len)
-{
- if(!arg) return 1;
- if(fwrite(buf, 1, len, arg) != (unsigned int)len) return 0;
- return 1;
-}
-
-typedef int char_io(void *arg, const void *buf, int len);
-
-/* This function handles display of
- * strings, one character at a time.
- * It is passed an unsigned long for each
- * character because it could come from 2 or even
- * 4 byte forms.
- */
-
-static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, char_io *io_ch, void *arg)
-{
- unsigned char chflgs, chtmp;
- char tmphex[HEX_SIZE(long)+3];
-
- if(c > 0xffffffffL)
- return -1;
- if(c > 0xffff) {
- BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
- if(!io_ch(arg, tmphex, 10)) return -1;
- return 10;
- }
- if(c > 0xff) {
- BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
- if(!io_ch(arg, tmphex, 6)) return -1;
- return 6;
- }
- chtmp = (unsigned char)c;
- if(chtmp > 0x7f) chflgs = flags & ASN1_STRFLGS_ESC_MSB;
- else chflgs = char_type[chtmp] & flags;
- if(chflgs & CHARTYPE_BS_ESC) {
- /* If we don't escape with quotes, signal we need quotes */
- if(chflgs & ASN1_STRFLGS_ESC_QUOTE) {
- if(do_quotes) *do_quotes = 1;
- if(!io_ch(arg, &chtmp, 1)) return -1;
- return 1;
- }
- if(!io_ch(arg, "\\", 1)) return -1;
- if(!io_ch(arg, &chtmp, 1)) return -1;
- return 2;
- }
- if(chflgs & (ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB)) {
- BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
- if(!io_ch(arg, tmphex, 3)) return -1;
- return 3;
- }
- /* If we get this far and do any escaping at all must escape
- * the escape character itself: backslash.
- */
- if (chtmp == '\\' && flags & ESC_FLAGS) {
- if(!io_ch(arg, "\\\\", 2)) return -1;
- return 2;
- }
- if(!io_ch(arg, &chtmp, 1)) return -1;
- return 1;
-}
-
-#define BUF_TYPE_WIDTH_MASK 0x7
-#define BUF_TYPE_CONVUTF8 0x8
-
-/* This function sends each character in a buffer to
- * do_esc_char(). It interprets the content formats
- * and converts to or from UTF8 as appropriate.
- */
-
-static int do_buf(unsigned char *buf, int buflen,
- int type, unsigned char flags, char *quotes, char_io *io_ch, void *arg)
-{
- int i, outlen, len;
- unsigned char orflags, *p, *q;
- unsigned long c;
- p = buf;
- q = buf + buflen;
- outlen = 0;
- while(p != q) {
- if(p == buf && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_FIRST_ESC_2253;
- else orflags = 0;
- switch(type & BUF_TYPE_WIDTH_MASK) {
- case 4:
- c = ((unsigned long)*p++) << 24;
- c |= ((unsigned long)*p++) << 16;
- c |= ((unsigned long)*p++) << 8;
- c |= *p++;
- break;
-
- case 2:
- c = ((unsigned long)*p++) << 8;
- c |= *p++;
- break;
-
- case 1:
- c = *p++;
- break;
-
- case 0:
- i = UTF8_getc(p, buflen, &c);
- if(i < 0) return -1; /* Invalid UTF8String */
- p += i;
- break;
- default:
- return -1; /* invalid width */
- }
- if (p == q && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_LAST_ESC_2253;
- if(type & BUF_TYPE_CONVUTF8) {
- unsigned char utfbuf[6];
- int utflen;
- utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
- for(i = 0; i < utflen; i++) {
- /* We don't need to worry about setting orflags correctly
- * because if utflen==1 its value will be correct anyway
- * otherwise each character will be > 0x7f and so the
- * character will never be escaped on first and last.
- */
- len = do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), quotes, io_ch, arg);
- if(len < 0) return -1;
- outlen += len;
- }
- } else {
- len = do_esc_char(c, (unsigned char)(flags | orflags), quotes, io_ch, arg);
- if(len < 0) return -1;
- outlen += len;
- }
- }
- return outlen;
-}
-
-/* This function hex dumps a buffer of characters */
-
-static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen)
-{
- static const char hexdig[] = "0123456789ABCDEF";
- unsigned char *p, *q;
- char hextmp[2];
- if(arg) {
- p = buf;
- q = buf + buflen;
- while(p != q) {
- hextmp[0] = hexdig[*p >> 4];
- hextmp[1] = hexdig[*p & 0xf];
- if(!io_ch(arg, hextmp, 2)) return -1;
- p++;
- }
- }
- return buflen << 1;
-}
-
-/* "dump" a string. This is done when the type is unknown,
- * or the flags request it. We can either dump the content
- * octets or the entire DER encoding. This uses the RFC2253
- * #01234 format.
- */
-
-static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING *str)
-{
- /* Placing the ASN1_STRING in a temp ASN1_TYPE allows
- * the DER encoding to readily obtained
- */
- ASN1_TYPE t;
- unsigned char *der_buf, *p;
- int outlen, der_len;
-
- if(!io_ch(arg, "#", 1)) return -1;
- /* If we don't dump DER encoding just dump content octets */
- if(!(lflags & ASN1_STRFLGS_DUMP_DER)) {
- outlen = do_hex_dump(io_ch, arg, str->data, str->length);
- if(outlen < 0) return -1;
- return outlen + 1;
- }
- t.type = str->type;
- t.value.ptr = (char *)str;
- der_len = i2d_ASN1_TYPE(&t, NULL);
- der_buf = OPENSSL_malloc(der_len);
- if(!der_buf) return -1;
- p = der_buf;
- i2d_ASN1_TYPE(&t, &p);
- outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
- OPENSSL_free(der_buf);
- if(outlen < 0) return -1;
- return outlen + 1;
-}
-
-/* Lookup table to convert tags to character widths,
- * 0 = UTF8 encoded, -1 is used for non string types
- * otherwise it is the number of bytes per character
- */
-
-static const signed char tag2nbyte[] = {
- -1, -1, -1, -1, -1, /* 0-4 */
- -1, -1, -1, -1, -1, /* 5-9 */
- -1, -1, 0, -1, /* 10-13 */
- -1, -1, -1, -1, /* 15-17 */
- -1, 1, 1, /* 18-20 */
- -1, 1, 1, 1, /* 21-24 */
- -1, 1, -1, /* 25-27 */
- 4, -1, 2 /* 28-30 */
-};
-
-/* This is the main function, print out an
- * ASN1_STRING taking note of various escape
- * and display options. Returns number of
- * characters written or -1 if an error
- * occurred.
- */
-
-static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str)
-{
- int outlen, len;
- int type;
- char quotes;
- unsigned char flags;
- quotes = 0;
- /* Keep a copy of escape flags */
- flags = (unsigned char)(lflags & ESC_FLAGS);
-
- type = str->type;
-
- outlen = 0;
-
-
- if(lflags & ASN1_STRFLGS_SHOW_TYPE) {
- const char *tagname;
- tagname = ASN1_tag2str(type);
- outlen += strlen(tagname);
- if(!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) return -1;
- outlen++;
- }
-
- /* Decide what to do with type, either dump content or display it */
-
- /* Dump everything */
- if(lflags & ASN1_STRFLGS_DUMP_ALL) type = -1;
- /* Ignore the string type */
- else if(lflags & ASN1_STRFLGS_IGNORE_TYPE) type = 1;
- else {
- /* Else determine width based on type */
- if((type > 0) && (type < 31)) type = tag2nbyte[type];
- else type = -1;
- if((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) type = 1;
- }
-
- if(type == -1) {
- len = do_dump(lflags, io_ch, arg, str);
- if(len < 0) return -1;
- outlen += len;
- return outlen;
- }
-
- if(lflags & ASN1_STRFLGS_UTF8_CONVERT) {
- /* Note: if string is UTF8 and we want
- * to convert to UTF8 then we just interpret
- * it as 1 byte per character to avoid converting
- * twice.
- */
- if(!type) type = 1;
- else type |= BUF_TYPE_CONVUTF8;
- }
-
- len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
- if(len < 0) return -1;
- outlen += len;
- if(quotes) outlen += 2;
- if(!arg) return outlen;
- if(quotes && !io_ch(arg, "\"", 1)) return -1;
- if(do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
- return -1;
- if(quotes && !io_ch(arg, "\"", 1)) return -1;
- return outlen;
-}
-
-/* Used for line indenting: print 'indent' spaces */
-
-static int do_indent(char_io *io_ch, void *arg, int indent)
-{
- int i;
- for(i = 0; i < indent; i++)
- if(!io_ch(arg, " ", 1)) return 0;
- return 1;
-}
-
-#define FN_WIDTH_LN 25
-#define FN_WIDTH_SN 10
-
-static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n,
- int indent, unsigned long flags)
-{
- int i, prev = -1, orflags, cnt;
- int fn_opt, fn_nid;
- ASN1_OBJECT *fn;
- ASN1_STRING *val;
- X509_NAME_ENTRY *ent;
- char objtmp[80];
- const char *objbuf;
- int outlen, len;
- char *sep_dn, *sep_mv, *sep_eq;
- int sep_dn_len, sep_mv_len, sep_eq_len;
- if(indent < 0) indent = 0;
- outlen = indent;
- if(!do_indent(io_ch, arg, indent)) return -1;
- switch (flags & XN_FLAG_SEP_MASK)
- {
- case XN_FLAG_SEP_MULTILINE:
- sep_dn = "\n";
- sep_dn_len = 1;
- sep_mv = " + ";
- sep_mv_len = 3;
- break;
-
- case XN_FLAG_SEP_COMMA_PLUS:
- sep_dn = ",";
- sep_dn_len = 1;
- sep_mv = "+";
- sep_mv_len = 1;
- indent = 0;
- break;
-
- case XN_FLAG_SEP_CPLUS_SPC:
- sep_dn = ", ";
- sep_dn_len = 2;
- sep_mv = " + ";
- sep_mv_len = 3;
- indent = 0;
- break;
-
- case XN_FLAG_SEP_SPLUS_SPC:
- sep_dn = "; ";
- sep_dn_len = 2;
- sep_mv = " + ";
- sep_mv_len = 3;
- indent = 0;
- break;
-
- default:
- return -1;
- }
-
- if(flags & XN_FLAG_SPC_EQ) {
- sep_eq = " = ";
- sep_eq_len = 3;
- } else {
- sep_eq = "=";
- sep_eq_len = 1;
- }
-
- fn_opt = flags & XN_FLAG_FN_MASK;
-
- cnt = X509_NAME_entry_count(n);
- for(i = 0; i < cnt; i++) {
- if(flags & XN_FLAG_DN_REV)
- ent = X509_NAME_get_entry(n, cnt - i - 1);
- else ent = X509_NAME_get_entry(n, i);
- if(prev != -1) {
- if(prev == ent->set) {
- if(!io_ch(arg, sep_mv, sep_mv_len)) return -1;
- outlen += sep_mv_len;
- } else {
- if(!io_ch(arg, sep_dn, sep_dn_len)) return -1;
- outlen += sep_dn_len;
- if(!do_indent(io_ch, arg, indent)) return -1;
- outlen += indent;
- }
- }
- prev = ent->set;
- fn = X509_NAME_ENTRY_get_object(ent);
- val = X509_NAME_ENTRY_get_data(ent);
- fn_nid = OBJ_obj2nid(fn);
- if(fn_opt != XN_FLAG_FN_NONE) {
- int objlen, fld_len;
- if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) {
- OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
- fld_len = 0; /* XXX: what should this be? */
- objbuf = objtmp;
- } else {
- if(fn_opt == XN_FLAG_FN_SN) {
- fld_len = FN_WIDTH_SN;
- objbuf = OBJ_nid2sn(fn_nid);
- } else if(fn_opt == XN_FLAG_FN_LN) {
- fld_len = FN_WIDTH_LN;
- objbuf = OBJ_nid2ln(fn_nid);
- } else {
- fld_len = 0; /* XXX: what should this be? */
- objbuf = "";
- }
- }
- objlen = strlen(objbuf);
- if(!io_ch(arg, objbuf, objlen)) return -1;
- if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
- if (!do_indent(io_ch, arg, fld_len - objlen)) return -1;
- outlen += fld_len - objlen;
- }
- if(!io_ch(arg, sep_eq, sep_eq_len)) return -1;
- outlen += objlen + sep_eq_len;
- }
- /* If the field name is unknown then fix up the DER dump
- * flag. We might want to limit this further so it will
- * DER dump on anything other than a few 'standard' fields.
- */
- if((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
- orflags = ASN1_STRFLGS_DUMP_ALL;
- else orflags = 0;
-
- len = do_print_ex(io_ch, arg, flags | orflags, val);
- if(len < 0) return -1;
- outlen += len;
- }
- return outlen;
-}
-
-/* Wrappers round the main functions */
-
-int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags)
-{
- if(flags == XN_FLAG_COMPAT)
- return X509_NAME_print(out, nm, indent);
- return do_name_ex(send_bio_chars, out, nm, indent, flags);
-}
-
-#ifndef OPENSSL_NO_FP_API
-int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags)
-{
- if(flags == XN_FLAG_COMPAT)
- {
- BIO *btmp;
- int ret;
- btmp = BIO_new_fp(fp, BIO_NOCLOSE);
- if(!btmp) return -1;
- ret = X509_NAME_print(btmp, nm, indent);
- BIO_free(btmp);
- return ret;
- }
- return do_name_ex(send_fp_chars, fp, nm, indent, flags);
-}
-#endif
-
-int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags)
-{
- return do_print_ex(send_bio_chars, out, flags, str);
-}
-
-#ifndef OPENSSL_NO_FP_API
-int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags)
-{
- return do_print_ex(send_fp_chars, fp, flags, str);
-}
-#endif
-
-/* Utility function: convert any string type to UTF8, returns number of bytes
- * in output string or a negative error code
- */
-
-int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
-{
- ASN1_STRING stmp, *str = &stmp;
- int mbflag, type, ret;
- if(!in) return -1;
- type = in->type;
- if((type < 0) || (type > 30)) return -1;
- mbflag = tag2nbyte[type];
- if(mbflag == -1) return -1;
- mbflag |= MBSTRING_FLAG;
- stmp.data = NULL;
- ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
- if(ret < 0) return ret;
- *out = stmp.data;
- return stmp.length;
-}
+/* a_strex.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+
+#include "charmap.h"
+
+/* ASN1_STRING_print_ex() and X509_NAME_print_ex().
+ * Enhanced string and name printing routines handling
+ * multibyte characters, RFC2253 and a host of other
+ * options.
+ */
+
+
+#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
+
+#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
+ ASN1_STRFLGS_ESC_QUOTE | \
+ ASN1_STRFLGS_ESC_CTRL | \
+ ASN1_STRFLGS_ESC_MSB)
+
+
+/* Three IO functions for sending data to memory, a BIO and
+ * and a FILE pointer.
+ */
+#if 0 /* never used */
+static int send_mem_chars(void *arg, const void *buf, int len)
+{
+ unsigned char **out = arg;
+ if(!out) return 1;
+ memcpy(*out, buf, len);
+ *out += len;
+ return 1;
+}
+#endif
+
+static int send_bio_chars(void *arg, const void *buf, int len)
+{
+ if(!arg) return 1;
+ if(BIO_write(arg, buf, len) != len) return 0;
+ return 1;
+}
+
+static int send_fp_chars(void *arg, const void *buf, int len)
+{
+ if(!arg) return 1;
+ if(fwrite(buf, 1, len, arg) != (unsigned int)len) return 0;
+ return 1;
+}
+
+typedef int char_io(void *arg, const void *buf, int len);
+
+/* This function handles display of
+ * strings, one character at a time.
+ * It is passed an unsigned long for each
+ * character because it could come from 2 or even
+ * 4 byte forms.
+ */
+
+static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, char_io *io_ch, void *arg)
+{
+ unsigned char chflgs, chtmp;
+ char tmphex[HEX_SIZE(long)+3];
+
+ if(c > 0xffffffffL)
+ return -1;
+ if(c > 0xffff) {
+ BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
+ if(!io_ch(arg, tmphex, 10)) return -1;
+ return 10;
+ }
+ if(c > 0xff) {
+ BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
+ if(!io_ch(arg, tmphex, 6)) return -1;
+ return 6;
+ }
+ chtmp = (unsigned char)c;
+ if(chtmp > 0x7f) chflgs = flags & ASN1_STRFLGS_ESC_MSB;
+ else chflgs = char_type[chtmp] & flags;
+ if(chflgs & CHARTYPE_BS_ESC) {
+ /* If we don't escape with quotes, signal we need quotes */
+ if(chflgs & ASN1_STRFLGS_ESC_QUOTE) {
+ if(do_quotes) *do_quotes = 1;
+ if(!io_ch(arg, &chtmp, 1)) return -1;
+ return 1;
+ }
+ if(!io_ch(arg, "\\", 1)) return -1;
+ if(!io_ch(arg, &chtmp, 1)) return -1;
+ return 2;
+ }
+ if(chflgs & (ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB)) {
+ BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
+ if(!io_ch(arg, tmphex, 3)) return -1;
+ return 3;
+ }
+ /* If we get this far and do any escaping at all must escape
+ * the escape character itself: backslash.
+ */
+ if (chtmp == '\\' && flags & ESC_FLAGS) {
+ if(!io_ch(arg, "\\\\", 2)) return -1;
+ return 2;
+ }
+ if(!io_ch(arg, &chtmp, 1)) return -1;
+ return 1;
+}
+
+#define BUF_TYPE_WIDTH_MASK 0x7
+#define BUF_TYPE_CONVUTF8 0x8
+
+/* This function sends each character in a buffer to
+ * do_esc_char(). It interprets the content formats
+ * and converts to or from UTF8 as appropriate.
+ */
+
+static int do_buf(unsigned char *buf, int buflen,
+ int type, unsigned char flags, char *quotes, char_io *io_ch, void *arg)
+{
+ int i, outlen, len;
+ unsigned char orflags, *p, *q;
+ unsigned long c;
+ p = buf;
+ q = buf + buflen;
+ outlen = 0;
+ while(p != q) {
+ if(p == buf && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_FIRST_ESC_2253;
+ else orflags = 0;
+ switch(type & BUF_TYPE_WIDTH_MASK) {
+ case 4:
+ c = ((unsigned long)*p++) << 24;
+ c |= ((unsigned long)*p++) << 16;
+ c |= ((unsigned long)*p++) << 8;
+ c |= *p++;
+ break;
+
+ case 2:
+ c = ((unsigned long)*p++) << 8;
+ c |= *p++;
+ break;
+
+ case 1:
+ c = *p++;
+ break;
+
+ case 0:
+ i = UTF8_getc(p, buflen, &c);
+ if(i < 0) return -1; /* Invalid UTF8String */
+ p += i;
+ break;
+ default:
+ return -1; /* invalid width */
+ }
+ if (p == q && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_LAST_ESC_2253;
+ if(type & BUF_TYPE_CONVUTF8) {
+ unsigned char utfbuf[6];
+ int utflen;
+ utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
+ for(i = 0; i < utflen; i++) {
+ /* We don't need to worry about setting orflags correctly
+ * because if utflen==1 its value will be correct anyway
+ * otherwise each character will be > 0x7f and so the
+ * character will never be escaped on first and last.
+ */
+ len = do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), quotes, io_ch, arg);
+ if(len < 0) return -1;
+ outlen += len;
+ }
+ } else {
+ len = do_esc_char(c, (unsigned char)(flags | orflags), quotes, io_ch, arg);
+ if(len < 0) return -1;
+ outlen += len;
+ }
+ }
+ return outlen;
+}
+
+/* This function hex dumps a buffer of characters */
+
+static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen)
+{
+ static const char hexdig[] = "0123456789ABCDEF";
+ unsigned char *p, *q;
+ char hextmp[2];
+ if(arg) {
+ p = buf;
+ q = buf + buflen;
+ while(p != q) {
+ hextmp[0] = hexdig[*p >> 4];
+ hextmp[1] = hexdig[*p & 0xf];
+ if(!io_ch(arg, hextmp, 2)) return -1;
+ p++;
+ }
+ }
+ return buflen << 1;
+}
+
+/* "dump" a string. This is done when the type is unknown,
+ * or the flags request it. We can either dump the content
+ * octets or the entire DER encoding. This uses the RFC2253
+ * #01234 format.
+ */
+
+static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING *str)
+{
+ /* Placing the ASN1_STRING in a temp ASN1_TYPE allows
+ * the DER encoding to readily obtained
+ */
+ ASN1_TYPE t;
+ unsigned char *der_buf, *p;
+ int outlen, der_len;
+
+ if(!io_ch(arg, "#", 1)) return -1;
+ /* If we don't dump DER encoding just dump content octets */
+ if(!(lflags & ASN1_STRFLGS_DUMP_DER)) {
+ outlen = do_hex_dump(io_ch, arg, str->data, str->length);
+ if(outlen < 0) return -1;
+ return outlen + 1;
+ }
+ t.type = str->type;
+ t.value.ptr = (char *)str;
+ der_len = i2d_ASN1_TYPE(&t, NULL);
+ der_buf = OPENSSL_malloc(der_len);
+ if(!der_buf) return -1;
+ p = der_buf;
+ i2d_ASN1_TYPE(&t, &p);
+ outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
+ OPENSSL_free(der_buf);
+ if(outlen < 0) return -1;
+ return outlen + 1;
+}
+
+/* Lookup table to convert tags to character widths,
+ * 0 = UTF8 encoded, -1 is used for non string types
+ * otherwise it is the number of bytes per character
+ */
+
+static const signed char tag2nbyte[] = {
+ -1, -1, -1, -1, -1, /* 0-4 */
+ -1, -1, -1, -1, -1, /* 5-9 */
+ -1, -1, 0, -1, /* 10-13 */
+ -1, -1, -1, -1, /* 15-17 */
+ -1, 1, 1, /* 18-20 */
+ -1, 1, 1, 1, /* 21-24 */
+ -1, 1, -1, /* 25-27 */
+ 4, -1, 2 /* 28-30 */
+};
+
+/* This is the main function, print out an
+ * ASN1_STRING taking note of various escape
+ * and display options. Returns number of
+ * characters written or -1 if an error
+ * occurred.
+ */
+
+static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str)
+{
+ int outlen, len;
+ int type;
+ char quotes;
+ unsigned char flags;
+ quotes = 0;
+ /* Keep a copy of escape flags */
+ flags = (unsigned char)(lflags & ESC_FLAGS);
+
+ type = str->type;
+
+ outlen = 0;
+
+
+ if(lflags & ASN1_STRFLGS_SHOW_TYPE) {
+ const char *tagname;
+ tagname = ASN1_tag2str(type);
+ outlen += strlen(tagname);
+ if(!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) return -1;
+ outlen++;
+ }
+
+ /* Decide what to do with type, either dump content or display it */
+
+ /* Dump everything */
+ if(lflags & ASN1_STRFLGS_DUMP_ALL) type = -1;
+ /* Ignore the string type */
+ else if(lflags & ASN1_STRFLGS_IGNORE_TYPE) type = 1;
+ else {
+ /* Else determine width based on type */
+ if((type > 0) && (type < 31)) type = tag2nbyte[type];
+ else type = -1;
+ if((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) type = 1;
+ }
+
+ if(type == -1) {
+ len = do_dump(lflags, io_ch, arg, str);
+ if(len < 0) return -1;
+ outlen += len;
+ return outlen;
+ }
+
+ if(lflags & ASN1_STRFLGS_UTF8_CONVERT) {
+ /* Note: if string is UTF8 and we want
+ * to convert to UTF8 then we just interpret
+ * it as 1 byte per character to avoid converting
+ * twice.
+ */
+ if(!type) type = 1;
+ else type |= BUF_TYPE_CONVUTF8;
+ }
+
+ len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
+ if(len < 0) return -1;
+ outlen += len;
+ if(quotes) outlen += 2;
+ if(!arg) return outlen;
+ if(quotes && !io_ch(arg, "\"", 1)) return -1;
+ if(do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
+ return -1;
+ if(quotes && !io_ch(arg, "\"", 1)) return -1;
+ return outlen;
+}
+
+/* Used for line indenting: print 'indent' spaces */
+
+static int do_indent(char_io *io_ch, void *arg, int indent)
+{
+ int i;
+ for(i = 0; i < indent; i++)
+ if(!io_ch(arg, " ", 1)) return 0;
+ return 1;
+}
+
+#define FN_WIDTH_LN 25
+#define FN_WIDTH_SN 10
+
+static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n,
+ int indent, unsigned long flags)
+{
+ int i, prev = -1, orflags, cnt;
+ int fn_opt, fn_nid;
+ ASN1_OBJECT *fn;
+ ASN1_STRING *val;
+ X509_NAME_ENTRY *ent;
+ char objtmp[80];
+ const char *objbuf;
+ int outlen, len;
+ char *sep_dn, *sep_mv, *sep_eq;
+ int sep_dn_len, sep_mv_len, sep_eq_len;
+ if(indent < 0) indent = 0;
+ outlen = indent;
+ if(!do_indent(io_ch, arg, indent)) return -1;
+ switch (flags & XN_FLAG_SEP_MASK)
+ {
+ case XN_FLAG_SEP_MULTILINE:
+ sep_dn = "\n";
+ sep_dn_len = 1;
+ sep_mv = " + ";
+ sep_mv_len = 3;
+ break;
+
+ case XN_FLAG_SEP_COMMA_PLUS:
+ sep_dn = ",";
+ sep_dn_len = 1;
+ sep_mv = "+";
+ sep_mv_len = 1;
+ indent = 0;
+ break;
+
+ case XN_FLAG_SEP_CPLUS_SPC:
+ sep_dn = ", ";
+ sep_dn_len = 2;
+ sep_mv = " + ";
+ sep_mv_len = 3;
+ indent = 0;
+ break;
+
+ case XN_FLAG_SEP_SPLUS_SPC:
+ sep_dn = "; ";
+ sep_dn_len = 2;
+ sep_mv = " + ";
+ sep_mv_len = 3;
+ indent = 0;
+ break;
+
+ default:
+ return -1;
+ }
+
+ if(flags & XN_FLAG_SPC_EQ) {
+ sep_eq = " = ";
+ sep_eq_len = 3;
+ } else {
+ sep_eq = "=";
+ sep_eq_len = 1;
+ }
+
+ fn_opt = flags & XN_FLAG_FN_MASK;
+
+ cnt = X509_NAME_entry_count(n);
+ for(i = 0; i < cnt; i++) {
+ if(flags & XN_FLAG_DN_REV)
+ ent = X509_NAME_get_entry(n, cnt - i - 1);
+ else ent = X509_NAME_get_entry(n, i);
+ if(prev != -1) {
+ if(prev == ent->set) {
+ if(!io_ch(arg, sep_mv, sep_mv_len)) return -1;
+ outlen += sep_mv_len;
+ } else {
+ if(!io_ch(arg, sep_dn, sep_dn_len)) return -1;
+ outlen += sep_dn_len;
+ if(!do_indent(io_ch, arg, indent)) return -1;
+ outlen += indent;
+ }
+ }
+ prev = ent->set;
+ fn = X509_NAME_ENTRY_get_object(ent);
+ val = X509_NAME_ENTRY_get_data(ent);
+ fn_nid = OBJ_obj2nid(fn);
+ if(fn_opt != XN_FLAG_FN_NONE) {
+ int objlen, fld_len;
+ if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) {
+ OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
+ fld_len = 0; /* XXX: what should this be? */
+ objbuf = objtmp;
+ } else {
+ if(fn_opt == XN_FLAG_FN_SN) {
+ fld_len = FN_WIDTH_SN;
+ objbuf = OBJ_nid2sn(fn_nid);
+ } else if(fn_opt == XN_FLAG_FN_LN) {
+ fld_len = FN_WIDTH_LN;
+ objbuf = OBJ_nid2ln(fn_nid);
+ } else {
+ fld_len = 0; /* XXX: what should this be? */
+ objbuf = "";
+ }
+ }
+ objlen = strlen(objbuf);
+ if(!io_ch(arg, objbuf, objlen)) return -1;
+ if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
+ if (!do_indent(io_ch, arg, fld_len - objlen)) return -1;
+ outlen += fld_len - objlen;
+ }
+ if(!io_ch(arg, sep_eq, sep_eq_len)) return -1;
+ outlen += objlen + sep_eq_len;
+ }
+ /* If the field name is unknown then fix up the DER dump
+ * flag. We might want to limit this further so it will
+ * DER dump on anything other than a few 'standard' fields.
+ */
+ if((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
+ orflags = ASN1_STRFLGS_DUMP_ALL;
+ else orflags = 0;
+
+ len = do_print_ex(io_ch, arg, flags | orflags, val);
+ if(len < 0) return -1;
+ outlen += len;
+ }
+ return outlen;
+}
+
+/* Wrappers round the main functions */
+
+int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags)
+{
+ if(flags == XN_FLAG_COMPAT)
+ return X509_NAME_print(out, nm, indent);
+ return do_name_ex(send_bio_chars, out, nm, indent, flags);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags)
+{
+ if(flags == XN_FLAG_COMPAT)
+ {
+ BIO *btmp;
+ int ret;
+ btmp = BIO_new_fp(fp, BIO_NOCLOSE);
+ if(!btmp) return -1;
+ ret = X509_NAME_print(btmp, nm, indent);
+ BIO_free(btmp);
+ return ret;
+ }
+ return do_name_ex(send_fp_chars, fp, nm, indent, flags);
+}
+#endif
+
+int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags)
+{
+ return do_print_ex(send_bio_chars, out, flags, str);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags)
+{
+ return do_print_ex(send_fp_chars, fp, flags, str);
+}
+#endif
+
+/* Utility function: convert any string type to UTF8, returns number of bytes
+ * in output string or a negative error code
+ */
+
+int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
+{
+ ASN1_STRING stmp, *str = &stmp;
+ int mbflag, type, ret;
+ if(!in) return -1;
+ type = in->type;
+ if((type < 0) || (type > 30)) return -1;
+ mbflag = tag2nbyte[type];
+ if(mbflag == -1) return -1;
+ mbflag |= MBSTRING_FLAG;
+ stmp.data = NULL;
+ ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
+ if(ret < 0) return ret;
+ *out = stmp.data;
+ return stmp.length;
+}
diff --git a/openssl/crypto/asn1/a_strnid.c b/openssl/crypto/asn1/a_strnid.c
index 0a2f13c29..2fc48c155 100644
--- a/openssl/crypto/asn1/a_strnid.c
+++ b/openssl/crypto/asn1/a_strnid.c
@@ -1,290 +1,290 @@
-/* a_strnid.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 1999.
- */
-/* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include "cryptlib.h"
-#include <openssl/asn1.h>
-#include <openssl/objects.h>
-
-
-static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
-static void st_free(ASN1_STRING_TABLE *tbl);
-static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
- const ASN1_STRING_TABLE * const *b);
-
-
-/* This is the global mask for the mbstring functions: this is use to
- * mask out certain types (such as BMPString and UTF8String) because
- * certain software (e.g. Netscape) has problems with them.
- */
-
-static unsigned long global_mask = 0xFFFFFFFFL;
-
-void ASN1_STRING_set_default_mask(unsigned long mask)
-{
- global_mask = mask;
-}
-
-unsigned long ASN1_STRING_get_default_mask(void)
-{
- return global_mask;
-}
-
-/* This function sets the default to various "flavours" of configuration.
- * based on an ASCII string. Currently this is:
- * MASK:XXXX : a numerical mask value.
- * nobmp : Don't use BMPStrings (just Printable, T61).
- * pkix : PKIX recommendation in RFC2459.
- * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
- * default: the default value, Printable, T61, BMP.
- */
-
-int ASN1_STRING_set_default_mask_asc(const char *p)
-{
- unsigned long mask;
- char *end;
- if(!strncmp(p, "MASK:", 5)) {
- if(!p[5]) return 0;
- mask = strtoul(p + 5, &end, 0);
- if(*end) return 0;
- } else if(!strcmp(p, "nombstr"))
- mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
- else if(!strcmp(p, "pkix"))
- mask = ~((unsigned long)B_ASN1_T61STRING);
- else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING;
- else if(!strcmp(p, "default"))
- mask = 0xFFFFFFFFL;
- else return 0;
- ASN1_STRING_set_default_mask(mask);
- return 1;
-}
-
-/* The following function generates an ASN1_STRING based on limits in a table.
- * Frequently the types and length of an ASN1_STRING are restricted by a
- * corresponding OID. For example certificates and certificate requests.
- */
-
-ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in,
- int inlen, int inform, int nid)
-{
- ASN1_STRING_TABLE *tbl;
- ASN1_STRING *str = NULL;
- unsigned long mask;
- int ret;
- if(!out) out = &str;
- tbl = ASN1_STRING_TABLE_get(nid);
- if(tbl) {
- mask = tbl->mask;
- if(!(tbl->flags & STABLE_NO_MASK)) mask &= global_mask;
- ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
- tbl->minsize, tbl->maxsize);
- } else ret = ASN1_mbstring_copy(out, in, inlen, inform, DIRSTRING_TYPE & global_mask);
- if(ret <= 0) return NULL;
- return *out;
-}
-
-/* Now the tables and helper functions for the string table:
- */
-
-/* size limits: this stuff is taken straight from RFC3280 */
-
-#define ub_name 32768
-#define ub_common_name 64
-#define ub_locality_name 128
-#define ub_state_name 128
-#define ub_organization_name 64
-#define ub_organization_unit_name 64
-#define ub_title 64
-#define ub_email_address 128
-#define ub_serial_number 64
-
-
-/* This table must be kept in NID order */
-
-static const ASN1_STRING_TABLE tbl_standard[] = {
-{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
-{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
-{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
-{NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
-{NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
-{NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, 0},
-{NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK},
-{NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
-{NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
-{NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
-{NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
-{NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
-{NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
-{NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
-{NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
-{NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
-{NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
-{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
-{NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
-};
-
-static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
- const ASN1_STRING_TABLE * const *b)
-{
- return (*a)->nid - (*b)->nid;
-}
-
-DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
-
-static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
-{
- return a->nid - b->nid;
-}
-
-IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
-
-ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
-{
- int idx;
- ASN1_STRING_TABLE *ttmp;
- ASN1_STRING_TABLE fnd;
- fnd.nid = nid;
- ttmp = OBJ_bsearch_table(&fnd, tbl_standard,
- sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE));
- if(ttmp) return ttmp;
- if(!stable) return NULL;
- idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
- if(idx < 0) return NULL;
- return sk_ASN1_STRING_TABLE_value(stable, idx);
-}
-
-int ASN1_STRING_TABLE_add(int nid,
- long minsize, long maxsize, unsigned long mask,
- unsigned long flags)
-{
- ASN1_STRING_TABLE *tmp;
- char new_nid = 0;
- flags &= ~STABLE_FLAGS_MALLOC;
- if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
- if(!stable) {
- ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- if(!(tmp = ASN1_STRING_TABLE_get(nid))) {
- tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
- if(!tmp) {
- ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD,
- ERR_R_MALLOC_FAILURE);
- return 0;
- }
- tmp->flags = flags | STABLE_FLAGS_MALLOC;
- tmp->nid = nid;
- new_nid = 1;
- } else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
- if(minsize != -1) tmp->minsize = minsize;
- if(maxsize != -1) tmp->maxsize = maxsize;
- tmp->mask = mask;
- if(new_nid) sk_ASN1_STRING_TABLE_push(stable, tmp);
- return 1;
-}
-
-void ASN1_STRING_TABLE_cleanup(void)
-{
- STACK_OF(ASN1_STRING_TABLE) *tmp;
- tmp = stable;
- if(!tmp) return;
- stable = NULL;
- sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
-}
-
-static void st_free(ASN1_STRING_TABLE *tbl)
-{
- if(tbl->flags & STABLE_FLAGS_MALLOC) OPENSSL_free(tbl);
-}
-
-
-IMPLEMENT_STACK_OF(ASN1_STRING_TABLE)
-
-#ifdef STRING_TABLE_TEST
-
-main()
-{
- ASN1_STRING_TABLE *tmp;
- int i, last_nid = -1;
-
- for (tmp = tbl_standard, i = 0;
- i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
- {
- if (tmp->nid < last_nid)
- {
- last_nid = 0;
- break;
- }
- last_nid = tmp->nid;
- }
-
- if (last_nid != 0)
- {
- printf("Table order OK\n");
- exit(0);
- }
-
- for (tmp = tbl_standard, i = 0;
- i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
- printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
- OBJ_nid2ln(tmp->nid));
-
-}
-
-#endif
+/* a_strnid.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+
+
+static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
+static void st_free(ASN1_STRING_TABLE *tbl);
+static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
+ const ASN1_STRING_TABLE * const *b);
+
+
+/* This is the global mask for the mbstring functions: this is use to
+ * mask out certain types (such as BMPString and UTF8String) because
+ * certain software (e.g. Netscape) has problems with them.
+ */
+
+static unsigned long global_mask = 0xFFFFFFFFL;
+
+void ASN1_STRING_set_default_mask(unsigned long mask)
+{
+ global_mask = mask;
+}
+
+unsigned long ASN1_STRING_get_default_mask(void)
+{
+ return global_mask;
+}
+
+/* This function sets the default to various "flavours" of configuration.
+ * based on an ASCII string. Currently this is:
+ * MASK:XXXX : a numerical mask value.
+ * nobmp : Don't use BMPStrings (just Printable, T61).
+ * pkix : PKIX recommendation in RFC2459.
+ * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
+ * default: the default value, Printable, T61, BMP.
+ */
+
+int ASN1_STRING_set_default_mask_asc(const char *p)
+{
+ unsigned long mask;
+ char *end;
+ if(!strncmp(p, "MASK:", 5)) {
+ if(!p[5]) return 0;
+ mask = strtoul(p + 5, &end, 0);
+ if(*end) return 0;
+ } else if(!strcmp(p, "nombstr"))
+ mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
+ else if(!strcmp(p, "pkix"))
+ mask = ~((unsigned long)B_ASN1_T61STRING);
+ else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING;
+ else if(!strcmp(p, "default"))
+ mask = 0xFFFFFFFFL;
+ else return 0;
+ ASN1_STRING_set_default_mask(mask);
+ return 1;
+}
+
+/* The following function generates an ASN1_STRING based on limits in a table.
+ * Frequently the types and length of an ASN1_STRING are restricted by a
+ * corresponding OID. For example certificates and certificate requests.
+ */
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in,
+ int inlen, int inform, int nid)
+{
+ ASN1_STRING_TABLE *tbl;
+ ASN1_STRING *str = NULL;
+ unsigned long mask;
+ int ret;
+ if(!out) out = &str;
+ tbl = ASN1_STRING_TABLE_get(nid);
+ if(tbl) {
+ mask = tbl->mask;
+ if(!(tbl->flags & STABLE_NO_MASK)) mask &= global_mask;
+ ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
+ tbl->minsize, tbl->maxsize);
+ } else ret = ASN1_mbstring_copy(out, in, inlen, inform, DIRSTRING_TYPE & global_mask);
+ if(ret <= 0) return NULL;
+ return *out;
+}
+
+/* Now the tables and helper functions for the string table:
+ */
+
+/* size limits: this stuff is taken straight from RFC3280 */
+
+#define ub_name 32768
+#define ub_common_name 64
+#define ub_locality_name 128
+#define ub_state_name 128
+#define ub_organization_name 64
+#define ub_organization_unit_name 64
+#define ub_title 64
+#define ub_email_address 128
+#define ub_serial_number 64
+
+
+/* This table must be kept in NID order */
+
+static const ASN1_STRING_TABLE tbl_standard[] = {
+{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
+{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
+{NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
+{NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
+{NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, 0},
+{NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK},
+{NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
+{NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
+{NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
+{NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
+{NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
+{NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
+{NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+{NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
+{NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
+{NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
+{NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
+};
+
+static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
+ const ASN1_STRING_TABLE * const *b)
+{
+ return (*a)->nid - (*b)->nid;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
+static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
+{
+ return a->nid - b->nid;
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
+{
+ int idx;
+ ASN1_STRING_TABLE *ttmp;
+ ASN1_STRING_TABLE fnd;
+ fnd.nid = nid;
+ ttmp = OBJ_bsearch_table(&fnd, tbl_standard,
+ sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE));
+ if(ttmp) return ttmp;
+ if(!stable) return NULL;
+ idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
+ if(idx < 0) return NULL;
+ return sk_ASN1_STRING_TABLE_value(stable, idx);
+}
+
+int ASN1_STRING_TABLE_add(int nid,
+ long minsize, long maxsize, unsigned long mask,
+ unsigned long flags)
+{
+ ASN1_STRING_TABLE *tmp;
+ char new_nid = 0;
+ flags &= ~STABLE_FLAGS_MALLOC;
+ if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
+ if(!stable) {
+ ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if(!(tmp = ASN1_STRING_TABLE_get(nid))) {
+ tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
+ if(!tmp) {
+ ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD,
+ ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ tmp->flags = flags | STABLE_FLAGS_MALLOC;
+ tmp->nid = nid;
+ new_nid = 1;
+ } else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
+ if(minsize != -1) tmp->minsize = minsize;
+ if(maxsize != -1) tmp->maxsize = maxsize;
+ tmp->mask = mask;
+ if(new_nid) sk_ASN1_STRING_TABLE_push(stable, tmp);
+ return 1;
+}
+
+void ASN1_STRING_TABLE_cleanup(void)
+{
+ STACK_OF(ASN1_STRING_TABLE) *tmp;
+ tmp = stable;
+ if(!tmp) return;
+ stable = NULL;
+ sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
+}
+
+static void st_free(ASN1_STRING_TABLE *tbl)
+{
+ if(tbl->flags & STABLE_FLAGS_MALLOC) OPENSSL_free(tbl);
+}
+
+
+IMPLEMENT_STACK_OF(ASN1_STRING_TABLE)
+
+#ifdef STRING_TABLE_TEST
+
+main()
+{
+ ASN1_STRING_TABLE *tmp;
+ int i, last_nid = -1;
+
+ for (tmp = tbl_standard, i = 0;
+ i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
+ {
+ if (tmp->nid < last_nid)
+ {
+ last_nid = 0;
+ break;
+ }
+ last_nid = tmp->nid;
+ }
+
+ if (last_nid != 0)
+ {
+ printf("Table order OK\n");
+ exit(0);
+ }
+
+ for (tmp = tbl_standard, i = 0;
+ i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
+ printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
+ OBJ_nid2ln(tmp->nid));
+
+}
+
+#endif
diff --git a/openssl/crypto/asn1/ameth_lib.c b/openssl/crypto/asn1/ameth_lib.c
index 5e26a14b8..5a581b90e 100644
--- a/openssl/crypto/asn1/ameth_lib.c
+++ b/openssl/crypto/asn1/ameth_lib.c
@@ -1,450 +1,450 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2006.
- */
-/* ====================================================================
- * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/asn1t.h>
-#include <openssl/x509.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
-#include "asn1_locl.h"
-
-extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
-extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
-extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
-extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
-extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
-
-/* Keep this sorted in type order !! */
-static const EVP_PKEY_ASN1_METHOD *standard_methods[] =
- {
-#ifndef OPENSSL_NO_RSA
- &rsa_asn1_meths[0],
- &rsa_asn1_meths[1],
-#endif
-#ifndef OPENSSL_NO_DH
- &dh_asn1_meth,
-#endif
-#ifndef OPENSSL_NO_DSA
- &dsa_asn1_meths[0],
- &dsa_asn1_meths[1],
- &dsa_asn1_meths[2],
- &dsa_asn1_meths[3],
- &dsa_asn1_meths[4],
-#endif
-#ifndef OPENSSL_NO_EC
- &eckey_asn1_meth,
-#endif
- &hmac_asn1_meth
- };
-
-typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
-DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
-static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
-
-
-
-#ifdef TEST
-void main()
- {
- int i;
- for (i = 0;
- i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
- i++)
- fprintf(stderr, "Number %d id=%d (%s)\n", i,
- standard_methods[i]->pkey_id,
- OBJ_nid2sn(standard_methods[i]->pkey_id));
- }
-#endif
-
-DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
- const EVP_PKEY_ASN1_METHOD *, ameth);
-
-static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
- const EVP_PKEY_ASN1_METHOD * const *b)
- {
- return ((*a)->pkey_id - (*b)->pkey_id);
- }
-
-IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
- const EVP_PKEY_ASN1_METHOD *, ameth);
-
-int EVP_PKEY_asn1_get_count(void)
- {
- int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
- if (app_methods)
- num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
- return num;
- }
-
-const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
- {
- int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
- if (idx < 0)
- return NULL;
- if (idx < num)
- return standard_methods[idx];
- idx -= num;
- return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
- }
-
-static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
- {
- EVP_PKEY_ASN1_METHOD tmp;
- const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
- tmp.pkey_id = type;
- if (app_methods)
- {
- int idx;
- idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
- if (idx >= 0)
- return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
- }
- ret = OBJ_bsearch_ameth(&t, standard_methods,
- sizeof(standard_methods)
- /sizeof(EVP_PKEY_ASN1_METHOD *));
- if (!ret || !*ret)
- return NULL;
- return *ret;
- }
-
-/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
- * also search through engines and set *pe to a functional reference
- * to the engine implementing 'type' or NULL if no engine implements
- * it.
- */
-
-const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
- {
- const EVP_PKEY_ASN1_METHOD *t;
-
- for (;;)
- {
- t = pkey_asn1_find(type);
- if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
- break;
- type = t->pkey_base_id;
- }
- if (pe)
- {
-#ifndef OPENSSL_NO_ENGINE
- ENGINE *e;
- /* type will contain the final unaliased type */
- e = ENGINE_get_pkey_asn1_meth_engine(type);
- if (e)
- {
- *pe = e;
- return ENGINE_get_pkey_asn1_meth(e, type);
- }
-#endif
- *pe = NULL;
- }
- return t;
- }
-
-const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
- const char *str, int len)
- {
- int i;
- const EVP_PKEY_ASN1_METHOD *ameth;
- if (len == -1)
- len = strlen(str);
- if (pe)
- {
-#ifndef OPENSSL_NO_ENGINE
- ENGINE *e;
- ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
- if (ameth)
- {
- /* Convert structural into
- * functional reference
- */
- if (!ENGINE_init(e))
- ameth = NULL;
- ENGINE_free(e);
- *pe = e;
- return ameth;
- }
-#endif
- *pe = NULL;
- }
- for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
- {
- ameth = EVP_PKEY_asn1_get0(i);
- if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
- continue;
- if (((int)strlen(ameth->pem_str) == len) &&
- !strncasecmp(ameth->pem_str, str, len))
- return ameth;
- }
- return NULL;
- }
-
-int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
- {
- if (app_methods == NULL)
- {
- app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
- if (!app_methods)
- return 0;
- }
- if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
- return 0;
- sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
- return 1;
- }
-
-int EVP_PKEY_asn1_add_alias(int to, int from)
- {
- EVP_PKEY_ASN1_METHOD *ameth;
- ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
- if (!ameth)
- return 0;
- ameth->pkey_base_id = to;
- return EVP_PKEY_asn1_add0(ameth);
- }
-
-int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
- const char **pinfo, const char **ppem_str,
- const EVP_PKEY_ASN1_METHOD *ameth)
- {
- if (!ameth)
- return 0;
- if (ppkey_id)
- *ppkey_id = ameth->pkey_id;
- if (ppkey_base_id)
- *ppkey_base_id = ameth->pkey_base_id;
- if (ppkey_flags)
- *ppkey_flags = ameth->pkey_flags;
- if (pinfo)
- *pinfo = ameth->info;
- if (ppem_str)
- *ppem_str = ameth->pem_str;
- return 1;
- }
-
-const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
- {
- return pkey->ameth;
- }
-
-EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
- const char *pem_str, const char *info)
- {
- EVP_PKEY_ASN1_METHOD *ameth;
- ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
- if (!ameth)
- return NULL;
-
- ameth->pkey_id = id;
- ameth->pkey_base_id = id;
- ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
-
- if (info)
- {
- ameth->info = BUF_strdup(info);
- if (!ameth->info)
- goto err;
- }
- else
- ameth->info = NULL;
-
- if (pem_str)
- {
- ameth->pem_str = BUF_strdup(pem_str);
- if (!ameth->pem_str)
- goto err;
- }
- else
- ameth->pem_str = NULL;
-
- ameth->pub_decode = 0;
- ameth->pub_encode = 0;
- ameth->pub_cmp = 0;
- ameth->pub_print = 0;
-
- ameth->priv_decode = 0;
- ameth->priv_encode = 0;
- ameth->priv_print = 0;
-
- ameth->old_priv_encode = 0;
- ameth->old_priv_decode = 0;
-
- ameth->pkey_size = 0;
- ameth->pkey_bits = 0;
-
- ameth->param_decode = 0;
- ameth->param_encode = 0;
- ameth->param_missing = 0;
- ameth->param_copy = 0;
- ameth->param_cmp = 0;
- ameth->param_print = 0;
-
- ameth->pkey_free = 0;
- ameth->pkey_ctrl = 0;
-
- return ameth;
-
- err:
-
- EVP_PKEY_asn1_free(ameth);
- return NULL;
-
- }
-
-void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
- const EVP_PKEY_ASN1_METHOD *src)
- {
-
- dst->pub_decode = src->pub_decode;
- dst->pub_encode = src->pub_encode;
- dst->pub_cmp = src->pub_cmp;
- dst->pub_print = src->pub_print;
-
- dst->priv_decode = src->priv_decode;
- dst->priv_encode = src->priv_encode;
- dst->priv_print = src->priv_print;
-
- dst->old_priv_encode = src->old_priv_encode;
- dst->old_priv_decode = src->old_priv_decode;
-
- dst->pkey_size = src->pkey_size;
- dst->pkey_bits = src->pkey_bits;
-
- dst->param_decode = src->param_decode;
- dst->param_encode = src->param_encode;
- dst->param_missing = src->param_missing;
- dst->param_copy = src->param_copy;
- dst->param_cmp = src->param_cmp;
- dst->param_print = src->param_print;
-
- dst->pkey_free = src->pkey_free;
- dst->pkey_ctrl = src->pkey_ctrl;
-
- }
-
-void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
- {
- if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC))
- {
- if (ameth->pem_str)
- OPENSSL_free(ameth->pem_str);
- if (ameth->info)
- OPENSSL_free(ameth->info);
- OPENSSL_free(ameth);
- }
- }
-
-void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
- int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
- int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
- int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
- int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx),
- int (*pkey_size)(const EVP_PKEY *pk),
- int (*pkey_bits)(const EVP_PKEY *pk))
- {
- ameth->pub_decode = pub_decode;
- ameth->pub_encode = pub_encode;
- ameth->pub_cmp = pub_cmp;
- ameth->pub_print = pub_print;
- ameth->pkey_size = pkey_size;
- ameth->pkey_bits = pkey_bits;
- }
-
-void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
- int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
- int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
- int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx))
- {
- ameth->priv_decode = priv_decode;
- ameth->priv_encode = priv_encode;
- ameth->priv_print = priv_print;
- }
-
-void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
- int (*param_decode)(EVP_PKEY *pkey,
- const unsigned char **pder, int derlen),
- int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
- int (*param_missing)(const EVP_PKEY *pk),
- int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
- int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
- int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
- ASN1_PCTX *pctx))
- {
- ameth->param_decode = param_decode;
- ameth->param_encode = param_encode;
- ameth->param_missing = param_missing;
- ameth->param_copy = param_copy;
- ameth->param_cmp = param_cmp;
- ameth->param_print = param_print;
- }
-
-void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
- void (*pkey_free)(EVP_PKEY *pkey))
- {
- ameth->pkey_free = pkey_free;
- }
-
-void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
- int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
- long arg1, void *arg2))
- {
- ameth->pkey_ctrl = pkey_ctrl;
- }
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "asn1_locl.h"
+
+extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
+
+/* Keep this sorted in type order !! */
+static const EVP_PKEY_ASN1_METHOD *standard_methods[] =
+ {
+#ifndef OPENSSL_NO_RSA
+ &rsa_asn1_meths[0],
+ &rsa_asn1_meths[1],
+#endif
+#ifndef OPENSSL_NO_DH
+ &dh_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+ &dsa_asn1_meths[0],
+ &dsa_asn1_meths[1],
+ &dsa_asn1_meths[2],
+ &dsa_asn1_meths[3],
+ &dsa_asn1_meths[4],
+#endif
+#ifndef OPENSSL_NO_EC
+ &eckey_asn1_meth,
+#endif
+ &hmac_asn1_meth
+ };
+
+typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
+DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
+static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
+
+
+
+#ifdef TEST
+void main()
+ {
+ int i;
+ for (i = 0;
+ i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+ i++)
+ fprintf(stderr, "Number %d id=%d (%s)\n", i,
+ standard_methods[i]->pkey_id,
+ OBJ_nid2sn(standard_methods[i]->pkey_id));
+ }
+#endif
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+ const EVP_PKEY_ASN1_METHOD *, ameth);
+
+static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
+ const EVP_PKEY_ASN1_METHOD * const *b)
+ {
+ return ((*a)->pkey_id - (*b)->pkey_id);
+ }
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+ const EVP_PKEY_ASN1_METHOD *, ameth);
+
+int EVP_PKEY_asn1_get_count(void)
+ {
+ int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+ if (app_methods)
+ num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
+ return num;
+ }
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
+ {
+ int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+ if (idx < 0)
+ return NULL;
+ if (idx < num)
+ return standard_methods[idx];
+ idx -= num;
+ return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+ }
+
+static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
+ {
+ EVP_PKEY_ASN1_METHOD tmp;
+ const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
+ tmp.pkey_id = type;
+ if (app_methods)
+ {
+ int idx;
+ idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
+ if (idx >= 0)
+ return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+ }
+ ret = OBJ_bsearch_ameth(&t, standard_methods,
+ sizeof(standard_methods)
+ /sizeof(EVP_PKEY_ASN1_METHOD *));
+ if (!ret || !*ret)
+ return NULL;
+ return *ret;
+ }
+
+/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
+ * also search through engines and set *pe to a functional reference
+ * to the engine implementing 'type' or NULL if no engine implements
+ * it.
+ */
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
+ {
+ const EVP_PKEY_ASN1_METHOD *t;
+
+ for (;;)
+ {
+ t = pkey_asn1_find(type);
+ if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
+ break;
+ type = t->pkey_base_id;
+ }
+ if (pe)
+ {
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE *e;
+ /* type will contain the final unaliased type */
+ e = ENGINE_get_pkey_asn1_meth_engine(type);
+ if (e)
+ {
+ *pe = e;
+ return ENGINE_get_pkey_asn1_meth(e, type);
+ }
+#endif
+ *pe = NULL;
+ }
+ return t;
+ }
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+ const char *str, int len)
+ {
+ int i;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ if (len == -1)
+ len = strlen(str);
+ if (pe)
+ {
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE *e;
+ ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
+ if (ameth)
+ {
+ /* Convert structural into
+ * functional reference
+ */
+ if (!ENGINE_init(e))
+ ameth = NULL;
+ ENGINE_free(e);
+ *pe = e;
+ return ameth;
+ }
+#endif
+ *pe = NULL;
+ }
+ for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
+ {
+ ameth = EVP_PKEY_asn1_get0(i);
+ if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
+ continue;
+ if (((int)strlen(ameth->pem_str) == len) &&
+ !strncasecmp(ameth->pem_str, str, len))
+ return ameth;
+ }
+ return NULL;
+ }
+
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
+ {
+ if (app_methods == NULL)
+ {
+ app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
+ if (!app_methods)
+ return 0;
+ }
+ if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
+ return 0;
+ sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
+ return 1;
+ }
+
+int EVP_PKEY_asn1_add_alias(int to, int from)
+ {
+ EVP_PKEY_ASN1_METHOD *ameth;
+ ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
+ if (!ameth)
+ return 0;
+ ameth->pkey_base_id = to;
+ return EVP_PKEY_asn1_add0(ameth);
+ }
+
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
+ const char **pinfo, const char **ppem_str,
+ const EVP_PKEY_ASN1_METHOD *ameth)
+ {
+ if (!ameth)
+ return 0;
+ if (ppkey_id)
+ *ppkey_id = ameth->pkey_id;
+ if (ppkey_base_id)
+ *ppkey_base_id = ameth->pkey_base_id;
+ if (ppkey_flags)
+ *ppkey_flags = ameth->pkey_flags;
+ if (pinfo)
+ *pinfo = ameth->info;
+ if (ppem_str)
+ *ppem_str = ameth->pem_str;
+ return 1;
+ }
+
+const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
+ {
+ return pkey->ameth;
+ }
+
+EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
+ const char *pem_str, const char *info)
+ {
+ EVP_PKEY_ASN1_METHOD *ameth;
+ ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
+ if (!ameth)
+ return NULL;
+
+ ameth->pkey_id = id;
+ ameth->pkey_base_id = id;
+ ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
+
+ if (info)
+ {
+ ameth->info = BUF_strdup(info);
+ if (!ameth->info)
+ goto err;
+ }
+ else
+ ameth->info = NULL;
+
+ if (pem_str)
+ {
+ ameth->pem_str = BUF_strdup(pem_str);
+ if (!ameth->pem_str)
+ goto err;
+ }
+ else
+ ameth->pem_str = NULL;
+
+ ameth->pub_decode = 0;
+ ameth->pub_encode = 0;
+ ameth->pub_cmp = 0;
+ ameth->pub_print = 0;
+
+ ameth->priv_decode = 0;
+ ameth->priv_encode = 0;
+ ameth->priv_print = 0;
+
+ ameth->old_priv_encode = 0;
+ ameth->old_priv_decode = 0;
+
+ ameth->pkey_size = 0;
+ ameth->pkey_bits = 0;
+
+ ameth->param_decode = 0;
+ ameth->param_encode = 0;
+ ameth->param_missing = 0;
+ ameth->param_copy = 0;
+ ameth->param_cmp = 0;
+ ameth->param_print = 0;
+
+ ameth->pkey_free = 0;
+ ameth->pkey_ctrl = 0;
+
+ return ameth;
+
+ err:
+
+ EVP_PKEY_asn1_free(ameth);
+ return NULL;
+
+ }
+
+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
+ const EVP_PKEY_ASN1_METHOD *src)
+ {
+
+ dst->pub_decode = src->pub_decode;
+ dst->pub_encode = src->pub_encode;
+ dst->pub_cmp = src->pub_cmp;
+ dst->pub_print = src->pub_print;
+
+ dst->priv_decode = src->priv_decode;
+ dst->priv_encode = src->priv_encode;
+ dst->priv_print = src->priv_print;
+
+ dst->old_priv_encode = src->old_priv_encode;
+ dst->old_priv_decode = src->old_priv_decode;
+
+ dst->pkey_size = src->pkey_size;
+ dst->pkey_bits = src->pkey_bits;
+
+ dst->param_decode = src->param_decode;
+ dst->param_encode = src->param_encode;
+ dst->param_missing = src->param_missing;
+ dst->param_copy = src->param_copy;
+ dst->param_cmp = src->param_cmp;
+ dst->param_print = src->param_print;
+
+ dst->pkey_free = src->pkey_free;
+ dst->pkey_ctrl = src->pkey_ctrl;
+
+ }
+
+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
+ {
+ if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC))
+ {
+ if (ameth->pem_str)
+ OPENSSL_free(ameth->pem_str);
+ if (ameth->info)
+ OPENSSL_free(ameth->info);
+ OPENSSL_free(ameth);
+ }
+ }
+
+void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
+ int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
+ int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
+ int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx),
+ int (*pkey_size)(const EVP_PKEY *pk),
+ int (*pkey_bits)(const EVP_PKEY *pk))
+ {
+ ameth->pub_decode = pub_decode;
+ ameth->pub_encode = pub_encode;
+ ameth->pub_cmp = pub_cmp;
+ ameth->pub_print = pub_print;
+ ameth->pkey_size = pkey_size;
+ ameth->pkey_bits = pkey_bits;
+ }
+
+void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
+ int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
+ int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx))
+ {
+ ameth->priv_decode = priv_decode;
+ ameth->priv_encode = priv_encode;
+ ameth->priv_print = priv_print;
+ }
+
+void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*param_decode)(EVP_PKEY *pkey,
+ const unsigned char **pder, int derlen),
+ int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
+ int (*param_missing)(const EVP_PKEY *pk),
+ int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
+ int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
+ int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx))
+ {
+ ameth->param_decode = param_decode;
+ ameth->param_encode = param_encode;
+ ameth->param_missing = param_missing;
+ ameth->param_copy = param_copy;
+ ameth->param_cmp = param_cmp;
+ ameth->param_print = param_print;
+ }
+
+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+ void (*pkey_free)(EVP_PKEY *pkey))
+ {
+ ameth->pkey_free = pkey_free;
+ }
+
+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
+ long arg1, void *arg2))
+ {
+ ameth->pkey_ctrl = pkey_ctrl;
+ }
diff --git a/openssl/crypto/asn1/asn1.h b/openssl/crypto/asn1/asn1.h
index 1a5123216..59540e4e7 100644
--- a/openssl/crypto/asn1/asn1.h
+++ b/openssl/crypto/asn1/asn1.h
@@ -1,1402 +1,1402 @@
-/* crypto/asn1/asn1.h */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#ifndef HEADER_ASN1_H
-#define HEADER_ASN1_H
-
-#include <time.h>
-#include <openssl/e_os2.h>
-#ifndef OPENSSL_NO_BIO
-#include <openssl/bio.h>
-#endif
-#include <openssl/stack.h>
-#include <openssl/safestack.h>
-
-#include <openssl/symhacks.h>
-
-#include <openssl/ossl_typ.h>
-#ifndef OPENSSL_NO_DEPRECATED
-#include <openssl/bn.h>
-#endif
-
-#ifdef OPENSSL_BUILD_SHLIBCRYPTO
-# undef OPENSSL_EXTERN
-# define OPENSSL_EXTERN OPENSSL_EXPORT
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define V_ASN1_UNIVERSAL 0x00
-#define V_ASN1_APPLICATION 0x40
-#define V_ASN1_CONTEXT_SPECIFIC 0x80
-#define V_ASN1_PRIVATE 0xc0
-
-#define V_ASN1_CONSTRUCTED 0x20
-#define V_ASN1_PRIMITIVE_TAG 0x1f
-#define V_ASN1_PRIMATIVE_TAG 0x1f
-
-#define V_ASN1_APP_CHOOSE -2 /* let the recipient choose */
-#define V_ASN1_OTHER -3 /* used in ASN1_TYPE */
-#define V_ASN1_ANY -4 /* used in ASN1 template code */
-
-#define V_ASN1_NEG 0x100 /* negative flag */
-
-#define V_ASN1_UNDEF -1
-#define V_ASN1_EOC 0
-#define V_ASN1_BOOLEAN 1 /**/
-#define V_ASN1_INTEGER 2
-#define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG)
-#define V_ASN1_BIT_STRING 3
-#define V_ASN1_OCTET_STRING 4
-#define V_ASN1_NULL 5
-#define V_ASN1_OBJECT 6
-#define V_ASN1_OBJECT_DESCRIPTOR 7
-#define V_ASN1_EXTERNAL 8
-#define V_ASN1_REAL 9
-#define V_ASN1_ENUMERATED 10
-#define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG)
-#define V_ASN1_UTF8STRING 12
-#define V_ASN1_SEQUENCE 16
-#define V_ASN1_SET 17
-#define V_ASN1_NUMERICSTRING 18 /**/
-#define V_ASN1_PRINTABLESTRING 19
-#define V_ASN1_T61STRING 20
-#define V_ASN1_TELETEXSTRING 20 /* alias */
-#define V_ASN1_VIDEOTEXSTRING 21 /**/
-#define V_ASN1_IA5STRING 22
-#define V_ASN1_UTCTIME 23
-#define V_ASN1_GENERALIZEDTIME 24 /**/
-#define V_ASN1_GRAPHICSTRING 25 /**/
-#define V_ASN1_ISO64STRING 26 /**/
-#define V_ASN1_VISIBLESTRING 26 /* alias */
-#define V_ASN1_GENERALSTRING 27 /**/
-#define V_ASN1_UNIVERSALSTRING 28 /**/
-#define V_ASN1_BMPSTRING 30
-
-/* For use with d2i_ASN1_type_bytes() */
-#define B_ASN1_NUMERICSTRING 0x0001
-#define B_ASN1_PRINTABLESTRING 0x0002
-#define B_ASN1_T61STRING 0x0004
-#define B_ASN1_TELETEXSTRING 0x0004
-#define B_ASN1_VIDEOTEXSTRING 0x0008
-#define B_ASN1_IA5STRING 0x0010
-#define B_ASN1_GRAPHICSTRING 0x0020
-#define B_ASN1_ISO64STRING 0x0040
-#define B_ASN1_VISIBLESTRING 0x0040
-#define B_ASN1_GENERALSTRING 0x0080
-#define B_ASN1_UNIVERSALSTRING 0x0100
-#define B_ASN1_OCTET_STRING 0x0200
-#define B_ASN1_BIT_STRING 0x0400
-#define B_ASN1_BMPSTRING 0x0800
-#define B_ASN1_UNKNOWN 0x1000
-#define B_ASN1_UTF8STRING 0x2000
-#define B_ASN1_UTCTIME 0x4000
-#define B_ASN1_GENERALIZEDTIME 0x8000
-#define B_ASN1_SEQUENCE 0x10000
-
-/* For use with ASN1_mbstring_copy() */
-#define MBSTRING_FLAG 0x1000
-#define MBSTRING_UTF8 (MBSTRING_FLAG)
-#define MBSTRING_ASC (MBSTRING_FLAG|1)
-#define MBSTRING_BMP (MBSTRING_FLAG|2)
-#define MBSTRING_UNIV (MBSTRING_FLAG|4)
-
-#define SMIME_OLDMIME 0x400
-#define SMIME_CRLFEOL 0x800
-#define SMIME_STREAM 0x1000
-
-struct X509_algor_st;
-DECLARE_STACK_OF(X509_ALGOR)
-
-#define DECLARE_ASN1_SET_OF(type) /* filled in by mkstack.pl */
-#define IMPLEMENT_ASN1_SET_OF(type) /* nothing, no longer needed */
-
-/* We MUST make sure that, except for constness, asn1_ctx_st and
- asn1_const_ctx are exactly the same. Fortunately, as soon as
- the old ASN1 parsing macros are gone, we can throw this away
- as well... */
-typedef struct asn1_ctx_st
- {
- unsigned char *p;/* work char pointer */
- int eos; /* end of sequence read for indefinite encoding */
- int error; /* error code to use when returning an error */
- int inf; /* constructed if 0x20, indefinite is 0x21 */
- int tag; /* tag from last 'get object' */
- int xclass; /* class from last 'get object' */
- long slen; /* length of last 'get object' */
- unsigned char *max; /* largest value of p allowed */
- unsigned char *q;/* temporary variable */
- unsigned char **pp;/* variable */
- int line; /* used in error processing */
- } ASN1_CTX;
-
-typedef struct asn1_const_ctx_st
- {
- const unsigned char *p;/* work char pointer */
- int eos; /* end of sequence read for indefinite encoding */
- int error; /* error code to use when returning an error */
- int inf; /* constructed if 0x20, indefinite is 0x21 */
- int tag; /* tag from last 'get object' */
- int xclass; /* class from last 'get object' */
- long slen; /* length of last 'get object' */
- const unsigned char *max; /* largest value of p allowed */
- const unsigned char *q;/* temporary variable */
- const unsigned char **pp;/* variable */
- int line; /* used in error processing */
- } ASN1_const_CTX;
-
-/* These are used internally in the ASN1_OBJECT to keep track of
- * whether the names and data need to be free()ed */
-#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */
-#define ASN1_OBJECT_FLAG_CRITICAL 0x02 /* critical x509v3 object id */
-#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04 /* internal use */
-#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08 /* internal use */
-typedef struct asn1_object_st
- {
- const char *sn,*ln;
- int nid;
- int length;
- const unsigned char *data; /* data remains const after init */
- int flags; /* Should we free this one */
- } ASN1_OBJECT;
-
-#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */
-/* This indicates that the ASN1_STRING is not a real value but just a place
- * holder for the location where indefinite length constructed data should
- * be inserted in the memory buffer
- */
-#define ASN1_STRING_FLAG_NDEF 0x010
-
-/* This flag is used by the CMS code to indicate that a string is not
- * complete and is a place holder for content when it had all been
- * accessed. The flag will be reset when content has been written to it.
- */
-
-#define ASN1_STRING_FLAG_CONT 0x020
-/* This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING
- * type.
- */
-#define ASN1_STRING_FLAG_MSTRING 0x040
-/* This is the base type that holds just about everything :-) */
-typedef struct asn1_string_st
- {
- int length;
- int type;
- unsigned char *data;
- /* The value of the following field depends on the type being
- * held. It is mostly being used for BIT_STRING so if the
- * input data has a non-zero 'unused bits' value, it will be
- * handled correctly */
- long flags;
- } ASN1_STRING;
-
-/* ASN1_ENCODING structure: this is used to save the received
- * encoding of an ASN1 type. This is useful to get round
- * problems with invalid encodings which can break signatures.
- */
-
-typedef struct ASN1_ENCODING_st
- {
- unsigned char *enc; /* DER encoding */
- long len; /* Length of encoding */
- int modified; /* set to 1 if 'enc' is invalid */
- } ASN1_ENCODING;
-
-/* Used with ASN1 LONG type: if a long is set to this it is omitted */
-#define ASN1_LONG_UNDEF 0x7fffffffL
-
-#define STABLE_FLAGS_MALLOC 0x01
-#define STABLE_NO_MASK 0x02
-#define DIRSTRING_TYPE \
- (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)
-#define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING)
-
-typedef struct asn1_string_table_st {
- int nid;
- long minsize;
- long maxsize;
- unsigned long mask;
- unsigned long flags;
-} ASN1_STRING_TABLE;
-
-DECLARE_STACK_OF(ASN1_STRING_TABLE)
-
-/* size limits: this stuff is taken straight from RFC2459 */
-
-#define ub_name 32768
-#define ub_common_name 64
-#define ub_locality_name 128
-#define ub_state_name 128
-#define ub_organization_name 64
-#define ub_organization_unit_name 64
-#define ub_title 64
-#define ub_email_address 128
-
-/* Declarations for template structures: for full definitions
- * see asn1t.h
- */
-typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
-typedef struct ASN1_ITEM_st ASN1_ITEM;
-typedef struct ASN1_TLC_st ASN1_TLC;
-/* This is just an opaque pointer */
-typedef struct ASN1_VALUE_st ASN1_VALUE;
-
-/* Declare ASN1 functions: the implement macro in in asn1t.h */
-
-#define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)
-
-#define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \
- DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type)
-
-#define DECLARE_ASN1_FUNCTIONS_name(type, name) \
- DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
- DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)
-
-#define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
- DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
- DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
-
-#define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
- type *d2i_##name(type **a, const unsigned char **in, long len); \
- int i2d_##name(type *a, unsigned char **out); \
- DECLARE_ASN1_ITEM(itname)
-
-#define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
- type *d2i_##name(type **a, const unsigned char **in, long len); \
- int i2d_##name(const type *a, unsigned char **out); \
- DECLARE_ASN1_ITEM(name)
-
-#define DECLARE_ASN1_NDEF_FUNCTION(name) \
- int i2d_##name##_NDEF(name *a, unsigned char **out);
-
-#define DECLARE_ASN1_FUNCTIONS_const(name) \
- DECLARE_ASN1_ALLOC_FUNCTIONS(name) \
- DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name)
-
-#define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
- type *name##_new(void); \
- void name##_free(type *a);
-
-#define DECLARE_ASN1_PRINT_FUNCTION(stname) \
- DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
-
-#define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
- int fname##_print_ctx(BIO *out, stname *x, int indent, \
- const ASN1_PCTX *pctx);
-
-#define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
-#define I2D_OF(type) int (*)(type *,unsigned char **)
-#define I2D_OF_const(type) int (*)(const type *,unsigned char **)
-
-#define CHECKED_D2I_OF(type, d2i) \
- ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0)))
-#define CHECKED_I2D_OF(type, i2d) \
- ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0)))
-#define CHECKED_NEW_OF(type, xnew) \
- ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0)))
-#define CHECKED_PTR_OF(type, p) \
- ((void*) (1 ? p : (type*)0))
-#define CHECKED_PPTR_OF(type, p) \
- ((void**) (1 ? p : (type**)0))
-
-#define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
-#define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
-#define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)
-
-TYPEDEF_D2I2D_OF(void);
-
-/* The following macros and typedefs allow an ASN1_ITEM
- * to be embedded in a structure and referenced. Since
- * the ASN1_ITEM pointers need to be globally accessible
- * (possibly from shared libraries) they may exist in
- * different forms. On platforms that support it the
- * ASN1_ITEM structure itself will be globally exported.
- * Other platforms will export a function that returns
- * an ASN1_ITEM pointer.
- *
- * To handle both cases transparently the macros below
- * should be used instead of hard coding an ASN1_ITEM
- * pointer in a structure.
- *
- * The structure will look like this:
- *
- * typedef struct SOMETHING_st {
- * ...
- * ASN1_ITEM_EXP *iptr;
- * ...
- * } SOMETHING;
- *
- * It would be initialised as e.g.:
- *
- * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...};
- *
- * and the actual pointer extracted with:
- *
- * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr);
- *
- * Finally an ASN1_ITEM pointer can be extracted from an
- * appropriate reference with: ASN1_ITEM_rptr(X509). This
- * would be used when a function takes an ASN1_ITEM * argument.
- *
- */
-
-#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
-
-/* ASN1_ITEM pointer exported type */
-typedef const ASN1_ITEM ASN1_ITEM_EXP;
-
-/* Macro to obtain ASN1_ITEM pointer from exported type */
-#define ASN1_ITEM_ptr(iptr) (iptr)
-
-/* Macro to include ASN1_ITEM pointer from base type */
-#define ASN1_ITEM_ref(iptr) (&(iptr##_it))
-
-#define ASN1_ITEM_rptr(ref) (&(ref##_it))
-
-#define DECLARE_ASN1_ITEM(name) \
- OPENSSL_EXTERN const ASN1_ITEM name##_it;
-
-#else
-
-/* Platforms that can't easily handle shared global variables are declared
- * as functions returning ASN1_ITEM pointers.
- */
-
-/* ASN1_ITEM pointer exported type */
-typedef const ASN1_ITEM * ASN1_ITEM_EXP(void);
-
-/* Macro to obtain ASN1_ITEM pointer from exported type */
-#define ASN1_ITEM_ptr(iptr) (iptr())
-
-/* Macro to include ASN1_ITEM pointer from base type */
-#define ASN1_ITEM_ref(iptr) (iptr##_it)
-
-#define ASN1_ITEM_rptr(ref) (ref##_it())
-
-#define DECLARE_ASN1_ITEM(name) \
- const ASN1_ITEM * name##_it(void);
-
-#endif
-
-/* Parameters used by ASN1_STRING_print_ex() */
-
-/* These determine which characters to escape:
- * RFC2253 special characters, control characters and
- * MSB set characters
- */
-
-#define ASN1_STRFLGS_ESC_2253 1
-#define ASN1_STRFLGS_ESC_CTRL 2
-#define ASN1_STRFLGS_ESC_MSB 4
-
-
-/* This flag determines how we do escaping: normally
- * RC2253 backslash only, set this to use backslash and
- * quote.
- */
-
-#define ASN1_STRFLGS_ESC_QUOTE 8
-
-
-/* These three flags are internal use only. */
-
-/* Character is a valid PrintableString character */
-#define CHARTYPE_PRINTABLESTRING 0x10
-/* Character needs escaping if it is the first character */
-#define CHARTYPE_FIRST_ESC_2253 0x20
-/* Character needs escaping if it is the last character */
-#define CHARTYPE_LAST_ESC_2253 0x40
-
-/* NB the internal flags are safely reused below by flags
- * handled at the top level.
- */
-
-/* If this is set we convert all character strings
- * to UTF8 first
- */
-
-#define ASN1_STRFLGS_UTF8_CONVERT 0x10
-
-/* If this is set we don't attempt to interpret content:
- * just assume all strings are 1 byte per character. This
- * will produce some pretty odd looking output!
- */
-
-#define ASN1_STRFLGS_IGNORE_TYPE 0x20
-
-/* If this is set we include the string type in the output */
-#define ASN1_STRFLGS_SHOW_TYPE 0x40
-
-/* This determines which strings to display and which to
- * 'dump' (hex dump of content octets or DER encoding). We can
- * only dump non character strings or everything. If we
- * don't dump 'unknown' they are interpreted as character
- * strings with 1 octet per character and are subject to
- * the usual escaping options.
- */
-
-#define ASN1_STRFLGS_DUMP_ALL 0x80
-#define ASN1_STRFLGS_DUMP_UNKNOWN 0x100
-
-/* These determine what 'dumping' does, we can dump the
- * content octets or the DER encoding: both use the
- * RFC2253 #XXXXX notation.
- */
-
-#define ASN1_STRFLGS_DUMP_DER 0x200
-
-/* All the string flags consistent with RFC2253,
- * escaping control characters isn't essential in
- * RFC2253 but it is advisable anyway.
- */
-
-#define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \
- ASN1_STRFLGS_ESC_CTRL | \
- ASN1_STRFLGS_ESC_MSB | \
- ASN1_STRFLGS_UTF8_CONVERT | \
- ASN1_STRFLGS_DUMP_UNKNOWN | \
- ASN1_STRFLGS_DUMP_DER)
-
-DECLARE_STACK_OF(ASN1_INTEGER)
-DECLARE_ASN1_SET_OF(ASN1_INTEGER)
-
-DECLARE_STACK_OF(ASN1_GENERALSTRING)
-
-typedef struct asn1_type_st
- {
- int type;
- union {
- char *ptr;
- ASN1_BOOLEAN boolean;
- ASN1_STRING * asn1_string;
- ASN1_OBJECT * object;
- ASN1_INTEGER * integer;
- ASN1_ENUMERATED * enumerated;
- ASN1_BIT_STRING * bit_string;
- ASN1_OCTET_STRING * octet_string;
- ASN1_PRINTABLESTRING * printablestring;
- ASN1_T61STRING * t61string;
- ASN1_IA5STRING * ia5string;
- ASN1_GENERALSTRING * generalstring;
- ASN1_BMPSTRING * bmpstring;
- ASN1_UNIVERSALSTRING * universalstring;
- ASN1_UTCTIME * utctime;
- ASN1_GENERALIZEDTIME * generalizedtime;
- ASN1_VISIBLESTRING * visiblestring;
- ASN1_UTF8STRING * utf8string;
- /* set and sequence are left complete and still
- * contain the set or sequence bytes */
- ASN1_STRING * set;
- ASN1_STRING * sequence;
- ASN1_VALUE * asn1_value;
- } value;
- } ASN1_TYPE;
-
-DECLARE_STACK_OF(ASN1_TYPE)
-DECLARE_ASN1_SET_OF(ASN1_TYPE)
-
-typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
-
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
-
-typedef struct NETSCAPE_X509_st
- {
- ASN1_OCTET_STRING *header;
- X509 *cert;
- } NETSCAPE_X509;
-
-/* This is used to contain a list of bit names */
-typedef struct BIT_STRING_BITNAME_st {
- int bitnum;
- const char *lname;
- const char *sname;
-} BIT_STRING_BITNAME;
-
-
-#define M_ASN1_STRING_length(x) ((x)->length)
-#define M_ASN1_STRING_length_set(x, n) ((x)->length = (n))
-#define M_ASN1_STRING_type(x) ((x)->type)
-#define M_ASN1_STRING_data(x) ((x)->data)
-
-/* Macros for string operations */
-#define M_ASN1_BIT_STRING_new() (ASN1_BIT_STRING *)\
- ASN1_STRING_type_new(V_ASN1_BIT_STRING)
-#define M_ASN1_BIT_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
- ASN1_STRING_dup((const ASN1_STRING *)a)
-#define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
- (const ASN1_STRING *)a,(const ASN1_STRING *)b)
-#define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
-
-#define M_ASN1_INTEGER_new() (ASN1_INTEGER *)\
- ASN1_STRING_type_new(V_ASN1_INTEGER)
-#define M_ASN1_INTEGER_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\
- ASN1_STRING_dup((const ASN1_STRING *)a)
-#define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\
- (const ASN1_STRING *)a,(const ASN1_STRING *)b)
-
-#define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\
- ASN1_STRING_type_new(V_ASN1_ENUMERATED)
-#define M_ASN1_ENUMERATED_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\
- ASN1_STRING_dup((const ASN1_STRING *)a)
-#define M_ASN1_ENUMERATED_cmp(a,b) ASN1_STRING_cmp(\
- (const ASN1_STRING *)a,(const ASN1_STRING *)b)
-
-#define M_ASN1_OCTET_STRING_new() (ASN1_OCTET_STRING *)\
- ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
-#define M_ASN1_OCTET_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
- ASN1_STRING_dup((const ASN1_STRING *)a)
-#define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
- (const ASN1_STRING *)a,(const ASN1_STRING *)b)
-#define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
-#define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b)
-#define M_i2d_ASN1_OCTET_STRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\
- V_ASN1_UNIVERSAL)
-
-#define B_ASN1_TIME \
- B_ASN1_UTCTIME | \
- B_ASN1_GENERALIZEDTIME
-
-#define B_ASN1_PRINTABLE \
- B_ASN1_NUMERICSTRING| \
- B_ASN1_PRINTABLESTRING| \
- B_ASN1_T61STRING| \
- B_ASN1_IA5STRING| \
- B_ASN1_BIT_STRING| \
- B_ASN1_UNIVERSALSTRING|\
- B_ASN1_BMPSTRING|\
- B_ASN1_UTF8STRING|\
- B_ASN1_SEQUENCE|\
- B_ASN1_UNKNOWN
-
-#define B_ASN1_DIRECTORYSTRING \
- B_ASN1_PRINTABLESTRING| \
- B_ASN1_TELETEXSTRING|\
- B_ASN1_BMPSTRING|\
- B_ASN1_UNIVERSALSTRING|\
- B_ASN1_UTF8STRING
-
-#define B_ASN1_DISPLAYTEXT \
- B_ASN1_IA5STRING| \
- B_ASN1_VISIBLESTRING| \
- B_ASN1_BMPSTRING|\
- B_ASN1_UTF8STRING
-
-#define M_ASN1_PRINTABLE_new() ASN1_STRING_type_new(V_ASN1_T61STRING)
-#define M_ASN1_PRINTABLE_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
- pp,a->type,V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_PRINTABLE(a,pp,l) \
- d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
- B_ASN1_PRINTABLE)
-
-#define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
-#define M_DIRECTORYSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
- pp,a->type,V_ASN1_UNIVERSAL)
-#define M_d2i_DIRECTORYSTRING(a,pp,l) \
- d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
- B_ASN1_DIRECTORYSTRING)
-
-#define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
-#define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
- pp,a->type,V_ASN1_UNIVERSAL)
-#define M_d2i_DISPLAYTEXT(a,pp,l) \
- d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
- B_ASN1_DISPLAYTEXT)
-
-#define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\
- ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
-#define M_ASN1_PRINTABLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_PRINTABLESTRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \
- (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING)
-
-#define M_ASN1_T61STRING_new() (ASN1_T61STRING *)\
- ASN1_STRING_type_new(V_ASN1_T61STRING)
-#define M_ASN1_T61STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_T61STRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_T61STRING(a,pp,l) \
- (ASN1_T61STRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING)
-
-#define M_ASN1_IA5STRING_new() (ASN1_IA5STRING *)\
- ASN1_STRING_type_new(V_ASN1_IA5STRING)
-#define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_IA5STRING_dup(a) \
- (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a)
-#define M_i2d_ASN1_IA5STRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_IA5STRING(a,pp,l) \
- (ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\
- B_ASN1_IA5STRING)
-
-#define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\
- ASN1_STRING_type_new(V_ASN1_UTCTIME)
-#define M_ASN1_UTCTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\
- ASN1_STRING_dup((const ASN1_STRING *)a)
-
-#define M_ASN1_GENERALIZEDTIME_new() (ASN1_GENERALIZEDTIME *)\
- ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
-#define M_ASN1_GENERALIZEDTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
- (const ASN1_STRING *)a)
-
-#define M_ASN1_TIME_new() (ASN1_TIME *)\
- ASN1_STRING_type_new(V_ASN1_UTCTIME)
-#define M_ASN1_TIME_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_TIME_dup(a) (ASN1_TIME *)\
- ASN1_STRING_dup((const ASN1_STRING *)a)
-
-#define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\
- ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
-#define M_ASN1_GENERALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_GENERALSTRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_GENERALSTRING(a,pp,l) \
- (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING)
-
-#define M_ASN1_UNIVERSALSTRING_new() (ASN1_UNIVERSALSTRING *)\
- ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING)
-#define M_ASN1_UNIVERSALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \
- (ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING)
-
-#define M_ASN1_BMPSTRING_new() (ASN1_BMPSTRING *)\
- ASN1_STRING_type_new(V_ASN1_BMPSTRING)
-#define M_ASN1_BMPSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_BMPSTRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_BMPSTRING(a,pp,l) \
- (ASN1_BMPSTRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING)
-
-#define M_ASN1_VISIBLESTRING_new() (ASN1_VISIBLESTRING *)\
- ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
-#define M_ASN1_VISIBLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_VISIBLESTRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \
- (ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING)
-
-#define M_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\
- ASN1_STRING_type_new(V_ASN1_UTF8STRING)
-#define M_ASN1_UTF8STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
-#define M_i2d_ASN1_UTF8STRING(a,pp) \
- i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\
- V_ASN1_UNIVERSAL)
-#define M_d2i_ASN1_UTF8STRING(a,pp,l) \
- (ASN1_UTF8STRING *)d2i_ASN1_type_bytes\
- ((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING)
-
- /* for the is_set parameter to i2d_ASN1_SET */
-#define IS_SEQUENCE 0
-#define IS_SET 1
-
-DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
-
-int ASN1_TYPE_get(ASN1_TYPE *a);
-void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
-int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
-int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
-
-ASN1_OBJECT * ASN1_OBJECT_new(void );
-void ASN1_OBJECT_free(ASN1_OBJECT *a);
-int i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp);
-ASN1_OBJECT * c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
- long length);
-ASN1_OBJECT * d2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
- long length);
-
-DECLARE_ASN1_ITEM(ASN1_OBJECT)
-
-DECLARE_STACK_OF(ASN1_OBJECT)
-DECLARE_ASN1_SET_OF(ASN1_OBJECT)
-
-ASN1_STRING * ASN1_STRING_new(void);
-void ASN1_STRING_free(ASN1_STRING *a);
-int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
-ASN1_STRING * ASN1_STRING_dup(const ASN1_STRING *a);
-ASN1_STRING * ASN1_STRING_type_new(int type );
-int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
- /* Since this is used to store all sorts of things, via macros, for now, make
- its data void * */
-int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
-void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
-int ASN1_STRING_length(const ASN1_STRING *x);
-void ASN1_STRING_length_set(ASN1_STRING *x, int n);
-int ASN1_STRING_type(ASN1_STRING *x);
-unsigned char * ASN1_STRING_data(ASN1_STRING *x);
-
-DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
-int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp);
-ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp,
- long length);
-int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d,
- int length );
-int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
-int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
-int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
- unsigned char *flags, int flags_len);
-
-#ifndef OPENSSL_NO_BIO
-int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
- BIT_STRING_BITNAME *tbl, int indent);
-#endif
-int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
-int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
- BIT_STRING_BITNAME *tbl);
-
-int i2d_ASN1_BOOLEAN(int a,unsigned char **pp);
-int d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length);
-
-DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
-int i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
-ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp,
- long length);
-ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp,
- long length);
-ASN1_INTEGER * ASN1_INTEGER_dup(const ASN1_INTEGER *x);
-int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
-
-DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
-
-int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
-ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t);
-ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
- int offset_day, long offset_sec);
-int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
-int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
-#if 0
-time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s);
-#endif
-
-int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a);
-ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t);
-ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
- time_t t, int offset_day, long offset_sec);
-int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
-
-DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
-ASN1_OCTET_STRING * ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
-int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b);
-int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len);
-
-DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
-DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)
-
-int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
-int UTF8_putc(unsigned char *str, int len, unsigned long value);
-
-DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
-
-DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
-DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
-DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
-DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
-DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
-DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
-
-DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
-
-ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
-ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t,
- int offset_day, long offset_sec);
-int ASN1_TIME_check(ASN1_TIME *t);
-ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
-int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
-
-int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
- i2d_of_void *i2d, int ex_tag, int ex_class,
- int is_set);
-STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
- const unsigned char **pp,
- long length, d2i_of_void *d2i,
- void (*free_func)(OPENSSL_BLOCK), int ex_tag,
- int ex_class);
-
-#ifndef OPENSSL_NO_BIO
-int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
-int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
-int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
-int a2i_ASN1_ENUMERATED(BIO *bp,ASN1_ENUMERATED *bs,char *buf,int size);
-int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a);
-int a2i_ASN1_STRING(BIO *bp,ASN1_STRING *bs,char *buf,int size);
-int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
-#endif
-int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a);
-
-int a2d_ASN1_OBJECT(unsigned char *out,int olen, const char *buf, int num);
-ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len,
- const char *sn, const char *ln);
-
-int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
-long ASN1_INTEGER_get(const ASN1_INTEGER *a);
-ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
-BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn);
-
-int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
-long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
-ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
-BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn);
-
-/* General */
-/* given a string, return the correct type, max is the maximum length */
-int ASN1_PRINTABLE_type(const unsigned char *s, int max);
-
-int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
-ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
- long length, int Ptag, int Pclass);
-unsigned long ASN1_tag2bit(int tag);
-/* type is one or more of the B_ASN1_ values. */
-ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,const unsigned char **pp,
- long length,int type);
-
-/* PARSING */
-int asn1_Finish(ASN1_CTX *c);
-int asn1_const_Finish(ASN1_const_CTX *c);
-
-/* SPECIALS */
-int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
- int *pclass, long omax);
-int ASN1_check_infinite_end(unsigned char **p,long len);
-int ASN1_const_check_infinite_end(const unsigned char **p,long len);
-void ASN1_put_object(unsigned char **pp, int constructed, int length,
- int tag, int xclass);
-int ASN1_put_eoc(unsigned char **pp);
-int ASN1_object_size(int constructed, int length, int tag);
-
-/* Used to implement other functions */
-void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
-
-#define ASN1_dup_of(type,i2d,d2i,x) \
- ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
- CHECKED_D2I_OF(type, d2i), \
- CHECKED_PTR_OF(type, x)))
-
-#define ASN1_dup_of_const(type,i2d,d2i,x) \
- ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
- CHECKED_D2I_OF(type, d2i), \
- CHECKED_PTR_OF(const type, x)))
-
-void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
-
-/* ASN1 alloc/free macros for when a type is only used internally */
-
-#define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type))
-#define M_ASN1_free_of(x, type) \
- ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type))
-
-#ifndef OPENSSL_NO_FP_API
-void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x);
-
-#define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
- ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \
- CHECKED_D2I_OF(type, d2i), \
- in, \
- CHECKED_PPTR_OF(type, x)))
-
-void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
-int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x);
-
-#define ASN1_i2d_fp_of(type,i2d,out,x) \
- (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
- out, \
- CHECKED_PTR_OF(type, x)))
-
-#define ASN1_i2d_fp_of_const(type,i2d,out,x) \
- (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \
- out, \
- CHECKED_PTR_OF(const type, x)))
-
-int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
-int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
-#endif
-
-int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
-
-#ifndef OPENSSL_NO_BIO
-void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x);
-
-#define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
- ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \
- CHECKED_D2I_OF(type, d2i), \
- in, \
- CHECKED_PPTR_OF(type, x)))
-
-void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
-int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x);
-
-#define ASN1_i2d_bio_of(type,i2d,out,x) \
- (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
- out, \
- CHECKED_PTR_OF(type, x)))
-
-#define ASN1_i2d_bio_of_const(type,i2d,out,x) \
- (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \
- out, \
- CHECKED_PTR_OF(const type, x)))
-
-int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
-int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
-int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
-int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
-int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
-int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
-int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
- unsigned char *buf, int off);
-int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
-int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
-#endif
-const char *ASN1_tag2str(int tag);
-
-/* Used to load and write netscape format cert */
-
-DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509)
-
-int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
-
-int ASN1_TYPE_set_octetstring(ASN1_TYPE *a,
- unsigned char *data, int len);
-int ASN1_TYPE_get_octetstring(ASN1_TYPE *a,
- unsigned char *data, int max_len);
-int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
- unsigned char *data, int len);
-int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num,
- unsigned char *data, int max_len);
-
-STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
- d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK));
-unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
- unsigned char **buf, int *len );
-void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
-void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
-ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d,
- ASN1_OCTET_STRING **oct);
-
-#define ASN1_pack_string_of(type,obj,i2d,oct) \
- (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \
- CHECKED_I2D_OF(type, i2d), \
- oct))
-
-ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);
-
-void ASN1_STRING_set_default_mask(unsigned long mask);
-int ASN1_STRING_set_default_mask_asc(const char *p);
-unsigned long ASN1_STRING_get_default_mask(void);
-int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
- int inform, unsigned long mask);
-int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
- int inform, unsigned long mask,
- long minsize, long maxsize);
-
-ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
- const unsigned char *in, int inlen, int inform, int nid);
-ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
-int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
-void ASN1_STRING_TABLE_cleanup(void);
-
-/* ASN1 template functions */
-
-/* Old API compatible functions */
-ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
-void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
-ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it);
-int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
-int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
-
-void ASN1_add_oid_module(void);
-
-ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
-ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
-
-/* ASN1 Print flags */
-
-/* Indicate missing OPTIONAL fields */
-#define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001
-/* Mark start and end of SEQUENCE */
-#define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002
-/* Mark start and end of SEQUENCE/SET OF */
-#define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004
-/* Show the ASN1 type of primitives */
-#define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008
-/* Don't show ASN1 type of ANY */
-#define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010
-/* Don't show ASN1 type of MSTRINGs */
-#define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020
-/* Don't show field names in SEQUENCE */
-#define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040
-/* Show structure names of each SEQUENCE field */
-#define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080
-/* Don't show structure name even at top level */
-#define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100
-
-int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
- const ASN1_ITEM *it, const ASN1_PCTX *pctx);
-ASN1_PCTX *ASN1_PCTX_new(void);
-void ASN1_PCTX_free(ASN1_PCTX *p);
-unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p);
-void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
-unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p);
-void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
-unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p);
-void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
-unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p);
-void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
-unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p);
-void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
-
-BIO_METHOD *BIO_f_asn1(void);
-
-BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
-
-int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
- const ASN1_ITEM *it);
-int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
- const char *hdr,
- const ASN1_ITEM *it);
-int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
- int ctype_nid, int econt_nid,
- STACK_OF(X509_ALGOR) *mdalgs,
- const ASN1_ITEM *it);
-ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
-int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
-int SMIME_text(BIO *in, BIO *out);
-
-/* BEGIN ERROR CODES */
-/* The following lines are auto generated by the script mkerr.pl. Any changes
- * made after this point may be overwritten when the script is next run.
- */
-void ERR_load_ASN1_strings(void);
-
-/* Error codes for the ASN1 functions. */
-
-/* Function codes. */
-#define ASN1_F_A2D_ASN1_OBJECT 100
-#define ASN1_F_A2I_ASN1_ENUMERATED 101
-#define ASN1_F_A2I_ASN1_INTEGER 102
-#define ASN1_F_A2I_ASN1_STRING 103
-#define ASN1_F_APPEND_EXP 176
-#define ASN1_F_ASN1_BIT_STRING_SET_BIT 183
-#define ASN1_F_ASN1_CB 177
-#define ASN1_F_ASN1_CHECK_TLEN 104
-#define ASN1_F_ASN1_COLLATE_PRIMITIVE 105
-#define ASN1_F_ASN1_COLLECT 106
-#define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108
-#define ASN1_F_ASN1_D2I_FP 109
-#define ASN1_F_ASN1_D2I_READ_BIO 107
-#define ASN1_F_ASN1_DIGEST 184
-#define ASN1_F_ASN1_DO_ADB 110
-#define ASN1_F_ASN1_DUP 111
-#define ASN1_F_ASN1_ENUMERATED_SET 112
-#define ASN1_F_ASN1_ENUMERATED_TO_BN 113
-#define ASN1_F_ASN1_EX_C2I 204
-#define ASN1_F_ASN1_FIND_END 190
-#define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216
-#define ASN1_F_ASN1_GENERALIZEDTIME_SET 185
-#define ASN1_F_ASN1_GENERATE_V3 178
-#define ASN1_F_ASN1_GET_OBJECT 114
-#define ASN1_F_ASN1_HEADER_NEW 115
-#define ASN1_F_ASN1_I2D_BIO 116
-#define ASN1_F_ASN1_I2D_FP 117
-#define ASN1_F_ASN1_INTEGER_SET 118
-#define ASN1_F_ASN1_INTEGER_TO_BN 119
-#define ASN1_F_ASN1_ITEM_D2I_FP 206
-#define ASN1_F_ASN1_ITEM_DUP 191
-#define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121
-#define ASN1_F_ASN1_ITEM_EX_D2I 120
-#define ASN1_F_ASN1_ITEM_I2D_BIO 192
-#define ASN1_F_ASN1_ITEM_I2D_FP 193
-#define ASN1_F_ASN1_ITEM_PACK 198
-#define ASN1_F_ASN1_ITEM_SIGN 195
-#define ASN1_F_ASN1_ITEM_UNPACK 199
-#define ASN1_F_ASN1_ITEM_VERIFY 197
-#define ASN1_F_ASN1_MBSTRING_NCOPY 122
-#define ASN1_F_ASN1_OBJECT_NEW 123
-#define ASN1_F_ASN1_OUTPUT_DATA 214
-#define ASN1_F_ASN1_PACK_STRING 124
-#define ASN1_F_ASN1_PCTX_NEW 205
-#define ASN1_F_ASN1_PKCS5_PBE_SET 125
-#define ASN1_F_ASN1_SEQ_PACK 126
-#define ASN1_F_ASN1_SEQ_UNPACK 127
-#define ASN1_F_ASN1_SIGN 128
-#define ASN1_F_ASN1_STR2TYPE 179
-#define ASN1_F_ASN1_STRING_SET 186
-#define ASN1_F_ASN1_STRING_TABLE_ADD 129
-#define ASN1_F_ASN1_STRING_TYPE_NEW 130
-#define ASN1_F_ASN1_TEMPLATE_EX_D2I 132
-#define ASN1_F_ASN1_TEMPLATE_NEW 133
-#define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131
-#define ASN1_F_ASN1_TIME_ADJ 217
-#define ASN1_F_ASN1_TIME_SET 175
-#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134
-#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135
-#define ASN1_F_ASN1_UNPACK_STRING 136
-#define ASN1_F_ASN1_UTCTIME_ADJ 218
-#define ASN1_F_ASN1_UTCTIME_SET 187
-#define ASN1_F_ASN1_VERIFY 137
-#define ASN1_F_B64_READ_ASN1 209
-#define ASN1_F_B64_WRITE_ASN1 210
-#define ASN1_F_BIO_NEW_NDEF 208
-#define ASN1_F_BITSTR_CB 180
-#define ASN1_F_BN_TO_ASN1_ENUMERATED 138
-#define ASN1_F_BN_TO_ASN1_INTEGER 139
-#define ASN1_F_C2I_ASN1_BIT_STRING 189
-#define ASN1_F_C2I_ASN1_INTEGER 194
-#define ASN1_F_C2I_ASN1_OBJECT 196
-#define ASN1_F_COLLECT_DATA 140
-#define ASN1_F_D2I_ASN1_BIT_STRING 141
-#define ASN1_F_D2I_ASN1_BOOLEAN 142
-#define ASN1_F_D2I_ASN1_BYTES 143
-#define ASN1_F_D2I_ASN1_GENERALIZEDTIME 144
-#define ASN1_F_D2I_ASN1_HEADER 145
-#define ASN1_F_D2I_ASN1_INTEGER 146
-#define ASN1_F_D2I_ASN1_OBJECT 147
-#define ASN1_F_D2I_ASN1_SET 148
-#define ASN1_F_D2I_ASN1_TYPE_BYTES 149
-#define ASN1_F_D2I_ASN1_UINTEGER 150
-#define ASN1_F_D2I_ASN1_UTCTIME 151
-#define ASN1_F_D2I_AUTOPRIVATEKEY 207
-#define ASN1_F_D2I_NETSCAPE_RSA 152
-#define ASN1_F_D2I_NETSCAPE_RSA_2 153
-#define ASN1_F_D2I_PRIVATEKEY 154
-#define ASN1_F_D2I_PUBLICKEY 155
-#define ASN1_F_D2I_RSA_NET 200
-#define ASN1_F_D2I_RSA_NET_2 201
-#define ASN1_F_D2I_X509 156
-#define ASN1_F_D2I_X509_CINF 157
-#define ASN1_F_D2I_X509_PKEY 159
-#define ASN1_F_I2D_ASN1_BIO_STREAM 211
-#define ASN1_F_I2D_ASN1_SET 188
-#define ASN1_F_I2D_ASN1_TIME 160
-#define ASN1_F_I2D_DSA_PUBKEY 161
-#define ASN1_F_I2D_EC_PUBKEY 181
-#define ASN1_F_I2D_PRIVATEKEY 163
-#define ASN1_F_I2D_PUBLICKEY 164
-#define ASN1_F_I2D_RSA_NET 162
-#define ASN1_F_I2D_RSA_PUBKEY 165
-#define ASN1_F_LONG_C2I 166
-#define ASN1_F_OID_MODULE_INIT 174
-#define ASN1_F_PARSE_TAGGING 182
-#define ASN1_F_PKCS5_PBE2_SET_IV 167
-#define ASN1_F_PKCS5_PBE_SET 202
-#define ASN1_F_PKCS5_PBE_SET0_ALGOR 215
-#define ASN1_F_SMIME_READ_ASN1 212
-#define ASN1_F_SMIME_TEXT 213
-#define ASN1_F_X509_CINF_NEW 168
-#define ASN1_F_X509_CRL_ADD0_REVOKED 169
-#define ASN1_F_X509_INFO_NEW 170
-#define ASN1_F_X509_NAME_ENCODE 203
-#define ASN1_F_X509_NAME_EX_D2I 158
-#define ASN1_F_X509_NAME_EX_NEW 171
-#define ASN1_F_X509_NEW 172
-#define ASN1_F_X509_PKEY_NEW 173
-
-/* Reason codes. */
-#define ASN1_R_ADDING_OBJECT 171
-#define ASN1_R_ASN1_PARSE_ERROR 203
-#define ASN1_R_ASN1_SIG_PARSE_ERROR 204
-#define ASN1_R_AUX_ERROR 100
-#define ASN1_R_BAD_CLASS 101
-#define ASN1_R_BAD_OBJECT_HEADER 102
-#define ASN1_R_BAD_PASSWORD_READ 103
-#define ASN1_R_BAD_TAG 104
-#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214
-#define ASN1_R_BN_LIB 105
-#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106
-#define ASN1_R_BUFFER_TOO_SMALL 107
-#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108
-#define ASN1_R_DATA_IS_WRONG 109
-#define ASN1_R_DECODE_ERROR 110
-#define ASN1_R_DECODING_ERROR 111
-#define ASN1_R_DEPTH_EXCEEDED 174
-#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198
-#define ASN1_R_ENCODE_ERROR 112
-#define ASN1_R_ERROR_GETTING_TIME 173
-#define ASN1_R_ERROR_LOADING_SECTION 172
-#define ASN1_R_ERROR_PARSING_SET_ELEMENT 113
-#define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114
-#define ASN1_R_EXPECTING_AN_INTEGER 115
-#define ASN1_R_EXPECTING_AN_OBJECT 116
-#define ASN1_R_EXPECTING_A_BOOLEAN 117
-#define ASN1_R_EXPECTING_A_TIME 118
-#define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119
-#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120
-#define ASN1_R_FIELD_MISSING 121
-#define ASN1_R_FIRST_NUM_TOO_LARGE 122
-#define ASN1_R_HEADER_TOO_LONG 123
-#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175
-#define ASN1_R_ILLEGAL_BOOLEAN 176
-#define ASN1_R_ILLEGAL_CHARACTERS 124
-#define ASN1_R_ILLEGAL_FORMAT 177
-#define ASN1_R_ILLEGAL_HEX 178
-#define ASN1_R_ILLEGAL_IMPLICIT_TAG 179
-#define ASN1_R_ILLEGAL_INTEGER 180
-#define ASN1_R_ILLEGAL_NESTED_TAGGING 181
-#define ASN1_R_ILLEGAL_NULL 125
-#define ASN1_R_ILLEGAL_NULL_VALUE 182
-#define ASN1_R_ILLEGAL_OBJECT 183
-#define ASN1_R_ILLEGAL_OPTIONAL_ANY 126
-#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170
-#define ASN1_R_ILLEGAL_TAGGED_ANY 127
-#define ASN1_R_ILLEGAL_TIME_VALUE 184
-#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185
-#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
-#define ASN1_R_INVALID_BMPSTRING_LENGTH 129
-#define ASN1_R_INVALID_DIGIT 130
-#define ASN1_R_INVALID_MIME_TYPE 205
-#define ASN1_R_INVALID_MODIFIER 186
-#define ASN1_R_INVALID_NUMBER 187
-#define ASN1_R_INVALID_OBJECT_ENCODING 216
-#define ASN1_R_INVALID_SEPARATOR 131
-#define ASN1_R_INVALID_TIME_FORMAT 132
-#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133
-#define ASN1_R_INVALID_UTF8STRING 134
-#define ASN1_R_IV_TOO_LARGE 135
-#define ASN1_R_LENGTH_ERROR 136
-#define ASN1_R_LIST_ERROR 188
-#define ASN1_R_MIME_NO_CONTENT_TYPE 206
-#define ASN1_R_MIME_PARSE_ERROR 207
-#define ASN1_R_MIME_SIG_PARSE_ERROR 208
-#define ASN1_R_MISSING_EOC 137
-#define ASN1_R_MISSING_SECOND_NUMBER 138
-#define ASN1_R_MISSING_VALUE 189
-#define ASN1_R_MSTRING_NOT_UNIVERSAL 139
-#define ASN1_R_MSTRING_WRONG_TAG 140
-#define ASN1_R_NESTED_ASN1_STRING 197
-#define ASN1_R_NON_HEX_CHARACTERS 141
-#define ASN1_R_NOT_ASCII_FORMAT 190
-#define ASN1_R_NOT_ENOUGH_DATA 142
-#define ASN1_R_NO_CONTENT_TYPE 209
-#define ASN1_R_NO_DEFAULT_DIGEST 201
-#define ASN1_R_NO_MATCHING_CHOICE_TYPE 143
-#define ASN1_R_NO_MULTIPART_BODY_FAILURE 210
-#define ASN1_R_NO_MULTIPART_BOUNDARY 211
-#define ASN1_R_NO_SIG_CONTENT_TYPE 212
-#define ASN1_R_NULL_IS_WRONG_LENGTH 144
-#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191
-#define ASN1_R_ODD_NUMBER_OF_CHARS 145
-#define ASN1_R_PRIVATE_KEY_HEADER_MISSING 146
-#define ASN1_R_SECOND_NUMBER_TOO_LARGE 147
-#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148
-#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149
-#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192
-#define ASN1_R_SHORT_LINE 150
-#define ASN1_R_SIG_INVALID_MIME_TYPE 213
-#define ASN1_R_STREAMING_NOT_SUPPORTED 202
-#define ASN1_R_STRING_TOO_LONG 151
-#define ASN1_R_STRING_TOO_SHORT 152
-#define ASN1_R_TAG_VALUE_TOO_HIGH 153
-#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154
-#define ASN1_R_TIME_NOT_ASCII_FORMAT 193
-#define ASN1_R_TOO_LONG 155
-#define ASN1_R_TYPE_NOT_CONSTRUCTED 156
-#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157
-#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158
-#define ASN1_R_UNEXPECTED_EOC 159
-#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215
-#define ASN1_R_UNKNOWN_FORMAT 160
-#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161
-#define ASN1_R_UNKNOWN_OBJECT_TYPE 162
-#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163
-#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199
-#define ASN1_R_UNKNOWN_TAG 194
-#define ASN1_R_UNKOWN_FORMAT 195
-#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164
-#define ASN1_R_UNSUPPORTED_CIPHER 165
-#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166
-#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167
-#define ASN1_R_UNSUPPORTED_TYPE 196
-#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200
-#define ASN1_R_WRONG_TAG 168
-#define ASN1_R_WRONG_TYPE 169
-
-#ifdef __cplusplus
-}
-#endif
-#endif
+/* crypto/asn1/asn1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ASN1_H
+#define HEADER_ASN1_H
+
+#include <time.h>
+#include <openssl/e_os2.h>
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/stack.h>
+#include <openssl/safestack.h>
+
+#include <openssl/symhacks.h>
+
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define V_ASN1_UNIVERSAL 0x00
+#define V_ASN1_APPLICATION 0x40
+#define V_ASN1_CONTEXT_SPECIFIC 0x80
+#define V_ASN1_PRIVATE 0xc0
+
+#define V_ASN1_CONSTRUCTED 0x20
+#define V_ASN1_PRIMITIVE_TAG 0x1f
+#define V_ASN1_PRIMATIVE_TAG 0x1f
+
+#define V_ASN1_APP_CHOOSE -2 /* let the recipient choose */
+#define V_ASN1_OTHER -3 /* used in ASN1_TYPE */
+#define V_ASN1_ANY -4 /* used in ASN1 template code */
+
+#define V_ASN1_NEG 0x100 /* negative flag */
+
+#define V_ASN1_UNDEF -1
+#define V_ASN1_EOC 0
+#define V_ASN1_BOOLEAN 1 /**/
+#define V_ASN1_INTEGER 2
+#define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG)
+#define V_ASN1_BIT_STRING 3
+#define V_ASN1_OCTET_STRING 4
+#define V_ASN1_NULL 5
+#define V_ASN1_OBJECT 6
+#define V_ASN1_OBJECT_DESCRIPTOR 7
+#define V_ASN1_EXTERNAL 8
+#define V_ASN1_REAL 9
+#define V_ASN1_ENUMERATED 10
+#define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG)
+#define V_ASN1_UTF8STRING 12
+#define V_ASN1_SEQUENCE 16
+#define V_ASN1_SET 17
+#define V_ASN1_NUMERICSTRING 18 /**/
+#define V_ASN1_PRINTABLESTRING 19
+#define V_ASN1_T61STRING 20
+#define V_ASN1_TELETEXSTRING 20 /* alias */
+#define V_ASN1_VIDEOTEXSTRING 21 /**/
+#define V_ASN1_IA5STRING 22
+#define V_ASN1_UTCTIME 23
+#define V_ASN1_GENERALIZEDTIME 24 /**/
+#define V_ASN1_GRAPHICSTRING 25 /**/
+#define V_ASN1_ISO64STRING 26 /**/
+#define V_ASN1_VISIBLESTRING 26 /* alias */
+#define V_ASN1_GENERALSTRING 27 /**/
+#define V_ASN1_UNIVERSALSTRING 28 /**/
+#define V_ASN1_BMPSTRING 30
+
+/* For use with d2i_ASN1_type_bytes() */
+#define B_ASN1_NUMERICSTRING 0x0001
+#define B_ASN1_PRINTABLESTRING 0x0002
+#define B_ASN1_T61STRING 0x0004
+#define B_ASN1_TELETEXSTRING 0x0004
+#define B_ASN1_VIDEOTEXSTRING 0x0008
+#define B_ASN1_IA5STRING 0x0010
+#define B_ASN1_GRAPHICSTRING 0x0020
+#define B_ASN1_ISO64STRING 0x0040
+#define B_ASN1_VISIBLESTRING 0x0040
+#define B_ASN1_GENERALSTRING 0x0080
+#define B_ASN1_UNIVERSALSTRING 0x0100
+#define B_ASN1_OCTET_STRING 0x0200
+#define B_ASN1_BIT_STRING 0x0400
+#define B_ASN1_BMPSTRING 0x0800
+#define B_ASN1_UNKNOWN 0x1000
+#define B_ASN1_UTF8STRING 0x2000
+#define B_ASN1_UTCTIME 0x4000
+#define B_ASN1_GENERALIZEDTIME 0x8000
+#define B_ASN1_SEQUENCE 0x10000
+
+/* For use with ASN1_mbstring_copy() */
+#define MBSTRING_FLAG 0x1000
+#define MBSTRING_UTF8 (MBSTRING_FLAG)
+#define MBSTRING_ASC (MBSTRING_FLAG|1)
+#define MBSTRING_BMP (MBSTRING_FLAG|2)
+#define MBSTRING_UNIV (MBSTRING_FLAG|4)
+
+#define SMIME_OLDMIME 0x400
+#define SMIME_CRLFEOL 0x800
+#define SMIME_STREAM 0x1000
+
+struct X509_algor_st;
+DECLARE_STACK_OF(X509_ALGOR)
+
+#define DECLARE_ASN1_SET_OF(type) /* filled in by mkstack.pl */
+#define IMPLEMENT_ASN1_SET_OF(type) /* nothing, no longer needed */
+
+/* We MUST make sure that, except for constness, asn1_ctx_st and
+ asn1_const_ctx are exactly the same. Fortunately, as soon as
+ the old ASN1 parsing macros are gone, we can throw this away
+ as well... */
+typedef struct asn1_ctx_st
+ {
+ unsigned char *p;/* work char pointer */
+ int eos; /* end of sequence read for indefinite encoding */
+ int error; /* error code to use when returning an error */
+ int inf; /* constructed if 0x20, indefinite is 0x21 */
+ int tag; /* tag from last 'get object' */
+ int xclass; /* class from last 'get object' */
+ long slen; /* length of last 'get object' */
+ unsigned char *max; /* largest value of p allowed */
+ unsigned char *q;/* temporary variable */
+ unsigned char **pp;/* variable */
+ int line; /* used in error processing */
+ } ASN1_CTX;
+
+typedef struct asn1_const_ctx_st
+ {
+ const unsigned char *p;/* work char pointer */
+ int eos; /* end of sequence read for indefinite encoding */
+ int error; /* error code to use when returning an error */
+ int inf; /* constructed if 0x20, indefinite is 0x21 */
+ int tag; /* tag from last 'get object' */
+ int xclass; /* class from last 'get object' */
+ long slen; /* length of last 'get object' */
+ const unsigned char *max; /* largest value of p allowed */
+ const unsigned char *q;/* temporary variable */
+ const unsigned char **pp;/* variable */
+ int line; /* used in error processing */
+ } ASN1_const_CTX;
+
+/* These are used internally in the ASN1_OBJECT to keep track of
+ * whether the names and data need to be free()ed */
+#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */
+#define ASN1_OBJECT_FLAG_CRITICAL 0x02 /* critical x509v3 object id */
+#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04 /* internal use */
+#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08 /* internal use */
+typedef struct asn1_object_st
+ {
+ const char *sn,*ln;
+ int nid;
+ int length;
+ const unsigned char *data; /* data remains const after init */
+ int flags; /* Should we free this one */
+ } ASN1_OBJECT;
+
+#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */
+/* This indicates that the ASN1_STRING is not a real value but just a place
+ * holder for the location where indefinite length constructed data should
+ * be inserted in the memory buffer
+ */
+#define ASN1_STRING_FLAG_NDEF 0x010
+
+/* This flag is used by the CMS code to indicate that a string is not
+ * complete and is a place holder for content when it had all been
+ * accessed. The flag will be reset when content has been written to it.
+ */
+
+#define ASN1_STRING_FLAG_CONT 0x020
+/* This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING
+ * type.
+ */
+#define ASN1_STRING_FLAG_MSTRING 0x040
+/* This is the base type that holds just about everything :-) */
+typedef struct asn1_string_st
+ {
+ int length;
+ int type;
+ unsigned char *data;
+ /* The value of the following field depends on the type being
+ * held. It is mostly being used for BIT_STRING so if the
+ * input data has a non-zero 'unused bits' value, it will be
+ * handled correctly */
+ long flags;
+ } ASN1_STRING;
+
+/* ASN1_ENCODING structure: this is used to save the received
+ * encoding of an ASN1 type. This is useful to get round
+ * problems with invalid encodings which can break signatures.
+ */
+
+typedef struct ASN1_ENCODING_st
+ {
+ unsigned char *enc; /* DER encoding */
+ long len; /* Length of encoding */
+ int modified; /* set to 1 if 'enc' is invalid */
+ } ASN1_ENCODING;
+
+/* Used with ASN1 LONG type: if a long is set to this it is omitted */
+#define ASN1_LONG_UNDEF 0x7fffffffL
+
+#define STABLE_FLAGS_MALLOC 0x01
+#define STABLE_NO_MASK 0x02
+#define DIRSTRING_TYPE \
+ (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)
+#define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING)
+
+typedef struct asn1_string_table_st {
+ int nid;
+ long minsize;
+ long maxsize;
+ unsigned long mask;
+ unsigned long flags;
+} ASN1_STRING_TABLE;
+
+DECLARE_STACK_OF(ASN1_STRING_TABLE)
+
+/* size limits: this stuff is taken straight from RFC2459 */
+
+#define ub_name 32768
+#define ub_common_name 64
+#define ub_locality_name 128
+#define ub_state_name 128
+#define ub_organization_name 64
+#define ub_organization_unit_name 64
+#define ub_title 64
+#define ub_email_address 128
+
+/* Declarations for template structures: for full definitions
+ * see asn1t.h
+ */
+typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
+typedef struct ASN1_ITEM_st ASN1_ITEM;
+typedef struct ASN1_TLC_st ASN1_TLC;
+/* This is just an opaque pointer */
+typedef struct ASN1_VALUE_st ASN1_VALUE;
+
+/* Declare ASN1 functions: the implement macro in in asn1t.h */
+
+#define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)
+
+#define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \
+ DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type)
+
+#define DECLARE_ASN1_FUNCTIONS_name(type, name) \
+ DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+ DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)
+
+#define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
+ DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+ DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
+
+#define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
+ type *d2i_##name(type **a, const unsigned char **in, long len); \
+ int i2d_##name(type *a, unsigned char **out); \
+ DECLARE_ASN1_ITEM(itname)
+
+#define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
+ type *d2i_##name(type **a, const unsigned char **in, long len); \
+ int i2d_##name(const type *a, unsigned char **out); \
+ DECLARE_ASN1_ITEM(name)
+
+#define DECLARE_ASN1_NDEF_FUNCTION(name) \
+ int i2d_##name##_NDEF(name *a, unsigned char **out);
+
+#define DECLARE_ASN1_FUNCTIONS_const(name) \
+ DECLARE_ASN1_ALLOC_FUNCTIONS(name) \
+ DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name)
+
+#define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+ type *name##_new(void); \
+ void name##_free(type *a);
+
+#define DECLARE_ASN1_PRINT_FUNCTION(stname) \
+ DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
+
+#define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
+ int fname##_print_ctx(BIO *out, stname *x, int indent, \
+ const ASN1_PCTX *pctx);
+
+#define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
+#define I2D_OF(type) int (*)(type *,unsigned char **)
+#define I2D_OF_const(type) int (*)(const type *,unsigned char **)
+
+#define CHECKED_D2I_OF(type, d2i) \
+ ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0)))
+#define CHECKED_I2D_OF(type, i2d) \
+ ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0)))
+#define CHECKED_NEW_OF(type, xnew) \
+ ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0)))
+#define CHECKED_PTR_OF(type, p) \
+ ((void*) (1 ? p : (type*)0))
+#define CHECKED_PPTR_OF(type, p) \
+ ((void**) (1 ? p : (type**)0))
+
+#define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
+#define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
+#define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)
+
+TYPEDEF_D2I2D_OF(void);
+
+/* The following macros and typedefs allow an ASN1_ITEM
+ * to be embedded in a structure and referenced. Since
+ * the ASN1_ITEM pointers need to be globally accessible
+ * (possibly from shared libraries) they may exist in
+ * different forms. On platforms that support it the
+ * ASN1_ITEM structure itself will be globally exported.
+ * Other platforms will export a function that returns
+ * an ASN1_ITEM pointer.
+ *
+ * To handle both cases transparently the macros below
+ * should be used instead of hard coding an ASN1_ITEM
+ * pointer in a structure.
+ *
+ * The structure will look like this:
+ *
+ * typedef struct SOMETHING_st {
+ * ...
+ * ASN1_ITEM_EXP *iptr;
+ * ...
+ * } SOMETHING;
+ *
+ * It would be initialised as e.g.:
+ *
+ * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...};
+ *
+ * and the actual pointer extracted with:
+ *
+ * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr);
+ *
+ * Finally an ASN1_ITEM pointer can be extracted from an
+ * appropriate reference with: ASN1_ITEM_rptr(X509). This
+ * would be used when a function takes an ASN1_ITEM * argument.
+ *
+ */
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM ASN1_ITEM_EXP;
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#define ASN1_ITEM_ptr(iptr) (iptr)
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#define ASN1_ITEM_ref(iptr) (&(iptr##_it))
+
+#define ASN1_ITEM_rptr(ref) (&(ref##_it))
+
+#define DECLARE_ASN1_ITEM(name) \
+ OPENSSL_EXTERN const ASN1_ITEM name##_it;
+
+#else
+
+/* Platforms that can't easily handle shared global variables are declared
+ * as functions returning ASN1_ITEM pointers.
+ */
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM * ASN1_ITEM_EXP(void);
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#define ASN1_ITEM_ptr(iptr) (iptr())
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#define ASN1_ITEM_ref(iptr) (iptr##_it)
+
+#define ASN1_ITEM_rptr(ref) (ref##_it())
+
+#define DECLARE_ASN1_ITEM(name) \
+ const ASN1_ITEM * name##_it(void);
+
+#endif
+
+/* Parameters used by ASN1_STRING_print_ex() */
+
+/* These determine which characters to escape:
+ * RFC2253 special characters, control characters and
+ * MSB set characters
+ */
+
+#define ASN1_STRFLGS_ESC_2253 1
+#define ASN1_STRFLGS_ESC_CTRL 2
+#define ASN1_STRFLGS_ESC_MSB 4
+
+
+/* This flag determines how we do escaping: normally
+ * RC2253 backslash only, set this to use backslash and
+ * quote.
+ */
+
+#define ASN1_STRFLGS_ESC_QUOTE 8
+
+
+/* These three flags are internal use only. */
+
+/* Character is a valid PrintableString character */
+#define CHARTYPE_PRINTABLESTRING 0x10
+/* Character needs escaping if it is the first character */
+#define CHARTYPE_FIRST_ESC_2253 0x20
+/* Character needs escaping if it is the last character */
+#define CHARTYPE_LAST_ESC_2253 0x40
+
+/* NB the internal flags are safely reused below by flags
+ * handled at the top level.
+ */
+
+/* If this is set we convert all character strings
+ * to UTF8 first
+ */
+
+#define ASN1_STRFLGS_UTF8_CONVERT 0x10
+
+/* If this is set we don't attempt to interpret content:
+ * just assume all strings are 1 byte per character. This
+ * will produce some pretty odd looking output!
+ */
+
+#define ASN1_STRFLGS_IGNORE_TYPE 0x20
+
+/* If this is set we include the string type in the output */
+#define ASN1_STRFLGS_SHOW_TYPE 0x40
+
+/* This determines which strings to display and which to
+ * 'dump' (hex dump of content octets or DER encoding). We can
+ * only dump non character strings or everything. If we
+ * don't dump 'unknown' they are interpreted as character
+ * strings with 1 octet per character and are subject to
+ * the usual escaping options.
+ */
+
+#define ASN1_STRFLGS_DUMP_ALL 0x80
+#define ASN1_STRFLGS_DUMP_UNKNOWN 0x100
+
+/* These determine what 'dumping' does, we can dump the
+ * content octets or the DER encoding: both use the
+ * RFC2253 #XXXXX notation.
+ */
+
+#define ASN1_STRFLGS_DUMP_DER 0x200
+
+/* All the string flags consistent with RFC2253,
+ * escaping control characters isn't essential in
+ * RFC2253 but it is advisable anyway.
+ */
+
+#define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \
+ ASN1_STRFLGS_ESC_CTRL | \
+ ASN1_STRFLGS_ESC_MSB | \
+ ASN1_STRFLGS_UTF8_CONVERT | \
+ ASN1_STRFLGS_DUMP_UNKNOWN | \
+ ASN1_STRFLGS_DUMP_DER)
+
+DECLARE_STACK_OF(ASN1_INTEGER)
+DECLARE_ASN1_SET_OF(ASN1_INTEGER)
+
+DECLARE_STACK_OF(ASN1_GENERALSTRING)
+
+typedef struct asn1_type_st
+ {
+ int type;
+ union {
+ char *ptr;
+ ASN1_BOOLEAN boolean;
+ ASN1_STRING * asn1_string;
+ ASN1_OBJECT * object;
+ ASN1_INTEGER * integer;
+ ASN1_ENUMERATED * enumerated;
+ ASN1_BIT_STRING * bit_string;
+ ASN1_OCTET_STRING * octet_string;
+ ASN1_PRINTABLESTRING * printablestring;
+ ASN1_T61STRING * t61string;
+ ASN1_IA5STRING * ia5string;
+ ASN1_GENERALSTRING * generalstring;
+ ASN1_BMPSTRING * bmpstring;
+ ASN1_UNIVERSALSTRING * universalstring;
+ ASN1_UTCTIME * utctime;
+ ASN1_GENERALIZEDTIME * generalizedtime;
+ ASN1_VISIBLESTRING * visiblestring;
+ ASN1_UTF8STRING * utf8string;
+ /* set and sequence are left complete and still
+ * contain the set or sequence bytes */
+ ASN1_STRING * set;
+ ASN1_STRING * sequence;
+ ASN1_VALUE * asn1_value;
+ } value;
+ } ASN1_TYPE;
+
+DECLARE_STACK_OF(ASN1_TYPE)
+DECLARE_ASN1_SET_OF(ASN1_TYPE)
+
+typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
+
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
+
+typedef struct NETSCAPE_X509_st
+ {
+ ASN1_OCTET_STRING *header;
+ X509 *cert;
+ } NETSCAPE_X509;
+
+/* This is used to contain a list of bit names */
+typedef struct BIT_STRING_BITNAME_st {
+ int bitnum;
+ const char *lname;
+ const char *sname;
+} BIT_STRING_BITNAME;
+
+
+#define M_ASN1_STRING_length(x) ((x)->length)
+#define M_ASN1_STRING_length_set(x, n) ((x)->length = (n))
+#define M_ASN1_STRING_type(x) ((x)->type)
+#define M_ASN1_STRING_data(x) ((x)->data)
+
+/* Macros for string operations */
+#define M_ASN1_BIT_STRING_new() (ASN1_BIT_STRING *)\
+ ASN1_STRING_type_new(V_ASN1_BIT_STRING)
+#define M_ASN1_BIT_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
+ ASN1_STRING_dup((const ASN1_STRING *)a)
+#define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
+ (const ASN1_STRING *)a,(const ASN1_STRING *)b)
+#define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
+
+#define M_ASN1_INTEGER_new() (ASN1_INTEGER *)\
+ ASN1_STRING_type_new(V_ASN1_INTEGER)
+#define M_ASN1_INTEGER_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\
+ ASN1_STRING_dup((const ASN1_STRING *)a)
+#define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\
+ (const ASN1_STRING *)a,(const ASN1_STRING *)b)
+
+#define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\
+ ASN1_STRING_type_new(V_ASN1_ENUMERATED)
+#define M_ASN1_ENUMERATED_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\
+ ASN1_STRING_dup((const ASN1_STRING *)a)
+#define M_ASN1_ENUMERATED_cmp(a,b) ASN1_STRING_cmp(\
+ (const ASN1_STRING *)a,(const ASN1_STRING *)b)
+
+#define M_ASN1_OCTET_STRING_new() (ASN1_OCTET_STRING *)\
+ ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
+#define M_ASN1_OCTET_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
+ ASN1_STRING_dup((const ASN1_STRING *)a)
+#define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
+ (const ASN1_STRING *)a,(const ASN1_STRING *)b)
+#define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
+#define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b)
+#define M_i2d_ASN1_OCTET_STRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\
+ V_ASN1_UNIVERSAL)
+
+#define B_ASN1_TIME \
+ B_ASN1_UTCTIME | \
+ B_ASN1_GENERALIZEDTIME
+
+#define B_ASN1_PRINTABLE \
+ B_ASN1_NUMERICSTRING| \
+ B_ASN1_PRINTABLESTRING| \
+ B_ASN1_T61STRING| \
+ B_ASN1_IA5STRING| \
+ B_ASN1_BIT_STRING| \
+ B_ASN1_UNIVERSALSTRING|\
+ B_ASN1_BMPSTRING|\
+ B_ASN1_UTF8STRING|\
+ B_ASN1_SEQUENCE|\
+ B_ASN1_UNKNOWN
+
+#define B_ASN1_DIRECTORYSTRING \
+ B_ASN1_PRINTABLESTRING| \
+ B_ASN1_TELETEXSTRING|\
+ B_ASN1_BMPSTRING|\
+ B_ASN1_UNIVERSALSTRING|\
+ B_ASN1_UTF8STRING
+
+#define B_ASN1_DISPLAYTEXT \
+ B_ASN1_IA5STRING| \
+ B_ASN1_VISIBLESTRING| \
+ B_ASN1_BMPSTRING|\
+ B_ASN1_UTF8STRING
+
+#define M_ASN1_PRINTABLE_new() ASN1_STRING_type_new(V_ASN1_T61STRING)
+#define M_ASN1_PRINTABLE_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+ pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_PRINTABLE(a,pp,l) \
+ d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+ B_ASN1_PRINTABLE)
+
+#define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+#define M_DIRECTORYSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+ pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_DIRECTORYSTRING(a,pp,l) \
+ d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+ B_ASN1_DIRECTORYSTRING)
+
+#define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+#define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+ pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_DISPLAYTEXT(a,pp,l) \
+ d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+ B_ASN1_DISPLAYTEXT)
+
+#define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\
+ ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+#define M_ASN1_PRINTABLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_PRINTABLESTRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\
+ V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \
+ (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING)
+
+#define M_ASN1_T61STRING_new() (ASN1_T61STRING *)\
+ ASN1_STRING_type_new(V_ASN1_T61STRING)
+#define M_ASN1_T61STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_T61STRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\
+ V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_T61STRING(a,pp,l) \
+ (ASN1_T61STRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING)
+
+#define M_ASN1_IA5STRING_new() (ASN1_IA5STRING *)\
+ ASN1_STRING_type_new(V_ASN1_IA5STRING)
+#define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_IA5STRING_dup(a) \
+ (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a)
+#define M_i2d_ASN1_IA5STRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
+ V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_IA5STRING(a,pp,l) \
+ (ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\
+ B_ASN1_IA5STRING)
+
+#define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\
+ ASN1_STRING_type_new(V_ASN1_UTCTIME)
+#define M_ASN1_UTCTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\
+ ASN1_STRING_dup((const ASN1_STRING *)a)
+
+#define M_ASN1_GENERALIZEDTIME_new() (ASN1_GENERALIZEDTIME *)\
+ ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
+#define M_ASN1_GENERALIZEDTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
+ (const ASN1_STRING *)a)
+
+#define M_ASN1_TIME_new() (ASN1_TIME *)\
+ ASN1_STRING_type_new(V_ASN1_UTCTIME)
+#define M_ASN1_TIME_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_TIME_dup(a) (ASN1_TIME *)\
+ ASN1_STRING_dup((const ASN1_STRING *)a)
+
+#define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\
+ ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
+#define M_ASN1_GENERALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_GENERALSTRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\
+ V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_GENERALSTRING(a,pp,l) \
+ (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING)
+
+#define M_ASN1_UNIVERSALSTRING_new() (ASN1_UNIVERSALSTRING *)\
+ ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING)
+#define M_ASN1_UNIVERSALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\
+ V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \
+ (ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING)
+
+#define M_ASN1_BMPSTRING_new() (ASN1_BMPSTRING *)\
+ ASN1_STRING_type_new(V_ASN1_BMPSTRING)
+#define M_ASN1_BMPSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_BMPSTRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\
+ V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_BMPSTRING(a,pp,l) \
+ (ASN1_BMPSTRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING)
+
+#define M_ASN1_VISIBLESTRING_new() (ASN1_VISIBLESTRING *)\
+ ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+#define M_ASN1_VISIBLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_VISIBLESTRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\
+ V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \
+ (ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING)
+
+#define M_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\
+ ASN1_STRING_type_new(V_ASN1_UTF8STRING)
+#define M_ASN1_UTF8STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_UTF8STRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\
+ V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_UTF8STRING(a,pp,l) \
+ (ASN1_UTF8STRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING)
+
+ /* for the is_set parameter to i2d_ASN1_SET */
+#define IS_SEQUENCE 0
+#define IS_SET 1
+
+DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+
+int ASN1_TYPE_get(ASN1_TYPE *a);
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
+
+ASN1_OBJECT * ASN1_OBJECT_new(void );
+void ASN1_OBJECT_free(ASN1_OBJECT *a);
+int i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp);
+ASN1_OBJECT * c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
+ long length);
+ASN1_OBJECT * d2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
+ long length);
+
+DECLARE_ASN1_ITEM(ASN1_OBJECT)
+
+DECLARE_STACK_OF(ASN1_OBJECT)
+DECLARE_ASN1_SET_OF(ASN1_OBJECT)
+
+ASN1_STRING * ASN1_STRING_new(void);
+void ASN1_STRING_free(ASN1_STRING *a);
+int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
+ASN1_STRING * ASN1_STRING_dup(const ASN1_STRING *a);
+ASN1_STRING * ASN1_STRING_type_new(int type );
+int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
+ /* Since this is used to store all sorts of things, via macros, for now, make
+ its data void * */
+int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
+void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
+int ASN1_STRING_length(const ASN1_STRING *x);
+void ASN1_STRING_length_set(ASN1_STRING *x, int n);
+int ASN1_STRING_type(ASN1_STRING *x);
+unsigned char * ASN1_STRING_data(ASN1_STRING *x);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
+int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp);
+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp,
+ long length);
+int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d,
+ int length );
+int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
+int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
+int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
+ unsigned char *flags, int flags_len);
+
+#ifndef OPENSSL_NO_BIO
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+ BIT_STRING_BITNAME *tbl, int indent);
+#endif
+int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
+ BIT_STRING_BITNAME *tbl);
+
+int i2d_ASN1_BOOLEAN(int a,unsigned char **pp);
+int d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
+int i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp,
+ long length);
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp,
+ long length);
+ASN1_INTEGER * ASN1_INTEGER_dup(const ASN1_INTEGER *x);
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
+
+int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t);
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+ int offset_day, long offset_sec);
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
+#if 0
+time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s);
+#endif
+
+int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+ time_t t, int offset_day, long offset_sec);
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
+ASN1_OCTET_STRING * ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b);
+int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
+DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
+int UTF8_putc(unsigned char *str, int len, unsigned long value);
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
+DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
+
+DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
+
+ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t,
+ int offset_day, long offset_sec);
+int ASN1_TIME_check(ASN1_TIME *t);
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
+
+int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
+ i2d_of_void *i2d, int ex_tag, int ex_class,
+ int is_set);
+STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
+ const unsigned char **pp,
+ long length, d2i_of_void *d2i,
+ void (*free_func)(OPENSSL_BLOCK), int ex_tag,
+ int ex_class);
+
+#ifndef OPENSSL_NO_BIO
+int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
+int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
+int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
+int a2i_ASN1_ENUMERATED(BIO *bp,ASN1_ENUMERATED *bs,char *buf,int size);
+int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a);
+int a2i_ASN1_STRING(BIO *bp,ASN1_STRING *bs,char *buf,int size);
+int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
+#endif
+int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a);
+
+int a2d_ASN1_OBJECT(unsigned char *out,int olen, const char *buf, int num);
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len,
+ const char *sn, const char *ln);
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
+long ASN1_INTEGER_get(const ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn);
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
+long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
+BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn);
+
+/* General */
+/* given a string, return the correct type, max is the maximum length */
+int ASN1_PRINTABLE_type(const unsigned char *s, int max);
+
+int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
+ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
+ long length, int Ptag, int Pclass);
+unsigned long ASN1_tag2bit(int tag);
+/* type is one or more of the B_ASN1_ values. */
+ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,const unsigned char **pp,
+ long length,int type);
+
+/* PARSING */
+int asn1_Finish(ASN1_CTX *c);
+int asn1_const_Finish(ASN1_const_CTX *c);
+
+/* SPECIALS */
+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+ int *pclass, long omax);
+int ASN1_check_infinite_end(unsigned char **p,long len);
+int ASN1_const_check_infinite_end(const unsigned char **p,long len);
+void ASN1_put_object(unsigned char **pp, int constructed, int length,
+ int tag, int xclass);
+int ASN1_put_eoc(unsigned char **pp);
+int ASN1_object_size(int constructed, int length, int tag);
+
+/* Used to implement other functions */
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
+
+#define ASN1_dup_of(type,i2d,d2i,x) \
+ ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
+ CHECKED_D2I_OF(type, d2i), \
+ CHECKED_PTR_OF(type, x)))
+
+#define ASN1_dup_of_const(type,i2d,d2i,x) \
+ ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
+ CHECKED_D2I_OF(type, d2i), \
+ CHECKED_PTR_OF(const type, x)))
+
+void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
+
+/* ASN1 alloc/free macros for when a type is only used internally */
+
+#define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type))
+#define M_ASN1_free_of(x, type) \
+ ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type))
+
+#ifndef OPENSSL_NO_FP_API
+void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x);
+
+#define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
+ ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \
+ CHECKED_D2I_OF(type, d2i), \
+ in, \
+ CHECKED_PPTR_OF(type, x)))
+
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
+int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x);
+
+#define ASN1_i2d_fp_of(type,i2d,out,x) \
+ (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
+ out, \
+ CHECKED_PTR_OF(type, x)))
+
+#define ASN1_i2d_fp_of_const(type,i2d,out,x) \
+ (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \
+ out, \
+ CHECKED_PTR_OF(const type, x)))
+
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
+int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
+#endif
+
+int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
+
+#ifndef OPENSSL_NO_BIO
+void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x);
+
+#define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
+ ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \
+ CHECKED_D2I_OF(type, d2i), \
+ in, \
+ CHECKED_PPTR_OF(type, x)))
+
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
+int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x);
+
+#define ASN1_i2d_bio_of(type,i2d,out,x) \
+ (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
+ out, \
+ CHECKED_PTR_OF(type, x)))
+
+#define ASN1_i2d_bio_of_const(type,i2d,out,x) \
+ (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \
+ out, \
+ CHECKED_PTR_OF(const type, x)))
+
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
+int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
+int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
+int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
+int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+ unsigned char *buf, int off);
+int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
+int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
+#endif
+const char *ASN1_tag2str(int tag);
+
+/* Used to load and write netscape format cert */
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509)
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a,
+ unsigned char *data, int len);
+int ASN1_TYPE_get_octetstring(ASN1_TYPE *a,
+ unsigned char *data, int max_len);
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
+ unsigned char *data, int len);
+int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num,
+ unsigned char *data, int max_len);
+
+STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
+ d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK));
+unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
+ unsigned char **buf, int *len );
+void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
+void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
+ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d,
+ ASN1_OCTET_STRING **oct);
+
+#define ASN1_pack_string_of(type,obj,i2d,oct) \
+ (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \
+ CHECKED_I2D_OF(type, i2d), \
+ oct))
+
+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);
+
+void ASN1_STRING_set_default_mask(unsigned long mask);
+int ASN1_STRING_set_default_mask_asc(const char *p);
+unsigned long ASN1_STRING_get_default_mask(void);
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+ int inform, unsigned long mask);
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+ int inform, unsigned long mask,
+ long minsize, long maxsize);
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
+ const unsigned char *in, int inlen, int inform, int nid);
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
+int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
+void ASN1_STRING_TABLE_cleanup(void);
+
+/* ASN1 template functions */
+
+/* Old API compatible functions */
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
+ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it);
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+
+void ASN1_add_oid_module(void);
+
+ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
+ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
+
+/* ASN1 Print flags */
+
+/* Indicate missing OPTIONAL fields */
+#define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001
+/* Mark start and end of SEQUENCE */
+#define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002
+/* Mark start and end of SEQUENCE/SET OF */
+#define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004
+/* Show the ASN1 type of primitives */
+#define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008
+/* Don't show ASN1 type of ANY */
+#define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010
+/* Don't show ASN1 type of MSTRINGs */
+#define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020
+/* Don't show field names in SEQUENCE */
+#define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040
+/* Show structure names of each SEQUENCE field */
+#define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080
+/* Don't show structure name even at top level */
+#define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+ const ASN1_ITEM *it, const ASN1_PCTX *pctx);
+ASN1_PCTX *ASN1_PCTX_new(void);
+void ASN1_PCTX_free(ASN1_PCTX *p);
+unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
+
+BIO_METHOD *BIO_f_asn1(void);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+ const ASN1_ITEM *it);
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+ const char *hdr,
+ const ASN1_ITEM *it);
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+ int ctype_nid, int econt_nid,
+ STACK_OF(X509_ALGOR) *mdalgs,
+ const ASN1_ITEM *it);
+ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
+int SMIME_text(BIO *in, BIO *out);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ASN1_strings(void);
+
+/* Error codes for the ASN1 functions. */
+
+/* Function codes. */
+#define ASN1_F_A2D_ASN1_OBJECT 100
+#define ASN1_F_A2I_ASN1_ENUMERATED 101
+#define ASN1_F_A2I_ASN1_INTEGER 102
+#define ASN1_F_A2I_ASN1_STRING 103
+#define ASN1_F_APPEND_EXP 176
+#define ASN1_F_ASN1_BIT_STRING_SET_BIT 183
+#define ASN1_F_ASN1_CB 177
+#define ASN1_F_ASN1_CHECK_TLEN 104
+#define ASN1_F_ASN1_COLLATE_PRIMITIVE 105
+#define ASN1_F_ASN1_COLLECT 106
+#define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108
+#define ASN1_F_ASN1_D2I_FP 109
+#define ASN1_F_ASN1_D2I_READ_BIO 107
+#define ASN1_F_ASN1_DIGEST 184
+#define ASN1_F_ASN1_DO_ADB 110
+#define ASN1_F_ASN1_DUP 111
+#define ASN1_F_ASN1_ENUMERATED_SET 112
+#define ASN1_F_ASN1_ENUMERATED_TO_BN 113
+#define ASN1_F_ASN1_EX_C2I 204
+#define ASN1_F_ASN1_FIND_END 190
+#define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216
+#define ASN1_F_ASN1_GENERALIZEDTIME_SET 185
+#define ASN1_F_ASN1_GENERATE_V3 178
+#define ASN1_F_ASN1_GET_OBJECT 114
+#define ASN1_F_ASN1_HEADER_NEW 115
+#define ASN1_F_ASN1_I2D_BIO 116
+#define ASN1_F_ASN1_I2D_FP 117
+#define ASN1_F_ASN1_INTEGER_SET 118
+#define ASN1_F_ASN1_INTEGER_TO_BN 119
+#define ASN1_F_ASN1_ITEM_D2I_FP 206
+#define ASN1_F_ASN1_ITEM_DUP 191
+#define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121
+#define ASN1_F_ASN1_ITEM_EX_D2I 120
+#define ASN1_F_ASN1_ITEM_I2D_BIO 192
+#define ASN1_F_ASN1_ITEM_I2D_FP 193
+#define ASN1_F_ASN1_ITEM_PACK 198
+#define ASN1_F_ASN1_ITEM_SIGN 195
+#define ASN1_F_ASN1_ITEM_UNPACK 199
+#define ASN1_F_ASN1_ITEM_VERIFY 197
+#define ASN1_F_ASN1_MBSTRING_NCOPY 122
+#define ASN1_F_ASN1_OBJECT_NEW 123
+#define ASN1_F_ASN1_OUTPUT_DATA 214
+#define ASN1_F_ASN1_PACK_STRING 124
+#define ASN1_F_ASN1_PCTX_NEW 205
+#define ASN1_F_ASN1_PKCS5_PBE_SET 125
+#define ASN1_F_ASN1_SEQ_PACK 126
+#define ASN1_F_ASN1_SEQ_UNPACK 127
+#define ASN1_F_ASN1_SIGN 128
+#define ASN1_F_ASN1_STR2TYPE 179
+#define ASN1_F_ASN1_STRING_SET 186
+#define ASN1_F_ASN1_STRING_TABLE_ADD 129
+#define ASN1_F_ASN1_STRING_TYPE_NEW 130
+#define ASN1_F_ASN1_TEMPLATE_EX_D2I 132
+#define ASN1_F_ASN1_TEMPLATE_NEW 133
+#define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131
+#define ASN1_F_ASN1_TIME_ADJ 217
+#define ASN1_F_ASN1_TIME_SET 175
+#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134
+#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135
+#define ASN1_F_ASN1_UNPACK_STRING 136
+#define ASN1_F_ASN1_UTCTIME_ADJ 218
+#define ASN1_F_ASN1_UTCTIME_SET 187
+#define ASN1_F_ASN1_VERIFY 137
+#define ASN1_F_B64_READ_ASN1 209
+#define ASN1_F_B64_WRITE_ASN1 210
+#define ASN1_F_BIO_NEW_NDEF 208
+#define ASN1_F_BITSTR_CB 180
+#define ASN1_F_BN_TO_ASN1_ENUMERATED 138
+#define ASN1_F_BN_TO_ASN1_INTEGER 139
+#define ASN1_F_C2I_ASN1_BIT_STRING 189
+#define ASN1_F_C2I_ASN1_INTEGER 194
+#define ASN1_F_C2I_ASN1_OBJECT 196
+#define ASN1_F_COLLECT_DATA 140
+#define ASN1_F_D2I_ASN1_BIT_STRING 141
+#define ASN1_F_D2I_ASN1_BOOLEAN 142
+#define ASN1_F_D2I_ASN1_BYTES 143
+#define ASN1_F_D2I_ASN1_GENERALIZEDTIME 144
+#define ASN1_F_D2I_ASN1_HEADER 145
+#define ASN1_F_D2I_ASN1_INTEGER 146
+#define ASN1_F_D2I_ASN1_OBJECT 147
+#define ASN1_F_D2I_ASN1_SET 148
+#define ASN1_F_D2I_ASN1_TYPE_BYTES 149
+#define ASN1_F_D2I_ASN1_UINTEGER 150
+#define ASN1_F_D2I_ASN1_UTCTIME 151
+#define ASN1_F_D2I_AUTOPRIVATEKEY 207
+#define ASN1_F_D2I_NETSCAPE_RSA 152
+#define ASN1_F_D2I_NETSCAPE_RSA_2 153
+#define ASN1_F_D2I_PRIVATEKEY 154
+#define ASN1_F_D2I_PUBLICKEY 155
+#define ASN1_F_D2I_RSA_NET 200
+#define ASN1_F_D2I_RSA_NET_2 201
+#define ASN1_F_D2I_X509 156
+#define ASN1_F_D2I_X509_CINF 157
+#define ASN1_F_D2I_X509_PKEY 159
+#define ASN1_F_I2D_ASN1_BIO_STREAM 211
+#define ASN1_F_I2D_ASN1_SET 188
+#define ASN1_F_I2D_ASN1_TIME 160
+#define ASN1_F_I2D_DSA_PUBKEY 161
+#define ASN1_F_I2D_EC_PUBKEY 181
+#define ASN1_F_I2D_PRIVATEKEY 163
+#define ASN1_F_I2D_PUBLICKEY 164
+#define ASN1_F_I2D_RSA_NET 162
+#define ASN1_F_I2D_RSA_PUBKEY 165
+#define ASN1_F_LONG_C2I 166
+#define ASN1_F_OID_MODULE_INIT 174
+#define ASN1_F_PARSE_TAGGING 182
+#define ASN1_F_PKCS5_PBE2_SET_IV 167
+#define ASN1_F_PKCS5_PBE_SET 202
+#define ASN1_F_PKCS5_PBE_SET0_ALGOR 215
+#define ASN1_F_SMIME_READ_ASN1 212
+#define ASN1_F_SMIME_TEXT 213
+#define ASN1_F_X509_CINF_NEW 168
+#define ASN1_F_X509_CRL_ADD0_REVOKED 169
+#define ASN1_F_X509_INFO_NEW 170
+#define ASN1_F_X509_NAME_ENCODE 203
+#define ASN1_F_X509_NAME_EX_D2I 158
+#define ASN1_F_X509_NAME_EX_NEW 171
+#define ASN1_F_X509_NEW 172
+#define ASN1_F_X509_PKEY_NEW 173
+
+/* Reason codes. */
+#define ASN1_R_ADDING_OBJECT 171
+#define ASN1_R_ASN1_PARSE_ERROR 203
+#define ASN1_R_ASN1_SIG_PARSE_ERROR 204
+#define ASN1_R_AUX_ERROR 100
+#define ASN1_R_BAD_CLASS 101
+#define ASN1_R_BAD_OBJECT_HEADER 102
+#define ASN1_R_BAD_PASSWORD_READ 103
+#define ASN1_R_BAD_TAG 104
+#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214
+#define ASN1_R_BN_LIB 105
+#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106
+#define ASN1_R_BUFFER_TOO_SMALL 107
+#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108
+#define ASN1_R_DATA_IS_WRONG 109
+#define ASN1_R_DECODE_ERROR 110
+#define ASN1_R_DECODING_ERROR 111
+#define ASN1_R_DEPTH_EXCEEDED 174
+#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198
+#define ASN1_R_ENCODE_ERROR 112
+#define ASN1_R_ERROR_GETTING_TIME 173
+#define ASN1_R_ERROR_LOADING_SECTION 172
+#define ASN1_R_ERROR_PARSING_SET_ELEMENT 113
+#define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114
+#define ASN1_R_EXPECTING_AN_INTEGER 115
+#define ASN1_R_EXPECTING_AN_OBJECT 116
+#define ASN1_R_EXPECTING_A_BOOLEAN 117
+#define ASN1_R_EXPECTING_A_TIME 118
+#define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119
+#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120
+#define ASN1_R_FIELD_MISSING 121
+#define ASN1_R_FIRST_NUM_TOO_LARGE 122
+#define ASN1_R_HEADER_TOO_LONG 123
+#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175
+#define ASN1_R_ILLEGAL_BOOLEAN 176
+#define ASN1_R_ILLEGAL_CHARACTERS 124
+#define ASN1_R_ILLEGAL_FORMAT 177
+#define ASN1_R_ILLEGAL_HEX 178
+#define ASN1_R_ILLEGAL_IMPLICIT_TAG 179
+#define ASN1_R_ILLEGAL_INTEGER 180
+#define ASN1_R_ILLEGAL_NESTED_TAGGING 181
+#define ASN1_R_ILLEGAL_NULL 125
+#define ASN1_R_ILLEGAL_NULL_VALUE 182
+#define ASN1_R_ILLEGAL_OBJECT 183
+#define ASN1_R_ILLEGAL_OPTIONAL_ANY 126
+#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170
+#define ASN1_R_ILLEGAL_TAGGED_ANY 127
+#define ASN1_R_ILLEGAL_TIME_VALUE 184
+#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185
+#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
+#define ASN1_R_INVALID_BMPSTRING_LENGTH 129
+#define ASN1_R_INVALID_DIGIT 130
+#define ASN1_R_INVALID_MIME_TYPE 205
+#define ASN1_R_INVALID_MODIFIER 186
+#define ASN1_R_INVALID_NUMBER 187
+#define ASN1_R_INVALID_OBJECT_ENCODING 216
+#define ASN1_R_INVALID_SEPARATOR 131
+#define ASN1_R_INVALID_TIME_FORMAT 132
+#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133
+#define ASN1_R_INVALID_UTF8STRING 134
+#define ASN1_R_IV_TOO_LARGE 135
+#define ASN1_R_LENGTH_ERROR 136
+#define ASN1_R_LIST_ERROR 188
+#define ASN1_R_MIME_NO_CONTENT_TYPE 206
+#define ASN1_R_MIME_PARSE_ERROR 207
+#define ASN1_R_MIME_SIG_PARSE_ERROR 208
+#define ASN1_R_MISSING_EOC 137
+#define ASN1_R_MISSING_SECOND_NUMBER 138
+#define ASN1_R_MISSING_VALUE 189
+#define ASN1_R_MSTRING_NOT_UNIVERSAL 139
+#define ASN1_R_MSTRING_WRONG_TAG 140
+#define ASN1_R_NESTED_ASN1_STRING 197
+#define ASN1_R_NON_HEX_CHARACTERS 141
+#define ASN1_R_NOT_ASCII_FORMAT 190
+#define ASN1_R_NOT_ENOUGH_DATA 142
+#define ASN1_R_NO_CONTENT_TYPE 209
+#define ASN1_R_NO_DEFAULT_DIGEST 201
+#define ASN1_R_NO_MATCHING_CHOICE_TYPE 143
+#define ASN1_R_NO_MULTIPART_BODY_FAILURE 210
+#define ASN1_R_NO_MULTIPART_BOUNDARY 211
+#define ASN1_R_NO_SIG_CONTENT_TYPE 212
+#define ASN1_R_NULL_IS_WRONG_LENGTH 144
+#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191
+#define ASN1_R_ODD_NUMBER_OF_CHARS 145
+#define ASN1_R_PRIVATE_KEY_HEADER_MISSING 146
+#define ASN1_R_SECOND_NUMBER_TOO_LARGE 147
+#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148
+#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149
+#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192
+#define ASN1_R_SHORT_LINE 150
+#define ASN1_R_SIG_INVALID_MIME_TYPE 213
+#define ASN1_R_STREAMING_NOT_SUPPORTED 202
+#define ASN1_R_STRING_TOO_LONG 151
+#define ASN1_R_STRING_TOO_SHORT 152
+#define ASN1_R_TAG_VALUE_TOO_HIGH 153
+#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154
+#define ASN1_R_TIME_NOT_ASCII_FORMAT 193
+#define ASN1_R_TOO_LONG 155
+#define ASN1_R_TYPE_NOT_CONSTRUCTED 156
+#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157
+#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158
+#define ASN1_R_UNEXPECTED_EOC 159
+#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215
+#define ASN1_R_UNKNOWN_FORMAT 160
+#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161
+#define ASN1_R_UNKNOWN_OBJECT_TYPE 162
+#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163
+#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199
+#define ASN1_R_UNKNOWN_TAG 194
+#define ASN1_R_UNKOWN_FORMAT 195
+#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164
+#define ASN1_R_UNSUPPORTED_CIPHER 165
+#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166
+#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167
+#define ASN1_R_UNSUPPORTED_TYPE 196
+#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200
+#define ASN1_R_WRONG_TAG 168
+#define ASN1_R_WRONG_TYPE 169
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/bio/bss_dgram.c b/openssl/crypto/bio/bss_dgram.c
index 117ab599d..07d012a46 100644
--- a/openssl/crypto/bio/bss_dgram.c
+++ b/openssl/crypto/bio/bss_dgram.c
@@ -1,830 +1,830 @@
-/* crypto/bio/bio_dgram.c */
-/*
- * DTLS implementation written by Nagendra Modadugu
- * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
- */
-/* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#ifndef OPENSSL_NO_DGRAM
-
-#include <stdio.h>
-#include <errno.h>
-#define USE_SOCKETS
-#include "cryptlib.h"
-
-#include <openssl/bio.h>
-
-#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
-#include <sys/timeb.h>
-#endif
-
-#ifdef OPENSSL_SYS_LINUX
-#define IP_MTU 14 /* linux is lame */
-#endif
-
-#ifdef WATT32
-#define sock_write SockWrite /* Watt-32 uses same names */
-#define sock_read SockRead
-#define sock_puts SockPuts
-#endif
-
-static int dgram_write(BIO *h, const char *buf, int num);
-static int dgram_read(BIO *h, char *buf, int size);
-static int dgram_puts(BIO *h, const char *str);
-static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int dgram_new(BIO *h);
-static int dgram_free(BIO *data);
-static int dgram_clear(BIO *bio);
-
-static int BIO_dgram_should_retry(int s);
-
-static void get_current_time(struct timeval *t);
-
-static BIO_METHOD methods_dgramp=
- {
- BIO_TYPE_DGRAM,
- "datagram socket",
- dgram_write,
- dgram_read,
- dgram_puts,
- NULL, /* dgram_gets, */
- dgram_ctrl,
- dgram_new,
- dgram_free,
- NULL,
- };
-
-typedef struct bio_dgram_data_st
- {
- union {
- struct sockaddr sa;
- struct sockaddr_in sa_in;
-#if OPENSSL_USE_IPV6
- struct sockaddr_in6 sa_in6;
-#endif
- } peer;
- unsigned int connected;
- unsigned int _errno;
- unsigned int mtu;
- struct timeval next_timeout;
- struct timeval socket_timeout;
- } bio_dgram_data;
-
-BIO_METHOD *BIO_s_datagram(void)
- {
- return(&methods_dgramp);
- }
-
-BIO *BIO_new_dgram(int fd, int close_flag)
- {
- BIO *ret;
-
- ret=BIO_new(BIO_s_datagram());
- if (ret == NULL) return(NULL);
- BIO_set_fd(ret,fd,close_flag);
- return(ret);
- }
-
-static int dgram_new(BIO *bi)
- {
- bio_dgram_data *data = NULL;
-
- bi->init=0;
- bi->num=0;
- data = OPENSSL_malloc(sizeof(bio_dgram_data));
- if (data == NULL)
- return 0;
- memset(data, 0x00, sizeof(bio_dgram_data));
- bi->ptr = data;
-
- bi->flags=0;
- return(1);
- }
-
-static int dgram_free(BIO *a)
- {
- bio_dgram_data *data;
-
- if (a == NULL) return(0);
- if ( ! dgram_clear(a))
- return 0;
-
- data = (bio_dgram_data *)a->ptr;
- if(data != NULL) OPENSSL_free(data);
-
- return(1);
- }
-
-static int dgram_clear(BIO *a)
- {
- if (a == NULL) return(0);
- if (a->shutdown)
- {
- if (a->init)
- {
- SHUTDOWN2(a->num);
- }
- a->init=0;
- a->flags=0;
- }
- return(1);
- }
-
-static void dgram_adjust_rcv_timeout(BIO *b)
- {
-#if defined(SO_RCVTIMEO)
- bio_dgram_data *data = (bio_dgram_data *)b->ptr;
- int sz = sizeof(int);
-
- /* Is a timer active? */
- if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
- {
- struct timeval timenow, timeleft;
-
- /* Read current socket timeout */
-#ifdef OPENSSL_SYS_WINDOWS
- int timeout;
- if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void*)&timeout, &sz) < 0)
- { perror("getsockopt"); }
- else
- {
- data->socket_timeout.tv_sec = timeout / 1000;
- data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
- }
-#else
- if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- &(data->socket_timeout), (void *)&sz) < 0)
- { perror("getsockopt"); }
-#endif
-
- /* Get current time */
- get_current_time(&timenow);
-
- /* Calculate time left until timer expires */
- memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
- timeleft.tv_sec -= timenow.tv_sec;
- timeleft.tv_usec -= timenow.tv_usec;
- if (timeleft.tv_usec < 0)
- {
- timeleft.tv_sec--;
- timeleft.tv_usec += 1000000;
- }
-
- if (timeleft.tv_sec < 0)
- {
- timeleft.tv_sec = 0;
- timeleft.tv_usec = 1;
- }
-
- /* Adjust socket timeout if next handhake message timer
- * will expire earlier.
- */
- if ((data->socket_timeout.tv_sec == 0 && data->socket_timeout.tv_usec == 0) ||
- (data->socket_timeout.tv_sec > timeleft.tv_sec) ||
- (data->socket_timeout.tv_sec == timeleft.tv_sec &&
- data->socket_timeout.tv_usec >= timeleft.tv_usec))
- {
-#ifdef OPENSSL_SYS_WINDOWS
- timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
- if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void*)&timeout, sizeof(timeout)) < 0)
- { perror("setsockopt"); }
-#else
- if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
- sizeof(struct timeval)) < 0)
- { perror("setsockopt"); }
-#endif
- }
- }
-#endif
- }
-
-static void dgram_reset_rcv_timeout(BIO *b)
- {
-#if defined(SO_RCVTIMEO)
- bio_dgram_data *data = (bio_dgram_data *)b->ptr;
-
- /* Is a timer active? */
- if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
- {
-#ifdef OPENSSL_SYS_WINDOWS
- int timeout = data->socket_timeout.tv_sec * 1000 +
- data->socket_timeout.tv_usec / 1000;
- if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void*)&timeout, sizeof(timeout)) < 0)
- { perror("setsockopt"); }
-#else
- if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
- sizeof(struct timeval)) < 0)
- { perror("setsockopt"); }
-#endif
- }
-#endif
- }
-
-static int dgram_read(BIO *b, char *out, int outl)
- {
- int ret=0;
- bio_dgram_data *data = (bio_dgram_data *)b->ptr;
-
- struct {
- /*
- * See commentary in b_sock.c. <appro>
- */
- union { size_t s; int i; } len;
- union {
- struct sockaddr sa;
- struct sockaddr_in sa_in;
-#if OPENSSL_USE_IPV6
- struct sockaddr_in6 sa_in6;
-#endif
- } peer;
- } sa;
-
- sa.len.s=0;
- sa.len.i=sizeof(sa.peer);
-
- if (out != NULL)
- {
- clear_socket_error();
- memset(&sa.peer, 0x00, sizeof(sa.peer));
- dgram_adjust_rcv_timeout(b);
- ret=recvfrom(b->num,out,outl,0,&sa.peer.sa,(void *)&sa.len);
- if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0)
- {
- OPENSSL_assert(sa.len.s<=sizeof(sa.peer));
- sa.len.i = (int)sa.len.s;
- }
- dgram_reset_rcv_timeout(b);
-
- if ( ! data->connected && ret >= 0)
- BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer);
-
- BIO_clear_retry_flags(b);
- if (ret < 0)
- {
- if (BIO_dgram_should_retry(ret))
- {
- BIO_set_retry_read(b);
- data->_errno = get_last_socket_error();
- }
- }
- }
- return(ret);
- }
-
-static int dgram_write(BIO *b, const char *in, int inl)
- {
- int ret;
- bio_dgram_data *data = (bio_dgram_data *)b->ptr;
- clear_socket_error();
-
- if ( data->connected )
- ret=writesocket(b->num,in,inl);
- else
- {
- int peerlen = sizeof(data->peer);
-
- if (data->peer.sa.sa_family == AF_INET)
- peerlen = sizeof(data->peer.sa_in);
-#if OPENSSL_USE_IPV6
- else if (data->peer.sa.sa_family == AF_INET6)
- peerlen = sizeof(data->peer.sa_in6);
-#endif
-#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
- ret=sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen);
-#else
- ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen);
-#endif
- }
-
- BIO_clear_retry_flags(b);
- if (ret <= 0)
- {
- if (BIO_dgram_should_retry(ret))
- {
- BIO_set_retry_write(b);
- data->_errno = get_last_socket_error();
-
-#if 0 /* higher layers are responsible for querying MTU, if necessary */
- if ( data->_errno == EMSGSIZE)
- /* retrieve the new MTU */
- BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
-#endif
- }
- }
- return(ret);
- }
-
-static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
- {
- long ret=1;
- int *ip;
- struct sockaddr *to = NULL;
- bio_dgram_data *data = NULL;
-#if defined(IP_MTU_DISCOVER) || defined(IP_MTU)
- long sockopt_val = 0;
- unsigned int sockopt_len = 0;
-#endif
-#ifdef OPENSSL_SYS_LINUX
- socklen_t addr_len;
- union {
- struct sockaddr sa;
- struct sockaddr_in s4;
-#if OPENSSL_USE_IPV6
- struct sockaddr_in6 s6;
-#endif
- } addr;
-#endif
-
- data = (bio_dgram_data *)b->ptr;
-
- switch (cmd)
- {
- case BIO_CTRL_RESET:
- num=0;
- case BIO_C_FILE_SEEK:
- ret=0;
- break;
- case BIO_C_FILE_TELL:
- case BIO_CTRL_INFO:
- ret=0;
- break;
- case BIO_C_SET_FD:
- dgram_clear(b);
- b->num= *((int *)ptr);
- b->shutdown=(int)num;
- b->init=1;
- break;
- case BIO_C_GET_FD:
- if (b->init)
- {
- ip=(int *)ptr;
- if (ip != NULL) *ip=b->num;
- ret=b->num;
- }
- else
- ret= -1;
- break;
- case BIO_CTRL_GET_CLOSE:
- ret=b->shutdown;
- break;
- case BIO_CTRL_SET_CLOSE:
- b->shutdown=(int)num;
- break;
- case BIO_CTRL_PENDING:
- case BIO_CTRL_WPENDING:
- ret=0;
- break;
- case BIO_CTRL_DUP:
- case BIO_CTRL_FLUSH:
- ret=1;
- break;
- case BIO_CTRL_DGRAM_CONNECT:
- to = (struct sockaddr *)ptr;
-#if 0
- if (connect(b->num, to, sizeof(struct sockaddr)) < 0)
- { perror("connect"); ret = 0; }
- else
- {
-#endif
- switch (to->sa_family)
- {
- case AF_INET:
- memcpy(&data->peer,to,sizeof(data->peer.sa_in));
- break;
-#if OPENSSL_USE_IPV6
- case AF_INET6:
- memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
- break;
-#endif
- default:
- memcpy(&data->peer,to,sizeof(data->peer.sa));
- break;
- }
-#if 0
- }
-#endif
- break;
- /* (Linux)kernel sets DF bit on outgoing IP packets */
- case BIO_CTRL_DGRAM_MTU_DISCOVER:
-#ifdef OPENSSL_SYS_LINUX
- addr_len = (socklen_t)sizeof(addr);
- memset((void *)&addr, 0, sizeof(addr));
- if (getsockname(b->num, &addr.sa, &addr_len) < 0)
- {
- ret = 0;
- break;
- }
- sockopt_len = sizeof(sockopt_val);
- switch (addr.sa.sa_family)
- {
- case AF_INET:
- sockopt_val = IP_PMTUDISC_DO;
- if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
- &sockopt_val, sizeof(sockopt_val))) < 0)
- perror("setsockopt");
- break;
-#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER)
- case AF_INET6:
- sockopt_val = IPV6_PMTUDISC_DO;
- if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
- &sockopt_val, sizeof(sockopt_val))) < 0)
- perror("setsockopt");
- break;
-#endif
- default:
- ret = -1;
- break;
- }
- ret = -1;
-#else
- break;
-#endif
- case BIO_CTRL_DGRAM_QUERY_MTU:
-#ifdef OPENSSL_SYS_LINUX
- addr_len = (socklen_t)sizeof(addr);
- memset((void *)&addr, 0, sizeof(addr));
- if (getsockname(b->num, &addr.sa, &addr_len) < 0)
- {
- ret = 0;
- break;
- }
- sockopt_len = sizeof(sockopt_val);
- switch (addr.sa.sa_family)
- {
- case AF_INET:
- if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
- &sockopt_len)) < 0 || sockopt_val < 0)
- {
- ret = 0;
- }
- else
- {
- /* we assume that the transport protocol is UDP and no
- * IP options are used.
- */
- data->mtu = sockopt_val - 8 - 20;
- ret = data->mtu;
- }
- break;
-#if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
- case AF_INET6:
- if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val,
- &sockopt_len)) < 0 || sockopt_val < 0)
- {
- ret = 0;
- }
- else
- {
- /* we assume that the transport protocol is UDP and no
- * IPV6 options are used.
- */
- data->mtu = sockopt_val - 8 - 40;
- ret = data->mtu;
- }
- break;
-#endif
- default:
- ret = 0;
- break;
- }
-#else
- ret = 0;
-#endif
- break;
- case BIO_CTRL_DGRAM_GET_MTU:
- return data->mtu;
- break;
- case BIO_CTRL_DGRAM_SET_MTU:
- data->mtu = num;
- ret = num;
- break;
- case BIO_CTRL_DGRAM_SET_CONNECTED:
- to = (struct sockaddr *)ptr;
-
- if ( to != NULL)
- {
- data->connected = 1;
- switch (to->sa_family)
- {
- case AF_INET:
- memcpy(&data->peer,to,sizeof(data->peer.sa_in));
- break;
-#if OPENSSL_USE_IPV6
- case AF_INET6:
- memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
- break;
-#endif
- default:
- memcpy(&data->peer,to,sizeof(data->peer.sa));
- break;
- }
- }
- else
- {
- data->connected = 0;
- memset(&(data->peer), 0x00, sizeof(data->peer));
- }
- break;
- case BIO_CTRL_DGRAM_GET_PEER:
- switch (data->peer.sa.sa_family)
- {
- case AF_INET:
- ret=sizeof(data->peer.sa_in);
- break;
-#if OPENSSL_USE_IPV6
- case AF_INET6:
- ret=sizeof(data->peer.sa_in6);
- break;
-#endif
- default:
- ret=sizeof(data->peer.sa);
- break;
- }
- if (num==0 || num>ret)
- num=ret;
- memcpy(ptr,&data->peer,(ret=num));
- break;
- case BIO_CTRL_DGRAM_SET_PEER:
- to = (struct sockaddr *) ptr;
- switch (to->sa_family)
- {
- case AF_INET:
- memcpy(&data->peer,to,sizeof(data->peer.sa_in));
- break;
-#if OPENSSL_USE_IPV6
- case AF_INET6:
- memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
- break;
-#endif
- default:
- memcpy(&data->peer,to,sizeof(data->peer.sa));
- break;
- }
- break;
- case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
- memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
- break;
-#if defined(SO_RCVTIMEO)
- case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
-#ifdef OPENSSL_SYS_WINDOWS
- {
- struct timeval *tv = (struct timeval *)ptr;
- int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
- if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void*)&timeout, sizeof(timeout)) < 0)
- { perror("setsockopt"); ret = -1; }
- }
-#else
- if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
- sizeof(struct timeval)) < 0)
- { perror("setsockopt"); ret = -1; }
-#endif
- break;
- case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
-#ifdef OPENSSL_SYS_WINDOWS
- {
- int timeout, sz = sizeof(timeout);
- struct timeval *tv = (struct timeval *)ptr;
- if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- (void*)&timeout, &sz) < 0)
- { perror("getsockopt"); ret = -1; }
- else
- {
- tv->tv_sec = timeout / 1000;
- tv->tv_usec = (timeout % 1000) * 1000;
- ret = sizeof(*tv);
- }
- }
-#else
- if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
- ptr, (void *)&ret) < 0)
- { perror("getsockopt"); ret = -1; }
-#endif
- break;
-#endif
-#if defined(SO_SNDTIMEO)
- case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
-#ifdef OPENSSL_SYS_WINDOWS
- {
- struct timeval *tv = (struct timeval *)ptr;
- int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
- if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
- (void*)&timeout, sizeof(timeout)) < 0)
- { perror("setsockopt"); ret = -1; }
- }
-#else
- if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
- sizeof(struct timeval)) < 0)
- { perror("setsockopt"); ret = -1; }
-#endif
- break;
- case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
-#ifdef OPENSSL_SYS_WINDOWS
- {
- int timeout, sz = sizeof(timeout);
- struct timeval *tv = (struct timeval *)ptr;
- if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
- (void*)&timeout, &sz) < 0)
- { perror("getsockopt"); ret = -1; }
- else
- {
- tv->tv_sec = timeout / 1000;
- tv->tv_usec = (timeout % 1000) * 1000;
- ret = sizeof(*tv);
- }
- }
-#else
- if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
- ptr, (void *)&ret) < 0)
- { perror("getsockopt"); ret = -1; }
-#endif
- break;
-#endif
- case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
- /* fall-through */
- case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
-#ifdef OPENSSL_SYS_WINDOWS
- if ( data->_errno == WSAETIMEDOUT)
-#else
- if ( data->_errno == EAGAIN)
-#endif
- {
- ret = 1;
- data->_errno = 0;
- }
- else
- ret = 0;
- break;
-#ifdef EMSGSIZE
- case BIO_CTRL_DGRAM_MTU_EXCEEDED:
- if ( data->_errno == EMSGSIZE)
- {
- ret = 1;
- data->_errno = 0;
- }
- else
- ret = 0;
- break;
-#endif
- default:
- ret=0;
- break;
- }
- return(ret);
- }
-
-static int dgram_puts(BIO *bp, const char *str)
- {
- int n,ret;
-
- n=strlen(str);
- ret=dgram_write(bp,str,n);
- return(ret);
- }
-
-static int BIO_dgram_should_retry(int i)
- {
- int err;
-
- if ((i == 0) || (i == -1))
- {
- err=get_last_socket_error();
-
-#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */
- if ((i == -1) && (err == 0))
- return(1);
-#endif
-
- return(BIO_dgram_non_fatal_error(err));
- }
- return(0);
- }
-
-int BIO_dgram_non_fatal_error(int err)
- {
- switch (err)
- {
-#if defined(OPENSSL_SYS_WINDOWS)
-# if defined(WSAEWOULDBLOCK)
- case WSAEWOULDBLOCK:
-# endif
-
-# if 0 /* This appears to always be an error */
-# if defined(WSAENOTCONN)
- case WSAENOTCONN:
-# endif
-# endif
-#endif
-
-#ifdef EWOULDBLOCK
-# ifdef WSAEWOULDBLOCK
-# if WSAEWOULDBLOCK != EWOULDBLOCK
- case EWOULDBLOCK:
-# endif
-# else
- case EWOULDBLOCK:
-# endif
-#endif
-
-#ifdef EINTR
- case EINTR:
-#endif
-
-#ifdef EAGAIN
-#if EWOULDBLOCK != EAGAIN
- case EAGAIN:
-# endif
-#endif
-
-#ifdef EPROTO
- case EPROTO:
-#endif
-
-#ifdef EINPROGRESS
- case EINPROGRESS:
-#endif
-
-#ifdef EALREADY
- case EALREADY:
-#endif
-
- return(1);
- /* break; */
- default:
- break;
- }
- return(0);
- }
-#endif
-
-static void get_current_time(struct timeval *t)
- {
-#ifdef OPENSSL_SYS_WIN32
- struct _timeb tb;
- _ftime(&tb);
- t->tv_sec = (long)tb.time;
- t->tv_usec = (long)tb.millitm * 1000;
-#elif defined(OPENSSL_SYS_VMS)
- struct timeb tb;
- ftime(&tb);
- t->tv_sec = (long)tb.time;
- t->tv_usec = (long)tb.millitm * 1000;
-#else
- gettimeofday(t, NULL);
-#endif
- }
+/* crypto/bio/bio_dgram.c */
+/*
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef OPENSSL_NO_DGRAM
+
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+
+#include <openssl/bio.h>
+
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
+#include <sys/timeb.h>
+#endif
+
+#ifdef OPENSSL_SYS_LINUX
+#define IP_MTU 14 /* linux is lame */
+#endif
+
+#ifdef WATT32
+#define sock_write SockWrite /* Watt-32 uses same names */
+#define sock_read SockRead
+#define sock_puts SockPuts
+#endif
+
+static int dgram_write(BIO *h, const char *buf, int num);
+static int dgram_read(BIO *h, char *buf, int size);
+static int dgram_puts(BIO *h, const char *str);
+static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int dgram_new(BIO *h);
+static int dgram_free(BIO *data);
+static int dgram_clear(BIO *bio);
+
+static int BIO_dgram_should_retry(int s);
+
+static void get_current_time(struct timeval *t);
+
+static BIO_METHOD methods_dgramp=
+ {
+ BIO_TYPE_DGRAM,
+ "datagram socket",
+ dgram_write,
+ dgram_read,
+ dgram_puts,
+ NULL, /* dgram_gets, */
+ dgram_ctrl,
+ dgram_new,
+ dgram_free,
+ NULL,
+ };
+
+typedef struct bio_dgram_data_st
+ {
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sa_in;
+#if OPENSSL_USE_IPV6
+ struct sockaddr_in6 sa_in6;
+#endif
+ } peer;
+ unsigned int connected;
+ unsigned int _errno;
+ unsigned int mtu;
+ struct timeval next_timeout;
+ struct timeval socket_timeout;
+ } bio_dgram_data;
+
+BIO_METHOD *BIO_s_datagram(void)
+ {
+ return(&methods_dgramp);
+ }
+
+BIO *BIO_new_dgram(int fd, int close_flag)
+ {
+ BIO *ret;
+
+ ret=BIO_new(BIO_s_datagram());
+ if (ret == NULL) return(NULL);
+ BIO_set_fd(ret,fd,close_flag);
+ return(ret);
+ }
+
+static int dgram_new(BIO *bi)
+ {
+ bio_dgram_data *data = NULL;
+
+ bi->init=0;
+ bi->num=0;
+ data = OPENSSL_malloc(sizeof(bio_dgram_data));
+ if (data == NULL)
+ return 0;
+ memset(data, 0x00, sizeof(bio_dgram_data));
+ bi->ptr = data;
+
+ bi->flags=0;
+ return(1);
+ }
+
+static int dgram_free(BIO *a)
+ {
+ bio_dgram_data *data;
+
+ if (a == NULL) return(0);
+ if ( ! dgram_clear(a))
+ return 0;
+
+ data = (bio_dgram_data *)a->ptr;
+ if(data != NULL) OPENSSL_free(data);
+
+ return(1);
+ }
+
+static int dgram_clear(BIO *a)
+ {
+ if (a == NULL) return(0);
+ if (a->shutdown)
+ {
+ if (a->init)
+ {
+ SHUTDOWN2(a->num);
+ }
+ a->init=0;
+ a->flags=0;
+ }
+ return(1);
+ }
+
+static void dgram_adjust_rcv_timeout(BIO *b)
+ {
+#if defined(SO_RCVTIMEO)
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+ int sz = sizeof(int);
+
+ /* Is a timer active? */
+ if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
+ {
+ struct timeval timenow, timeleft;
+
+ /* Read current socket timeout */
+#ifdef OPENSSL_SYS_WINDOWS
+ int timeout;
+ if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void*)&timeout, &sz) < 0)
+ { perror("getsockopt"); }
+ else
+ {
+ data->socket_timeout.tv_sec = timeout / 1000;
+ data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
+ }
+#else
+ if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ &(data->socket_timeout), (void *)&sz) < 0)
+ { perror("getsockopt"); }
+#endif
+
+ /* Get current time */
+ get_current_time(&timenow);
+
+ /* Calculate time left until timer expires */
+ memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
+ timeleft.tv_sec -= timenow.tv_sec;
+ timeleft.tv_usec -= timenow.tv_usec;
+ if (timeleft.tv_usec < 0)
+ {
+ timeleft.tv_sec--;
+ timeleft.tv_usec += 1000000;
+ }
+
+ if (timeleft.tv_sec < 0)
+ {
+ timeleft.tv_sec = 0;
+ timeleft.tv_usec = 1;
+ }
+
+ /* Adjust socket timeout if next handhake message timer
+ * will expire earlier.
+ */
+ if ((data->socket_timeout.tv_sec == 0 && data->socket_timeout.tv_usec == 0) ||
+ (data->socket_timeout.tv_sec > timeleft.tv_sec) ||
+ (data->socket_timeout.tv_sec == timeleft.tv_sec &&
+ data->socket_timeout.tv_usec >= timeleft.tv_usec))
+ {
+#ifdef OPENSSL_SYS_WINDOWS
+ timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void*)&timeout, sizeof(timeout)) < 0)
+ { perror("setsockopt"); }
+#else
+ if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
+ sizeof(struct timeval)) < 0)
+ { perror("setsockopt"); }
+#endif
+ }
+ }
+#endif
+ }
+
+static void dgram_reset_rcv_timeout(BIO *b)
+ {
+#if defined(SO_RCVTIMEO)
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+
+ /* Is a timer active? */
+ if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
+ {
+#ifdef OPENSSL_SYS_WINDOWS
+ int timeout = data->socket_timeout.tv_sec * 1000 +
+ data->socket_timeout.tv_usec / 1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void*)&timeout, sizeof(timeout)) < 0)
+ { perror("setsockopt"); }
+#else
+ if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
+ sizeof(struct timeval)) < 0)
+ { perror("setsockopt"); }
+#endif
+ }
+#endif
+ }
+
+static int dgram_read(BIO *b, char *out, int outl)
+ {
+ int ret=0;
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+
+ struct {
+ /*
+ * See commentary in b_sock.c. <appro>
+ */
+ union { size_t s; int i; } len;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sa_in;
+#if OPENSSL_USE_IPV6
+ struct sockaddr_in6 sa_in6;
+#endif
+ } peer;
+ } sa;
+
+ sa.len.s=0;
+ sa.len.i=sizeof(sa.peer);
+
+ if (out != NULL)
+ {
+ clear_socket_error();
+ memset(&sa.peer, 0x00, sizeof(sa.peer));
+ dgram_adjust_rcv_timeout(b);
+ ret=recvfrom(b->num,out,outl,0,&sa.peer.sa,(void *)&sa.len);
+ if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0)
+ {
+ OPENSSL_assert(sa.len.s<=sizeof(sa.peer));
+ sa.len.i = (int)sa.len.s;
+ }
+ dgram_reset_rcv_timeout(b);
+
+ if ( ! data->connected && ret >= 0)
+ BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer);
+
+ BIO_clear_retry_flags(b);
+ if (ret < 0)
+ {
+ if (BIO_dgram_should_retry(ret))
+ {
+ BIO_set_retry_read(b);
+ data->_errno = get_last_socket_error();
+ }
+ }
+ }
+ return(ret);
+ }
+
+static int dgram_write(BIO *b, const char *in, int inl)
+ {
+ int ret;
+ bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+ clear_socket_error();
+
+ if ( data->connected )
+ ret=writesocket(b->num,in,inl);
+ else
+ {
+ int peerlen = sizeof(data->peer);
+
+ if (data->peer.sa.sa_family == AF_INET)
+ peerlen = sizeof(data->peer.sa_in);
+#if OPENSSL_USE_IPV6
+ else if (data->peer.sa.sa_family == AF_INET6)
+ peerlen = sizeof(data->peer.sa_in6);
+#endif
+#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
+ ret=sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen);
+#else
+ ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen);
+#endif
+ }
+
+ BIO_clear_retry_flags(b);
+ if (ret <= 0)
+ {
+ if (BIO_dgram_should_retry(ret))
+ {
+ BIO_set_retry_write(b);
+ data->_errno = get_last_socket_error();
+
+#if 0 /* higher layers are responsible for querying MTU, if necessary */
+ if ( data->_errno == EMSGSIZE)
+ /* retrieve the new MTU */
+ BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+#endif
+ }
+ }
+ return(ret);
+ }
+
+static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
+ {
+ long ret=1;
+ int *ip;
+ struct sockaddr *to = NULL;
+ bio_dgram_data *data = NULL;
+#if defined(IP_MTU_DISCOVER) || defined(IP_MTU)
+ long sockopt_val = 0;
+ unsigned int sockopt_len = 0;
+#endif
+#ifdef OPENSSL_SYS_LINUX
+ socklen_t addr_len;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in s4;
+#if OPENSSL_USE_IPV6
+ struct sockaddr_in6 s6;
+#endif
+ } addr;
+#endif
+
+ data = (bio_dgram_data *)b->ptr;
+
+ switch (cmd)
+ {
+ case BIO_CTRL_RESET:
+ num=0;
+ case BIO_C_FILE_SEEK:
+ ret=0;
+ break;
+ case BIO_C_FILE_TELL:
+ case BIO_CTRL_INFO:
+ ret=0;
+ break;
+ case BIO_C_SET_FD:
+ dgram_clear(b);
+ b->num= *((int *)ptr);
+ b->shutdown=(int)num;
+ b->init=1;
+ break;
+ case BIO_C_GET_FD:
+ if (b->init)
+ {
+ ip=(int *)ptr;
+ if (ip != NULL) *ip=b->num;
+ ret=b->num;
+ }
+ else
+ ret= -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret=b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown=(int)num;
+ break;
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ ret=0;
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret=1;
+ break;
+ case BIO_CTRL_DGRAM_CONNECT:
+ to = (struct sockaddr *)ptr;
+#if 0
+ if (connect(b->num, to, sizeof(struct sockaddr)) < 0)
+ { perror("connect"); ret = 0; }
+ else
+ {
+#endif
+ switch (to->sa_family)
+ {
+ case AF_INET:
+ memcpy(&data->peer,to,sizeof(data->peer.sa_in));
+ break;
+#if OPENSSL_USE_IPV6
+ case AF_INET6:
+ memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
+ break;
+#endif
+ default:
+ memcpy(&data->peer,to,sizeof(data->peer.sa));
+ break;
+ }
+#if 0
+ }
+#endif
+ break;
+ /* (Linux)kernel sets DF bit on outgoing IP packets */
+ case BIO_CTRL_DGRAM_MTU_DISCOVER:
+#ifdef OPENSSL_SYS_LINUX
+ addr_len = (socklen_t)sizeof(addr);
+ memset((void *)&addr, 0, sizeof(addr));
+ if (getsockname(b->num, &addr.sa, &addr_len) < 0)
+ {
+ ret = 0;
+ break;
+ }
+ sockopt_len = sizeof(sockopt_val);
+ switch (addr.sa.sa_family)
+ {
+ case AF_INET:
+ sockopt_val = IP_PMTUDISC_DO;
+ if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+ &sockopt_val, sizeof(sockopt_val))) < 0)
+ perror("setsockopt");
+ break;
+#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER)
+ case AF_INET6:
+ sockopt_val = IPV6_PMTUDISC_DO;
+ if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+ &sockopt_val, sizeof(sockopt_val))) < 0)
+ perror("setsockopt");
+ break;
+#endif
+ default:
+ ret = -1;
+ break;
+ }
+ ret = -1;
+#else
+ break;
+#endif
+ case BIO_CTRL_DGRAM_QUERY_MTU:
+#ifdef OPENSSL_SYS_LINUX
+ addr_len = (socklen_t)sizeof(addr);
+ memset((void *)&addr, 0, sizeof(addr));
+ if (getsockname(b->num, &addr.sa, &addr_len) < 0)
+ {
+ ret = 0;
+ break;
+ }
+ sockopt_len = sizeof(sockopt_val);
+ switch (addr.sa.sa_family)
+ {
+ case AF_INET:
+ if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
+ &sockopt_len)) < 0 || sockopt_val < 0)
+ {
+ ret = 0;
+ }
+ else
+ {
+ /* we assume that the transport protocol is UDP and no
+ * IP options are used.
+ */
+ data->mtu = sockopt_val - 8 - 20;
+ ret = data->mtu;
+ }
+ break;
+#if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
+ case AF_INET6:
+ if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val,
+ &sockopt_len)) < 0 || sockopt_val < 0)
+ {
+ ret = 0;
+ }
+ else
+ {
+ /* we assume that the transport protocol is UDP and no
+ * IPV6 options are used.
+ */
+ data->mtu = sockopt_val - 8 - 40;
+ ret = data->mtu;
+ }
+ break;
+#endif
+ default:
+ ret = 0;
+ break;
+ }
+#else
+ ret = 0;
+#endif
+ break;
+ case BIO_CTRL_DGRAM_GET_MTU:
+ return data->mtu;
+ break;
+ case BIO_CTRL_DGRAM_SET_MTU:
+ data->mtu = num;
+ ret = num;
+ break;
+ case BIO_CTRL_DGRAM_SET_CONNECTED:
+ to = (struct sockaddr *)ptr;
+
+ if ( to != NULL)
+ {
+ data->connected = 1;
+ switch (to->sa_family)
+ {
+ case AF_INET:
+ memcpy(&data->peer,to,sizeof(data->peer.sa_in));
+ break;
+#if OPENSSL_USE_IPV6
+ case AF_INET6:
+ memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
+ break;
+#endif
+ default:
+ memcpy(&data->peer,to,sizeof(data->peer.sa));
+ break;
+ }
+ }
+ else
+ {
+ data->connected = 0;
+ memset(&(data->peer), 0x00, sizeof(data->peer));
+ }
+ break;
+ case BIO_CTRL_DGRAM_GET_PEER:
+ switch (data->peer.sa.sa_family)
+ {
+ case AF_INET:
+ ret=sizeof(data->peer.sa_in);
+ break;
+#if OPENSSL_USE_IPV6
+ case AF_INET6:
+ ret=sizeof(data->peer.sa_in6);
+ break;
+#endif
+ default:
+ ret=sizeof(data->peer.sa);
+ break;
+ }
+ if (num==0 || num>ret)
+ num=ret;
+ memcpy(ptr,&data->peer,(ret=num));
+ break;
+ case BIO_CTRL_DGRAM_SET_PEER:
+ to = (struct sockaddr *) ptr;
+ switch (to->sa_family)
+ {
+ case AF_INET:
+ memcpy(&data->peer,to,sizeof(data->peer.sa_in));
+ break;
+#if OPENSSL_USE_IPV6
+ case AF_INET6:
+ memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
+ break;
+#endif
+ default:
+ memcpy(&data->peer,to,sizeof(data->peer.sa));
+ break;
+ }
+ break;
+ case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
+ memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
+ break;
+#if defined(SO_RCVTIMEO)
+ case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+ {
+ struct timeval *tv = (struct timeval *)ptr;
+ int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void*)&timeout, sizeof(timeout)) < 0)
+ { perror("setsockopt"); ret = -1; }
+ }
+#else
+ if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
+ sizeof(struct timeval)) < 0)
+ { perror("setsockopt"); ret = -1; }
+#endif
+ break;
+ case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+ {
+ int timeout, sz = sizeof(timeout);
+ struct timeval *tv = (struct timeval *)ptr;
+ if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ (void*)&timeout, &sz) < 0)
+ { perror("getsockopt"); ret = -1; }
+ else
+ {
+ tv->tv_sec = timeout / 1000;
+ tv->tv_usec = (timeout % 1000) * 1000;
+ ret = sizeof(*tv);
+ }
+ }
+#else
+ if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+ ptr, (void *)&ret) < 0)
+ { perror("getsockopt"); ret = -1; }
+#endif
+ break;
+#endif
+#if defined(SO_SNDTIMEO)
+ case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+ {
+ struct timeval *tv = (struct timeval *)ptr;
+ int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
+ if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+ (void*)&timeout, sizeof(timeout)) < 0)
+ { perror("setsockopt"); ret = -1; }
+ }
+#else
+ if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
+ sizeof(struct timeval)) < 0)
+ { perror("setsockopt"); ret = -1; }
+#endif
+ break;
+ case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+ {
+ int timeout, sz = sizeof(timeout);
+ struct timeval *tv = (struct timeval *)ptr;
+ if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+ (void*)&timeout, &sz) < 0)
+ { perror("getsockopt"); ret = -1; }
+ else
+ {
+ tv->tv_sec = timeout / 1000;
+ tv->tv_usec = (timeout % 1000) * 1000;
+ ret = sizeof(*tv);
+ }
+ }
+#else
+ if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+ ptr, (void *)&ret) < 0)
+ { perror("getsockopt"); ret = -1; }
+#endif
+ break;
+#endif
+ case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
+ /* fall-through */
+ case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
+#ifdef OPENSSL_SYS_WINDOWS
+ if ( data->_errno == WSAETIMEDOUT)
+#else
+ if ( data->_errno == EAGAIN)
+#endif
+ {
+ ret = 1;
+ data->_errno = 0;
+ }
+ else
+ ret = 0;
+ break;
+#ifdef EMSGSIZE
+ case BIO_CTRL_DGRAM_MTU_EXCEEDED:
+ if ( data->_errno == EMSGSIZE)
+ {
+ ret = 1;
+ data->_errno = 0;
+ }
+ else
+ ret = 0;
+ break;
+#endif
+ default:
+ ret=0;
+ break;
+ }
+ return(ret);
+ }
+
+static int dgram_puts(BIO *bp, const char *str)
+ {
+ int n,ret;
+
+ n=strlen(str);
+ ret=dgram_write(bp,str,n);
+ return(ret);
+ }
+
+static int BIO_dgram_should_retry(int i)
+ {
+ int err;
+
+ if ((i == 0) || (i == -1))
+ {
+ err=get_last_socket_error();
+
+#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */
+ if ((i == -1) && (err == 0))
+ return(1);
+#endif
+
+ return(BIO_dgram_non_fatal_error(err));
+ }
+ return(0);
+ }
+
+int BIO_dgram_non_fatal_error(int err)
+ {
+ switch (err)
+ {
+#if defined(OPENSSL_SYS_WINDOWS)
+# if defined(WSAEWOULDBLOCK)
+ case WSAEWOULDBLOCK:
+# endif
+
+# if 0 /* This appears to always be an error */
+# if defined(WSAENOTCONN)
+ case WSAENOTCONN:
+# endif
+# endif
+#endif
+
+#ifdef EWOULDBLOCK
+# ifdef WSAEWOULDBLOCK
+# if WSAEWOULDBLOCK != EWOULDBLOCK
+ case EWOULDBLOCK:
+# endif
+# else
+ case EWOULDBLOCK:
+# endif
+#endif
+
+#ifdef EINTR
+ case EINTR:
+#endif
+
+#ifdef EAGAIN
+#if EWOULDBLOCK != EAGAIN
+ case EAGAIN:
+# endif
+#endif
+
+#ifdef EPROTO
+ case EPROTO:
+#endif
+
+#ifdef EINPROGRESS
+ case EINPROGRESS:
+#endif
+
+#ifdef EALREADY
+ case EALREADY:
+#endif
+
+ return(1);
+ /* break; */
+ default:
+ break;
+ }
+ return(0);
+ }
+#endif
+
+static void get_current_time(struct timeval *t)
+ {
+#ifdef OPENSSL_SYS_WIN32
+ struct _timeb tb;
+ _ftime(&tb);
+ t->tv_sec = (long)tb.time;
+ t->tv_usec = (long)tb.millitm * 1000;
+#elif defined(OPENSSL_SYS_VMS)
+ struct timeb tb;
+ ftime(&tb);
+ t->tv_sec = (long)tb.time;
+ t->tv_usec = (long)tb.millitm * 1000;
+#else
+ gettimeofday(t, NULL);
+#endif
+ }
diff --git a/openssl/crypto/bio/bss_file.c b/openssl/crypto/bio/bss_file.c
index a3d925d94..b954fe7eb 100644
--- a/openssl/crypto/bio/bss_file.c
+++ b/openssl/crypto/bio/bss_file.c
@@ -1,477 +1,477 @@
-/* crypto/bio/bss_file.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-/*
- * 03-Dec-1997 rdenny@dc3.com Fix bug preventing use of stdin/stdout
- * with binary data (e.g. asn1parse -inform DER < xxx) under
- * Windows
- */
-
-#ifndef HEADER_BSS_FILE_C
-#define HEADER_BSS_FILE_C
-
-#if defined(__linux) || defined(__sun) || defined(__hpux)
-/* Following definition aliases fopen to fopen64 on above mentioned
- * platforms. This makes it possible to open and sequentially access
- * files larger than 2GB from 32-bit application. It does not allow to
- * traverse them beyond 2GB with fseek/ftell, but on the other hand *no*
- * 32-bit platform permits that, not with fseek/ftell. Not to mention
- * that breaking 2GB limit for seeking would require surgery to *our*
- * API. But sequential access suffices for practical cases when you
- * can run into large files, such as fingerprinting, so we can let API
- * alone. For reference, the list of 32-bit platforms which allow for
- * sequential access of large files without extra "magic" comprise *BSD,
- * Darwin, IRIX...
- */
-#ifndef _FILE_OFFSET_BITS
-#define _FILE_OFFSET_BITS 64
-#endif
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include "cryptlib.h"
-#include "bio_lcl.h"
-#include <openssl/err.h>
-
-#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
-#include <nwfileio.h>
-#endif
-
-#if !defined(OPENSSL_NO_STDIO)
-
-static int MS_CALLBACK file_write(BIO *h, const char *buf, int num);
-static int MS_CALLBACK file_read(BIO *h, char *buf, int size);
-static int MS_CALLBACK file_puts(BIO *h, const char *str);
-static int MS_CALLBACK file_gets(BIO *h, char *str, int size);
-static long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-static int MS_CALLBACK file_new(BIO *h);
-static int MS_CALLBACK file_free(BIO *data);
-static BIO_METHOD methods_filep=
- {
- BIO_TYPE_FILE,
- "FILE pointer",
- file_write,
- file_read,
- file_puts,
- file_gets,
- file_ctrl,
- file_new,
- file_free,
- NULL,
- };
-
-BIO *BIO_new_file(const char *filename, const char *mode)
- {
- BIO *ret;
- FILE *file=NULL;
-
-#if defined(_WIN32) && defined(CP_UTF8)
- int sz, len_0 = (int)strlen(filename)+1;
- DWORD flags;
-
- /*
- * Basically there are three cases to cover: a) filename is
- * pure ASCII string; b) actual UTF-8 encoded string and
- * c) locale-ized string, i.e. one containing 8-bit
- * characters that are meaningful in current system locale.
- * If filename is pure ASCII or real UTF-8 encoded string,
- * MultiByteToWideChar succeeds and _wfopen works. If
- * filename is locale-ized string, chances are that
- * MultiByteToWideChar fails reporting
- * ERROR_NO_UNICODE_TRANSLATION, in which case we fall
- * back to fopen...
- */
- if ((sz=MultiByteToWideChar(CP_UTF8,(flags=MB_ERR_INVALID_CHARS),
- filename,len_0,NULL,0))>0 ||
- (GetLastError()==ERROR_INVALID_FLAGS &&
- (sz=MultiByteToWideChar(CP_UTF8,(flags=0),
- filename,len_0,NULL,0))>0)
- )
- {
- WCHAR wmode[8];
- WCHAR *wfilename = _alloca(sz*sizeof(WCHAR));
-
- if (MultiByteToWideChar(CP_UTF8,flags,
- filename,len_0,wfilename,sz) &&
- MultiByteToWideChar(CP_UTF8,0,mode,strlen(mode)+1,
- wmode,sizeof(wmode)/sizeof(wmode[0])) &&
- (file=_wfopen(wfilename,wmode))==NULL &&
- (errno==ENOENT || errno==EBADF)
- ) /* UTF-8 decode succeeded, but no file, filename
- * could still have been locale-ized... */
- file = fopen(filename,mode);
- }
- else if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION)
- {
- file = fopen(filename,mode);
- }
-#else
- file=fopen(filename,mode);
-#endif
- if (file == NULL)
- {
- SYSerr(SYS_F_FOPEN,get_last_sys_error());
- ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
- if (errno == ENOENT)
- BIOerr(BIO_F_BIO_NEW_FILE,BIO_R_NO_SUCH_FILE);
- else
- BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
- return(NULL);
- }
- if ((ret=BIO_new(BIO_s_file())) == NULL)
- {
- fclose(file);
- return(NULL);
- }
-
- BIO_clear_flags(ret,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
- BIO_set_fp(ret,file,BIO_CLOSE);
- return(ret);
- }
-
-BIO *BIO_new_fp(FILE *stream, int close_flag)
- {
- BIO *ret;
-
- if ((ret=BIO_new(BIO_s_file())) == NULL)
- return(NULL);
-
- BIO_set_flags(ret,BIO_FLAGS_UPLINK); /* redundant, left for documentation puposes */
- BIO_set_fp(ret,stream,close_flag);
- return(ret);
- }
-
-BIO_METHOD *BIO_s_file(void)
- {
- return(&methods_filep);
- }
-
-static int MS_CALLBACK file_new(BIO *bi)
- {
- bi->init=0;
- bi->num=0;
- bi->ptr=NULL;
- bi->flags=BIO_FLAGS_UPLINK; /* default to UPLINK */
- return(1);
- }
-
-static int MS_CALLBACK file_free(BIO *a)
- {
- if (a == NULL) return(0);
- if (a->shutdown)
- {
- if ((a->init) && (a->ptr != NULL))
- {
- if (a->flags&BIO_FLAGS_UPLINK)
- UP_fclose (a->ptr);
- else
- fclose (a->ptr);
- a->ptr=NULL;
- a->flags=BIO_FLAGS_UPLINK;
- }
- a->init=0;
- }
- return(1);
- }
-
-static int MS_CALLBACK file_read(BIO *b, char *out, int outl)
- {
- int ret=0;
-
- if (b->init && (out != NULL))
- {
- if (b->flags&BIO_FLAGS_UPLINK)
- ret=UP_fread(out,1,(int)outl,b->ptr);
- else
- ret=fread(out,1,(int)outl,(FILE *)b->ptr);
- if(ret == 0 && (b->flags&BIO_FLAGS_UPLINK)?UP_ferror((FILE *)b->ptr):ferror((FILE *)b->ptr))
- {
- SYSerr(SYS_F_FREAD,get_last_sys_error());
- BIOerr(BIO_F_FILE_READ,ERR_R_SYS_LIB);
- ret=-1;
- }
- }
- return(ret);
- }
-
-static int MS_CALLBACK file_write(BIO *b, const char *in, int inl)
- {
- int ret=0;
-
- if (b->init && (in != NULL))
- {
- if (b->flags&BIO_FLAGS_UPLINK)
- ret=UP_fwrite(in,(int)inl,1,b->ptr);
- else
- ret=fwrite(in,(int)inl,1,(FILE *)b->ptr);
- if (ret)
- ret=inl;
- /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
- /* according to Tim Hudson <tjh@cryptsoft.com>, the commented
- * out version above can cause 'inl' write calls under
- * some stupid stdio implementations (VMS) */
- }
- return(ret);
- }
-
-static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
- {
- long ret=1;
- FILE *fp=(FILE *)b->ptr;
- FILE **fpp;
- char p[4];
-
- switch (cmd)
- {
- case BIO_C_FILE_SEEK:
- case BIO_CTRL_RESET:
- if (b->flags&BIO_FLAGS_UPLINK)
- ret=(long)UP_fseek(b->ptr,num,0);
- else
- ret=(long)fseek(fp,num,0);
- break;
- case BIO_CTRL_EOF:
- if (b->flags&BIO_FLAGS_UPLINK)
- ret=(long)UP_feof(fp);
- else
- ret=(long)feof(fp);
- break;
- case BIO_C_FILE_TELL:
- case BIO_CTRL_INFO:
- if (b->flags&BIO_FLAGS_UPLINK)
- ret=UP_ftell(b->ptr);
- else
- ret=ftell(fp);
- break;
- case BIO_C_SET_FILE_PTR:
- file_free(b);
- b->shutdown=(int)num&BIO_CLOSE;
- b->ptr=ptr;
- b->init=1;
-#if BIO_FLAGS_UPLINK!=0
-#if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
-#define _IOB_ENTRIES 20
-#endif
-#if defined(_IOB_ENTRIES)
- /* Safety net to catch purely internal BIO_set_fp calls */
- if ((size_t)ptr >= (size_t)stdin &&
- (size_t)ptr < (size_t)(stdin+_IOB_ENTRIES))
- BIO_clear_flags(b,BIO_FLAGS_UPLINK);
-#endif
-#endif
-#ifdef UP_fsetmod
- if (b->flags&BIO_FLAGS_UPLINK)
- UP_fsetmod(b->ptr,(char)((num&BIO_FP_TEXT)?'t':'b'));
- else
-#endif
- {
-#if defined(OPENSSL_SYS_WINDOWS)
- int fd = _fileno((FILE*)ptr);
- if (num & BIO_FP_TEXT)
- _setmode(fd,_O_TEXT);
- else
- _setmode(fd,_O_BINARY);
-#elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
- int fd = fileno((FILE*)ptr);
- /* Under CLib there are differences in file modes */
- if (num & BIO_FP_TEXT)
- setmode(fd,O_TEXT);
- else
- setmode(fd,O_BINARY);
-#elif defined(OPENSSL_SYS_MSDOS)
- int fd = fileno((FILE*)ptr);
- /* Set correct text/binary mode */
- if (num & BIO_FP_TEXT)
- _setmode(fd,_O_TEXT);
- /* Dangerous to set stdin/stdout to raw (unless redirected) */
- else
- {
- if (fd == STDIN_FILENO || fd == STDOUT_FILENO)
- {
- if (isatty(fd) <= 0)
- _setmode(fd,_O_BINARY);
- }
- else
- _setmode(fd,_O_BINARY);
- }
-#elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
- int fd = fileno((FILE*)ptr);
- if (num & BIO_FP_TEXT)
- setmode(fd, O_TEXT);
- else
- setmode(fd, O_BINARY);
-#endif
- }
- break;
- case BIO_C_SET_FILENAME:
- file_free(b);
- b->shutdown=(int)num&BIO_CLOSE;
- if (num & BIO_FP_APPEND)
- {
- if (num & BIO_FP_READ)
- BUF_strlcpy(p,"a+",sizeof p);
- else BUF_strlcpy(p,"a",sizeof p);
- }
- else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
- BUF_strlcpy(p,"r+",sizeof p);
- else if (num & BIO_FP_WRITE)
- BUF_strlcpy(p,"w",sizeof p);
- else if (num & BIO_FP_READ)
- BUF_strlcpy(p,"r",sizeof p);
- else
- {
- BIOerr(BIO_F_FILE_CTRL,BIO_R_BAD_FOPEN_MODE);
- ret=0;
- break;
- }
-#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
- if (!(num & BIO_FP_TEXT))
- strcat(p,"b");
- else
- strcat(p,"t");
-#endif
-#if defined(OPENSSL_SYS_NETWARE)
- if (!(num & BIO_FP_TEXT))
- strcat(p,"b");
- else
- strcat(p,"t");
-#endif
- fp=fopen(ptr,p);
- if (fp == NULL)
- {
- SYSerr(SYS_F_FOPEN,get_last_sys_error());
- ERR_add_error_data(5,"fopen('",ptr,"','",p,"')");
- BIOerr(BIO_F_FILE_CTRL,ERR_R_SYS_LIB);
- ret=0;
- break;
- }
- b->ptr=fp;
- b->init=1;
- BIO_clear_flags(b,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
- break;
- case BIO_C_GET_FILE_PTR:
- /* the ptr parameter is actually a FILE ** in this case. */
- if (ptr != NULL)
- {
- fpp=(FILE **)ptr;
- *fpp=(FILE *)b->ptr;
- }
- break;
- case BIO_CTRL_GET_CLOSE:
- ret=(long)b->shutdown;
- break;
- case BIO_CTRL_SET_CLOSE:
- b->shutdown=(int)num;
- break;
- case BIO_CTRL_FLUSH:
- if (b->flags&BIO_FLAGS_UPLINK)
- UP_fflush(b->ptr);
- else
- fflush((FILE *)b->ptr);
- break;
- case BIO_CTRL_DUP:
- ret=1;
- break;
-
- case BIO_CTRL_WPENDING:
- case BIO_CTRL_PENDING:
- case BIO_CTRL_PUSH:
- case BIO_CTRL_POP:
- default:
- ret=0;
- break;
- }
- return(ret);
- }
-
-static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)
- {
- int ret=0;
-
- buf[0]='\0';
- if (bp->flags&BIO_FLAGS_UPLINK)
- {
- if (!UP_fgets(buf,size,bp->ptr))
- goto err;
- }
- else
- {
- if (!fgets(buf,size,(FILE *)bp->ptr))
- goto err;
- }
- if (buf[0] != '\0')
- ret=strlen(buf);
- err:
- return(ret);
- }
-
-static int MS_CALLBACK file_puts(BIO *bp, const char *str)
- {
- int n,ret;
-
- n=strlen(str);
- ret=file_write(bp,str,n);
- return(ret);
- }
-
-#endif /* OPENSSL_NO_STDIO */
-
-#endif /* HEADER_BSS_FILE_C */
-
-
+/* crypto/bio/bss_file.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * 03-Dec-1997 rdenny@dc3.com Fix bug preventing use of stdin/stdout
+ * with binary data (e.g. asn1parse -inform DER < xxx) under
+ * Windows
+ */
+
+#ifndef HEADER_BSS_FILE_C
+#define HEADER_BSS_FILE_C
+
+#if defined(__linux) || defined(__sun) || defined(__hpux)
+/* Following definition aliases fopen to fopen64 on above mentioned
+ * platforms. This makes it possible to open and sequentially access
+ * files larger than 2GB from 32-bit application. It does not allow to
+ * traverse them beyond 2GB with fseek/ftell, but on the other hand *no*
+ * 32-bit platform permits that, not with fseek/ftell. Not to mention
+ * that breaking 2GB limit for seeking would require surgery to *our*
+ * API. But sequential access suffices for practical cases when you
+ * can run into large files, such as fingerprinting, so we can let API
+ * alone. For reference, the list of 32-bit platforms which allow for
+ * sequential access of large files without extra "magic" comprise *BSD,
+ * Darwin, IRIX...
+ */
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64
+#endif
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include "bio_lcl.h"
+#include <openssl/err.h>
+
+#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
+#include <nwfileio.h>
+#endif
+
+#if !defined(OPENSSL_NO_STDIO)
+
+static int MS_CALLBACK file_write(BIO *h, const char *buf, int num);
+static int MS_CALLBACK file_read(BIO *h, char *buf, int size);
+static int MS_CALLBACK file_puts(BIO *h, const char *str);
+static int MS_CALLBACK file_gets(BIO *h, char *str, int size);
+static long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int MS_CALLBACK file_new(BIO *h);
+static int MS_CALLBACK file_free(BIO *data);
+static BIO_METHOD methods_filep=
+ {
+ BIO_TYPE_FILE,
+ "FILE pointer",
+ file_write,
+ file_read,
+ file_puts,
+ file_gets,
+ file_ctrl,
+ file_new,
+ file_free,
+ NULL,
+ };
+
+BIO *BIO_new_file(const char *filename, const char *mode)
+ {
+ BIO *ret;
+ FILE *file=NULL;
+
+#if defined(_WIN32) && defined(CP_UTF8)
+ int sz, len_0 = (int)strlen(filename)+1;
+ DWORD flags;
+
+ /*
+ * Basically there are three cases to cover: a) filename is
+ * pure ASCII string; b) actual UTF-8 encoded string and
+ * c) locale-ized string, i.e. one containing 8-bit
+ * characters that are meaningful in current system locale.
+ * If filename is pure ASCII or real UTF-8 encoded string,
+ * MultiByteToWideChar succeeds and _wfopen works. If
+ * filename is locale-ized string, chances are that
+ * MultiByteToWideChar fails reporting
+ * ERROR_NO_UNICODE_TRANSLATION, in which case we fall
+ * back to fopen...
+ */
+ if ((sz=MultiByteToWideChar(CP_UTF8,(flags=MB_ERR_INVALID_CHARS),
+ filename,len_0,NULL,0))>0 ||
+ (GetLastError()==ERROR_INVALID_FLAGS &&
+ (sz=MultiByteToWideChar(CP_UTF8,(flags=0),
+ filename,len_0,NULL,0))>0)
+ )
+ {
+ WCHAR wmode[8];
+ WCHAR *wfilename = _alloca(sz*sizeof(WCHAR));
+
+ if (MultiByteToWideChar(CP_UTF8,flags,
+ filename,len_0,wfilename,sz) &&
+ MultiByteToWideChar(CP_UTF8,0,mode,strlen(mode)+1,
+ wmode,sizeof(wmode)/sizeof(wmode[0])) &&
+ (file=_wfopen(wfilename,wmode))==NULL &&
+ (errno==ENOENT || errno==EBADF)
+ ) /* UTF-8 decode succeeded, but no file, filename
+ * could still have been locale-ized... */
+ file = fopen(filename,mode);
+ }
+ else if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION)
+ {
+ file = fopen(filename,mode);
+ }
+#else
+ file=fopen(filename,mode);
+#endif
+ if (file == NULL)
+ {
+ SYSerr(SYS_F_FOPEN,get_last_sys_error());
+ ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
+ if (errno == ENOENT)
+ BIOerr(BIO_F_BIO_NEW_FILE,BIO_R_NO_SUCH_FILE);
+ else
+ BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
+ return(NULL);
+ }
+ if ((ret=BIO_new(BIO_s_file())) == NULL)
+ {
+ fclose(file);
+ return(NULL);
+ }
+
+ BIO_clear_flags(ret,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
+ BIO_set_fp(ret,file,BIO_CLOSE);
+ return(ret);
+ }
+
+BIO *BIO_new_fp(FILE *stream, int close_flag)
+ {
+ BIO *ret;
+
+ if ((ret=BIO_new(BIO_s_file())) == NULL)
+ return(NULL);
+
+ BIO_set_flags(ret,BIO_FLAGS_UPLINK); /* redundant, left for documentation puposes */
+ BIO_set_fp(ret,stream,close_flag);
+ return(ret);
+ }
+
+BIO_METHOD *BIO_s_file(void)
+ {
+ return(&methods_filep);
+ }
+
+static int MS_CALLBACK file_new(BIO *bi)
+ {
+ bi->init=0;
+ bi->num=0;
+ bi->ptr=NULL;
+ bi->flags=BIO_FLAGS_UPLINK; /* default to UPLINK */
+ return(1);
+ }
+
+static int MS_CALLBACK file_free(BIO *a)
+ {
+ if (a == NULL) return(0);
+ if (a->shutdown)
+ {
+ if ((a->init) && (a->ptr != NULL))
+ {
+ if (a->flags&BIO_FLAGS_UPLINK)
+ UP_fclose (a->ptr);
+ else
+ fclose (a->ptr);
+ a->ptr=NULL;
+ a->flags=BIO_FLAGS_UPLINK;
+ }
+ a->init=0;
+ }
+ return(1);
+ }
+
+static int MS_CALLBACK file_read(BIO *b, char *out, int outl)
+ {
+ int ret=0;
+
+ if (b->init && (out != NULL))
+ {
+ if (b->flags&BIO_FLAGS_UPLINK)
+ ret=UP_fread(out,1,(int)outl,b->ptr);
+ else
+ ret=fread(out,1,(int)outl,(FILE *)b->ptr);
+ if(ret == 0 && (b->flags&BIO_FLAGS_UPLINK)?UP_ferror((FILE *)b->ptr):ferror((FILE *)b->ptr))
+ {
+ SYSerr(SYS_F_FREAD,get_last_sys_error());
+ BIOerr(BIO_F_FILE_READ,ERR_R_SYS_LIB);
+ ret=-1;
+ }
+ }
+ return(ret);
+ }
+
+static int MS_CALLBACK file_write(BIO *b, const char *in, int inl)
+ {
+ int ret=0;
+
+ if (b->init && (in != NULL))
+ {
+ if (b->flags&BIO_FLAGS_UPLINK)
+ ret=UP_fwrite(in,(int)inl,1,b->ptr);
+ else
+ ret=fwrite(in,(int)inl,1,(FILE *)b->ptr);
+ if (ret)
+ ret=inl;
+ /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
+ /* according to Tim Hudson <tjh@cryptsoft.com>, the commented
+ * out version above can cause 'inl' write calls under
+ * some stupid stdio implementations (VMS) */
+ }
+ return(ret);
+ }
+
+static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
+ {
+ long ret=1;
+ FILE *fp=(FILE *)b->ptr;
+ FILE **fpp;
+ char p[4];
+
+ switch (cmd)
+ {
+ case BIO_C_FILE_SEEK:
+ case BIO_CTRL_RESET:
+ if (b->flags&BIO_FLAGS_UPLINK)
+ ret=(long)UP_fseek(b->ptr,num,0);
+ else
+ ret=(long)fseek(fp,num,0);
+ break;
+ case BIO_CTRL_EOF:
+ if (b->flags&BIO_FLAGS_UPLINK)
+ ret=(long)UP_feof(fp);
+ else
+ ret=(long)feof(fp);
+ break;
+ case BIO_C_FILE_TELL:
+ case BIO_CTRL_INFO:
+ if (b->flags&BIO_FLAGS_UPLINK)
+ ret=UP_ftell(b->ptr);
+ else
+ ret=ftell(fp);
+ break;
+ case BIO_C_SET_FILE_PTR:
+ file_free(b);
+ b->shutdown=(int)num&BIO_CLOSE;
+ b->ptr=ptr;
+ b->init=1;
+#if BIO_FLAGS_UPLINK!=0
+#if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
+#define _IOB_ENTRIES 20
+#endif
+#if defined(_IOB_ENTRIES)
+ /* Safety net to catch purely internal BIO_set_fp calls */
+ if ((size_t)ptr >= (size_t)stdin &&
+ (size_t)ptr < (size_t)(stdin+_IOB_ENTRIES))
+ BIO_clear_flags(b,BIO_FLAGS_UPLINK);
+#endif
+#endif
+#ifdef UP_fsetmod
+ if (b->flags&BIO_FLAGS_UPLINK)
+ UP_fsetmod(b->ptr,(char)((num&BIO_FP_TEXT)?'t':'b'));
+ else
+#endif
+ {
+#if defined(OPENSSL_SYS_WINDOWS)
+ int fd = _fileno((FILE*)ptr);
+ if (num & BIO_FP_TEXT)
+ _setmode(fd,_O_TEXT);
+ else
+ _setmode(fd,_O_BINARY);
+#elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
+ int fd = fileno((FILE*)ptr);
+ /* Under CLib there are differences in file modes */
+ if (num & BIO_FP_TEXT)
+ setmode(fd,O_TEXT);
+ else
+ setmode(fd,O_BINARY);
+#elif defined(OPENSSL_SYS_MSDOS)
+ int fd = fileno((FILE*)ptr);
+ /* Set correct text/binary mode */
+ if (num & BIO_FP_TEXT)
+ _setmode(fd,_O_TEXT);
+ /* Dangerous to set stdin/stdout to raw (unless redirected) */
+ else
+ {
+ if (fd == STDIN_FILENO || fd == STDOUT_FILENO)
+ {
+ if (isatty(fd) <= 0)
+ _setmode(fd,_O_BINARY);
+ }
+ else
+ _setmode(fd,_O_BINARY);
+ }
+#elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
+ int fd = fileno((FILE*)ptr);
+ if (num & BIO_FP_TEXT)
+ setmode(fd, O_TEXT);
+ else
+ setmode(fd, O_BINARY);
+#endif
+ }
+ break;
+ case BIO_C_SET_FILENAME:
+ file_free(b);
+ b->shutdown=(int)num&BIO_CLOSE;
+ if (num & BIO_FP_APPEND)
+ {
+ if (num & BIO_FP_READ)
+ BUF_strlcpy(p,"a+",sizeof p);
+ else BUF_strlcpy(p,"a",sizeof p);
+ }
+ else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
+ BUF_strlcpy(p,"r+",sizeof p);
+ else if (num & BIO_FP_WRITE)
+ BUF_strlcpy(p,"w",sizeof p);
+ else if (num & BIO_FP_READ)
+ BUF_strlcpy(p,"r",sizeof p);
+ else
+ {
+ BIOerr(BIO_F_FILE_CTRL,BIO_R_BAD_FOPEN_MODE);
+ ret=0;
+ break;
+ }
+#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
+ if (!(num & BIO_FP_TEXT))
+ strcat(p,"b");
+ else
+ strcat(p,"t");
+#endif
+#if defined(OPENSSL_SYS_NETWARE)
+ if (!(num & BIO_FP_TEXT))
+ strcat(p,"b");
+ else
+ strcat(p,"t");
+#endif
+ fp=fopen(ptr,p);
+ if (fp == NULL)
+ {
+ SYSerr(SYS_F_FOPEN,get_last_sys_error());
+ ERR_add_error_data(5,"fopen('",ptr,"','",p,"')");
+ BIOerr(BIO_F_FILE_CTRL,ERR_R_SYS_LIB);
+ ret=0;
+ break;
+ }
+ b->ptr=fp;
+ b->init=1;
+ BIO_clear_flags(b,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
+ break;
+ case BIO_C_GET_FILE_PTR:
+ /* the ptr parameter is actually a FILE ** in this case. */
+ if (ptr != NULL)
+ {
+ fpp=(FILE **)ptr;
+ *fpp=(FILE *)b->ptr;
+ }
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret=(long)b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown=(int)num;
+ break;
+ case BIO_CTRL_FLUSH:
+ if (b->flags&BIO_FLAGS_UPLINK)
+ UP_fflush(b->ptr);
+ else
+ fflush((FILE *)b->ptr);
+ break;
+ case BIO_CTRL_DUP:
+ ret=1;
+ break;
+
+ case BIO_CTRL_WPENDING:
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_PUSH:
+ case BIO_CTRL_POP:
+ default:
+ ret=0;
+ break;
+ }
+ return(ret);
+ }
+
+static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)
+ {
+ int ret=0;
+
+ buf[0]='\0';
+ if (bp->flags&BIO_FLAGS_UPLINK)
+ {
+ if (!UP_fgets(buf,size,bp->ptr))
+ goto err;
+ }
+ else
+ {
+ if (!fgets(buf,size,(FILE *)bp->ptr))
+ goto err;
+ }
+ if (buf[0] != '\0')
+ ret=strlen(buf);
+ err:
+ return(ret);
+ }
+
+static int MS_CALLBACK file_puts(BIO *bp, const char *str)
+ {
+ int n,ret;
+
+ n=strlen(str);
+ ret=file_write(bp,str,n);
+ return(ret);
+ }
+
+#endif /* OPENSSL_NO_STDIO */
+
+#endif /* HEADER_BSS_FILE_C */
+
+
diff --git a/openssl/crypto/comp/c_rle.c b/openssl/crypto/comp/c_rle.c
index 3f0ae4c56..18bceae51 100644
--- a/openssl/crypto/comp/c_rle.c
+++ b/openssl/crypto/comp/c_rle.c
@@ -1,61 +1,61 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <openssl/objects.h>
-#include <openssl/comp.h>
-
-static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
- unsigned int olen, unsigned char *in, unsigned int ilen);
-static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
- unsigned int olen, unsigned char *in, unsigned int ilen);
-
-static COMP_METHOD rle_method={
- NID_rle_compression,
- LN_rle_compression,
- NULL,
- NULL,
- rle_compress_block,
- rle_expand_block,
- NULL,
- NULL,
- };
-
-COMP_METHOD *COMP_rle(void)
- {
- return(&rle_method);
- }
-
-static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
- unsigned int olen, unsigned char *in, unsigned int ilen)
- {
- /* int i; */
-
- if (olen < (ilen+1))
- {
- /* ZZZZZZZZZZZZZZZZZZZZZZ */
- return(-1);
- }
-
- *(out++)=0;
- memcpy(out,in,ilen);
- return(ilen+1);
- }
-
-static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
- unsigned int olen, unsigned char *in, unsigned int ilen)
- {
- int i;
-
- if (ilen == 0 || olen < (ilen-1))
- {
- /* ZZZZZZZZZZZZZZZZZZZZZZ */
- return(-1);
- }
-
- i= *(in++);
- if (i == 0)
- {
- memcpy(out,in,ilen-1);
- }
- return(ilen-1);
- }
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/objects.h>
+#include <openssl/comp.h>
+
+static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in, unsigned int ilen);
+static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in, unsigned int ilen);
+
+static COMP_METHOD rle_method={
+ NID_rle_compression,
+ LN_rle_compression,
+ NULL,
+ NULL,
+ rle_compress_block,
+ rle_expand_block,
+ NULL,
+ NULL,
+ };
+
+COMP_METHOD *COMP_rle(void)
+ {
+ return(&rle_method);
+ }
+
+static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in, unsigned int ilen)
+ {
+ /* int i; */
+
+ if (olen < (ilen+1))
+ {
+ /* ZZZZZZZZZZZZZZZZZZZZZZ */
+ return(-1);
+ }
+
+ *(out++)=0;
+ memcpy(out,in,ilen);
+ return(ilen+1);
+ }
+
+static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
+ unsigned int olen, unsigned char *in, unsigned int ilen)
+ {
+ int i;
+
+ if (ilen == 0 || olen < (ilen-1))
+ {
+ /* ZZZZZZZZZZZZZZZZZZZZZZ */
+ return(-1);
+ }
+
+ i= *(in++);
+ if (i == 0)
+ {
+ memcpy(out,in,ilen-1);
+ }
+ return(ilen-1);
+ }
diff --git a/openssl/crypto/crypto-lib.com b/openssl/crypto/crypto-lib.com
index f6d6c53cb..6719c8aed 100644
--- a/openssl/crypto/crypto-lib.com
+++ b/openssl/crypto/crypto-lib.com
@@ -1,1395 +1,1395 @@
-$!
-$! CRYPTO-LIB.COM
-$! Written By: Robert Byer
-$! Vice-President
-$! A-Com Computing, Inc.
-$! byer@mail.all-net.net
-$!
-$! Changes by Richard Levitte <richard@levitte.org>
-$! Zoltan Arpadffy <arpadffy@polarhome.com>
-$!
-$! This command files compiles and creates the "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB"
-$! library for OpenSSL. The "xxx" denotes the machine architecture, ALPHA,
-$! IA64 or VAX.
-$!
-$! It was re-written so it would try to determine what "C" compiler to use
-$! or you can specify which "C" compiler to use.
-$!
-$! Specify the following as P1 to build just that part or ALL to just
-$! build everything.
-$!
-$! LIBRARY To just compile the [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
-$! APPS To just compile the [.xxx.EXE.CRYPTO]*.EXE
-$! ALL To do both LIBRARY and APPS
-$!
-$! Specify DEBUG or NODEBUG as P2 to compile with or without debugger
-$! information.
-$!
-$! Specify which compiler at P3 to try to compile under.
-$!
-$! VAXC For VAX C.
-$! DECC For DEC C.
-$! GNUC For GNU C.
-$!
-$! If you don't specify a compiler, it will try to determine which
-$! "C" compiler to use.
-$!
-$! P4, if defined, sets a TCP/IP library to use, through one of the following
-$! keywords:
-$!
-$! UCX For UCX
-$! TCPIP For TCPIP (post UCX)
-$! SOCKETSHR For SOCKETSHR+NETLIB
-$!
-$! P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
-$!
-$! P6, if defined, sets a choice of crypto methods to compile.
-$! WARNING: this should only be done to recompile some part of an already
-$! fully compiled library.
-$!
-$! For 64 bit architectures (Alpha and IA64), specify the pointer size as P7.
-$! For 32 bit architectures (VAX), P7 is ignored.
-$! Currently supported values are:
-$!
-$! 32 To ge a library compiled with /POINTER_SIZE=32
-$! 64 To ge a library compiled with /POINTER_SIZE=64
-$!
-$!
-$! Define A TCP/IP Library That We Will Need To Link To.
-$! (That Is, If We Need To Link To One.)
-$!
-$ TCPIP_LIB = ""
-$!
-$! Check Which Architecture We Are Using.
-$!
-$ IF (F$GETSYI("CPU").LT.128)
-$ THEN
-$!
-$! The Architecture Is VAX
-$!
-$ ARCH = "VAX"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! The Architecture Is Alpha, IA64 or whatever comes in the future.
-$!
-$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
-$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
-$!
-$! End The Architecture Check.
-$!
-$ ENDIF
-$!
-$! Define The Different Encryption Types.
-$! NOTE: Some might think this list ugly. However, it's made this way to
-$! reflect the SDIRS variable in [-]Makefile.org as closely as possible,
-$! thereby making it fairly easy to verify that the lists are the same.
-$!
-$ ET_WHIRLPOOL = "WHRLPOOL"
-$ IF ARCH .EQS. "VAX" THEN ET_WHIRLPOOL = ""
-$ ENCRYPT_TYPES = "Basic,"+ -
- "OBJECTS,"+ -
- "MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,"+ET_WHIRLPOOL+","+ -
- "DES,AES,RC2,RC4,RC5,IDEA,BF,CAST,CAMELLIA,SEED,MODES,"+ -
- "BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,"+ -
- "BUFFER,BIO,STACK,LHASH,RAND,ERR,"+ -
- "EVP,EVP_2,EVP_3,ASN1,ASN1_2,PEM,X509,X509V3,"+ -
- "CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,UI,KRB5,"+ -
- "STORE,CMS,PQUEUE,TS,JPAKE"
-$! Define The OBJ Directory.
-$!
-$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.CRYPTO]
-$!
-$! Define The EXE Directory.
-$!
-$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.CRYPTO]
-$!
-$! Check To Make Sure We Have Valid Command Line Parameters.
-$!
-$ GOSUB CHECK_OPTIONS
-$!
-$! Initialise logical names and such
-$!
-$ GOSUB INITIALISE
-$!
-$! Tell The User What Kind of Machine We Run On.
-$!
-$ WRITE SYS$OUTPUT "Compiling On A ",ARCH," Machine."
-$!
-$!
-$! Check To See If The Architecture Specific OBJ Directory Exists.
-$!
-$ IF (F$PARSE(OBJ_DIR).EQS."")
-$ THEN
-$!
-$! It Dosen't Exist, So Create It.
-$!
-$ CREATE/DIR 'OBJ_DIR'
-$!
-$! End The Architecture Specific OBJ Directory Check.
-$!
-$ ENDIF
-$!
-$! Check To See If The Architecture Specific Directory Exists.
-$!
-$ IF (F$PARSE(EXE_DIR).EQS."")
-$ THEN
-$!
-$! It Dosen't Exist, So Create It.
-$!
-$ CREATE/DIRECTORY 'EXE_DIR'
-$!
-$! End The Architecture Specific Directory Check.
-$!
-$ ENDIF
-$!
-$! Define The Library Name.
-$!
-$ LIB_NAME := 'EXE_DIR'LIBCRYPTO'LIB32'.OLB
-$!
-$! Define The CRYPTO-LIB We Are To Use.
-$!
-$ CRYPTO_LIB := 'EXE_DIR'LIBCRYPTO'LIB32'.OLB
-$!
-$! Check To See If We Already Have A "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" Library...
-$!
-$ IF (F$SEARCH(LIB_NAME).EQS."")
-$ THEN
-$!
-$! Guess Not, Create The Library.
-$!
-$ LIBRARY/CREATE/OBJECT 'LIB_NAME'
-$!
-$! End The Library Check.
-$!
-$ ENDIF
-$!
-$! Build our options file for the application
-$!
-$ GOSUB CHECK_OPT_FILE
-$!
-$! Define The Different Encryption "library" Strings.
-$!
-$ APPS_DES = "DES/DES,CBC3_ENC"
-$ APPS_PKCS7 = "ENC/ENC;DEC/DEC;SIGN/SIGN;VERIFY/VERIFY,EXAMPLE"
-$
-$ LIB_ = "cryptlib,mem,mem_clr,mem_dbg,cversion,ex_data,cpt_err,ebcdic,uid,o_time,o_str,o_dir"
-$ LIB_MD2 = "md2_dgst,md2_one"
-$ LIB_MD4 = "md4_dgst,md4_one"
-$ LIB_MD5 = "md5_dgst,md5_one"
-$ LIB_SHA = "sha_dgst,sha1dgst,sha_one,sha1_one,sha256,sha512"
-$ LIB_MDC2 = "mdc2dgst,mdc2_one"
-$ LIB_HMAC = "hmac,hm_ameth,hm_pmeth"
-$ LIB_RIPEMD = "rmd_dgst,rmd_one"
-$ LIB_WHRLPOOL = "wp_dgst,wp_block"
-$ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ -
- "ecb3_enc,cfb64enc,cfb64ede,cfb_enc,ofb64ede,"+ -
- "enc_read,enc_writ,ofb64enc,"+ -
- "ofb_enc,str2key,pcbc_enc,qud_cksm,rand_key,"+ -
- "des_enc,fcrypt_b,"+ -
- "fcrypt,xcbc_enc,rpc_enc,cbc_cksm,"+ -
- "ede_cbcm_enc,des_old,des_old2,read2pwd"
-$ LIB_RC2 = "rc2_ecb,rc2_skey,rc2_cbc,rc2cfb64,rc2ofb64"
-$ LIB_RC4 = "rc4_skey,rc4_enc"
-$ LIB_RC5 = "rc5_skey,rc5_ecb,rc5_enc,rc5cfb64,rc5ofb64"
-$ LIB_IDEA = "i_cbc,i_cfb64,i_ofb64,i_ecb,i_skey"
-$ LIB_BF = "bf_skey,bf_ecb,bf_enc,bf_cfb64,bf_ofb64"
-$ LIB_CAST = "c_skey,c_ecb,c_enc,c_cfb64,c_ofb64"
-$ LIB_CAMELLIA = "camellia,cmll_misc,cmll_ecb,cmll_cbc,cmll_ofb,"+ -
- "cmll_cfb,cmll_ctr"
-$ LIB_SEED = "seed,seed_ecb,seed_cbc,seed_cfb,seed_ofb"
-$ LIB_MODES = "cbc128,ctr128,cfb128,ofb128,cts128"
-$ LIB_BN_ASM = "[.asm]vms.mar,vms-helper"
-$ IF F$TRNLNM("OPENSSL_NO_ASM") .OR. ARCH .NES. "VAX" THEN -
- LIB_BN_ASM = "bn_asm"
-$ LIB_BN = "bn_add,bn_div,bn_exp,bn_lib,bn_ctx,bn_mul,bn_mod,"+ -
- "bn_print,bn_rand,bn_shift,bn_word,bn_blind,"+ -
- "bn_kron,bn_sqrt,bn_gcd,bn_prime,bn_err,bn_sqr,"+LIB_BN_ASM+","+ -
- "bn_recp,bn_mont,bn_mpi,bn_exp2,bn_gf2m,bn_nist,"+ -
- "bn_depr,bn_const"
-$ LIB_EC = "ec_lib,ecp_smpl,ecp_mont,ecp_nist,ec_cvt,ec_mult,"+ -
- "ec_err,ec_curve,ec_check,ec_print,ec_asn1,ec_key,"+ -
- "ec2_smpl,ec2_mult,ec_ameth,ec_pmeth,eck_prn"
-$ LIB_RSA = "rsa_eay,rsa_gen,rsa_lib,rsa_sign,rsa_saos,rsa_err,"+ -
- "rsa_pk1,rsa_ssl,rsa_none,rsa_oaep,rsa_chk,rsa_null,"+ -
- "rsa_pss,rsa_x931,rsa_asn1,rsa_depr,rsa_ameth,rsa_prn,"+ -
- "rsa_pmeth"
-$ LIB_DSA = "dsa_gen,dsa_key,dsa_lib,dsa_asn1,dsa_vrf,dsa_sign,"+ -
- "dsa_err,dsa_ossl,dsa_depr,dsa_ameth,dsa_pmeth,dsa_prn"
-$ LIB_ECDSA = "ecs_lib,ecs_asn1,ecs_ossl,ecs_sign,ecs_vrf,ecs_err"
-$ LIB_DH = "dh_asn1,dh_gen,dh_key,dh_lib,dh_check,dh_err,dh_depr,"+ -
- "dh_ameth,dh_pmeth,dh_prn"
-$ LIB_ECDH = "ech_lib,ech_ossl,ech_key,ech_err"
-$ LIB_DSO = "dso_dl,dso_dlfcn,dso_err,dso_lib,dso_null,"+ -
- "dso_openssl,dso_win32,dso_vms,dso_beos"
-$ LIB_ENGINE = "eng_err,eng_lib,eng_list,eng_init,eng_ctrl,"+ -
- "eng_table,eng_pkey,eng_fat,eng_all,"+ -
- "tb_rsa,tb_dsa,tb_ecdsa,tb_dh,tb_ecdh,tb_rand,tb_store,"+ -
- "tb_cipher,tb_digest,tb_pkmeth,tb_asnmth,"+ -
- "eng_openssl,eng_dyn,eng_cnf,eng_cryptodev"
-$ LIB_AES = "aes_core,aes_misc,aes_ecb,aes_cbc,aes_cfb,aes_ofb,aes_ctr,"+ -
- "aes_ige,aes_wrap"
-$ LIB_BUFFER = "buffer,buf_err"
-$ LIB_BIO = "bio_lib,bio_cb,bio_err,"+ -
- "bss_mem,bss_null,bss_fd,"+ -
- "bss_file,bss_sock,bss_conn,"+ -
- "bf_null,bf_buff,b_print,b_dump,"+ -
- "b_sock,bss_acpt,bf_nbio,bss_rtcp,bss_bio,bss_log,"+ -
- "bss_dgram,"+ -
- "bf_lbuf"
-$ LIB_STACK = "stack"
-$ LIB_LHASH = "lhash,lh_stats"
-$ LIB_RAND = "md_rand,randfile,rand_lib,rand_err,rand_egd,"+ -
- "rand_vms"
-$ LIB_ERR = "err,err_all,err_prn"
-$ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err,obj_xref"
-$ LIB_EVP = "encode,digest,evp_enc,evp_key,evp_acnf,"+ -
- "e_des,e_bf,e_idea,e_des3,e_camellia,"+ -
- "e_rc4,e_aes,names,e_seed,"+ -
- "e_xcbc_d,e_rc2,e_cast,e_rc5"
-$ LIB_EVP_2 = "m_null,m_md2,m_md4,m_md5,m_sha,m_sha1,m_wp," + -
- "m_dss,m_dss1,m_mdc2,m_ripemd,m_ecdsa,"+ -
- "p_open,p_seal,p_sign,p_verify,p_lib,p_enc,p_dec,"+ -
- "bio_md,bio_b64,bio_enc,evp_err,e_null,"+ -
- "c_all,c_allc,c_alld,evp_lib,bio_ok,"+-
- "evp_pkey,evp_pbe,p5_crpt,p5_crpt2"
-$ LIB_EVP_3 = "e_old,pmeth_lib,pmeth_fn,pmeth_gn,m_sigver"
-$ LIB_ASN1 = "a_object,a_bitstr,a_utctm,a_gentm,a_time,a_int,a_octet,"+ -
- "a_print,a_type,a_set,a_dup,a_d2i_fp,a_i2d_fp,"+ -
- "a_enum,a_utf8,a_sign,a_digest,a_verify,a_mbstr,a_strex,"+ -
- "x_algor,x_val,x_pubkey,x_sig,x_req,x_attrib,x_bignum,"+ -
- "x_long,x_name,x_x509,x_x509a,x_crl,x_info,x_spki,nsseq,"+ -
- "x_nx509,d2i_pu,d2i_pr,i2d_pu,i2d_pr"
-$ LIB_ASN1_2 = "t_req,t_x509,t_x509a,t_crl,t_pkey,t_spki,t_bitst,"+ -
- "tasn_new,tasn_fre,tasn_enc,tasn_dec,tasn_utl,tasn_typ,"+ -
- "tasn_prn,ameth_lib,"+ -
- "f_int,f_string,n_pkey,"+ -
- "f_enum,x_pkey,a_bool,x_exten,bio_asn1,bio_ndef,asn_mime,"+ -
- "asn1_gen,asn1_par,asn1_lib,asn1_err,a_bytes,a_strnid,"+ -
- "evp_asn1,asn_pack,p5_pbe,p5_pbev2,p8_pkey,asn_moid"
-$ LIB_PEM = "pem_sign,pem_seal,pem_info,pem_lib,pem_all,pem_err,"+ -
- "pem_x509,pem_xaux,pem_oth,pem_pk8,pem_pkey,pvkfmt"
-$ LIB_X509 = "x509_def,x509_d2,x509_r2x,x509_cmp,"+ -
- "x509_obj,x509_req,x509spki,x509_vfy,"+ -
- "x509_set,x509cset,x509rset,x509_err,"+ -
- "x509name,x509_v3,x509_ext,x509_att,"+ -
- "x509type,x509_lu,x_all,x509_txt,"+ -
- "x509_trs,by_file,by_dir,x509_vpm"
-$ LIB_X509V3 = "v3_bcons,v3_bitst,v3_conf,v3_extku,v3_ia5,v3_lib,"+ -
- "v3_prn,v3_utl,v3err,v3_genn,v3_alt,v3_skey,v3_akey,v3_pku,"+ -
- "v3_int,v3_enum,v3_sxnet,v3_cpols,v3_crld,v3_purp,v3_info,"+ -
- "v3_ocsp,v3_akeya,v3_pmaps,v3_pcons,v3_ncons,v3_pcia,v3_pci,"+ -
- "pcy_cache,pcy_node,pcy_data,pcy_map,pcy_tree,pcy_lib,"+ -
- "v3_asid,v3_addr"
-$ LIB_CONF = "conf_err,conf_lib,conf_api,conf_def,conf_mod,conf_mall,conf_sap"
-$ LIB_TXT_DB = "txt_db"
-$ LIB_PKCS7 = "pk7_asn1,pk7_lib,pkcs7err,pk7_doit,pk7_smime,pk7_attr,"+ -
- "pk7_mime,bio_pk7"
-$ LIB_PKCS12 = "p12_add,p12_asn,p12_attr,p12_crpt,p12_crt,p12_decr,"+ -
- "p12_init,p12_key,p12_kiss,p12_mutl,"+ -
- "p12_utl,p12_npas,pk12err,p12_p8d,p12_p8e"
-$ LIB_COMP = "comp_lib,comp_err,"+ -
- "c_rle,c_zlib"
-$ LIB_OCSP = "ocsp_asn,ocsp_ext,ocsp_ht,ocsp_lib,ocsp_cl,"+ -
- "ocsp_srv,ocsp_prn,ocsp_vfy,ocsp_err"
-$ LIB_UI_COMPAT = ",ui_compat"
-$ LIB_UI = "ui_err,ui_lib,ui_openssl,ui_util"+LIB_UI_COMPAT
-$ LIB_KRB5 = "krb5_asn"
-$ LIB_STORE = "str_err,str_lib,str_meth,str_mem"
-$ LIB_CMS = "cms_lib,cms_asn1,cms_att,cms_io,cms_smime,cms_err,"+ -
- "cms_sd,cms_dd,cms_cd,cms_env,cms_enc,cms_ess"
-$ LIB_PQUEUE = "pqueue"
-$ LIB_TS = "ts_err,ts_req_utils,ts_req_print,ts_rsp_utils,ts_rsp_print,"+ -
- "ts_rsp_sign,ts_rsp_verify,ts_verify_ctx,ts_lib,ts_conf,"+ -
- "ts_asn1"
-$ LIB_JPAKE = "jpake,jpake_err"
-$!
-$! Setup exceptional compilations
-$!
-$ ! Add definitions for no threads on OpenVMS 7.1 and higher
-$ COMPILEWITH_CC3 = ",bss_rtcp,"
-$ ! Disable the DOLLARID warning
-$ COMPILEWITH_CC4 = ",a_utctm,bss_log,o_time,o_dir"
-$ ! Disable disjoint optimization
-$ COMPILEWITH_CC5 = ",md2_dgst,md4_dgst,md5_dgst,mdc2dgst," + -
- "seed,sha_dgst,sha1dgst,rmd_dgst,bf_enc,"
-$ ! Disable the MIXLINKAGE warning
-$ COMPILEWITH_CC6 = ",enc_read,set_key,"
-$!
-$! Figure Out What Other Modules We Are To Build.
-$!
-$ BUILD_SET:
-$!
-$! Define A Module Counter.
-$!
-$ MODULE_COUNTER = 0
-$!
-$! Top Of The Loop.
-$!
-$ MODULE_NEXT:
-$!
-$! Extract The Module Name From The Encryption List.
-$!
-$ MODULE_NAME = F$ELEMENT(MODULE_COUNTER,",",ENCRYPT_TYPES)
-$ IF MODULE_NAME.EQS."Basic" THEN MODULE_NAME = ""
-$ MODULE_NAME1 = MODULE_NAME
-$!
-$! Check To See If We Are At The End Of The Module List.
-$!
-$ IF (MODULE_NAME.EQS.",")
-$ THEN
-$!
-$! We Are At The End Of The Module List, Go To MODULE_DONE.
-$!
-$ GOTO MODULE_DONE
-$!
-$! End The Module List Check.
-$!
-$ ENDIF
-$!
-$! Increment The Moudle Counter.
-$!
-$ MODULE_COUNTER = MODULE_COUNTER + 1
-$!
-$! Create The Library and Apps Module Names.
-$!
-$ LIB_MODULE = "LIB_" + MODULE_NAME
-$ APPS_MODULE = "APPS_" + MODULE_NAME
-$ IF (F$EXTRACT(0,5,MODULE_NAME).EQS."ASN1_")
-$ THEN
-$ MODULE_NAME = "ASN1"
-$ ENDIF
-$ IF (F$EXTRACT(0,4,MODULE_NAME).EQS."EVP_")
-$ THEN
-$ MODULE_NAME = "EVP"
-$ ENDIF
-$!
-$! Set state (can be LIB and APPS)
-$!
-$ STATE = "LIB"
-$ IF BUILDALL .EQS. "APPS" THEN STATE = "APPS"
-$!
-$! Check if the library module name actually is defined
-$!
-$ IF F$TYPE('LIB_MODULE') .EQS. ""
-$ THEN
-$ WRITE SYS$ERROR ""
-$ WRITE SYS$ERROR "The module ",MODULE_NAME1," does not exist. Continuing..."
-$ WRITE SYS$ERROR ""
-$ GOTO MODULE_NEXT
-$ ENDIF
-$!
-$! Top Of The Module Loop.
-$!
-$ MODULE_AGAIN:
-$!
-$! Tell The User What Module We Are Building.
-$!
-$ IF (MODULE_NAME1.NES."")
-$ THEN
-$ IF STATE .EQS. "LIB"
-$ THEN
-$ WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Library Files. (",BUILDALL,",",STATE,")"
-$ ELSE IF F$TYPE('APPS_MODULE') .NES. ""
-$ THEN
-$ WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Applications. (",BUILDALL,",",STATE,")"
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$!
-$! Define A File Counter And Set It To "0".
-$!
-$ FILE_COUNTER = 0
-$ APPLICATION = ""
-$ APPLICATION_COUNTER = 0
-$!
-$! Top Of The File Loop.
-$!
-$ NEXT_FILE:
-$!
-$! Look in the LIB_MODULE is we're in state LIB
-$!
-$ IF STATE .EQS. "LIB"
-$ THEN
-$!
-$! O.K, Extract The File Name From The File List.
-$!
-$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",'LIB_MODULE')
-$!
-$! else
-$!
-$ ELSE
-$ FILE_NAME = ","
-$!
-$ IF F$TYPE('APPS_MODULE') .NES. ""
-$ THEN
-$!
-$! Extract The File Name From The File List.
-$! This part is a bit more complicated.
-$!
-$ IF APPLICATION .EQS. ""
-$ THEN
-$ APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE')
-$ APPLICATION_COUNTER = APPLICATION_COUNTER + 1
-$ APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION)
-$ APPLICATION = F$ELEMENT(0,"/",APPLICATION)
-$ FILE_COUNTER = 0
-$ ENDIF
-$
-$! WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*"
-$! SHOW SYMBOL APPLICATION*
-$!
-$ IF APPLICATION .NES. ";"
-$ THEN
-$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",APPLICATION_OBJECTS)
-$ IF FILE_NAME .EQS. ","
-$ THEN
-$ APPLICATION = ""
-$ GOTO NEXT_FILE
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$!
-$! Check To See If We Are At The End Of The File List.
-$!
-$ IF (FILE_NAME.EQS.",")
-$ THEN
-$!
-$! We Are At The End Of The File List, Change State Or Goto FILE_DONE.
-$!
-$ IF STATE .EQS. "LIB" .AND. BUILDALL .NES. "LIBRARY"
-$ THEN
-$ STATE = "APPS"
-$ GOTO MODULE_AGAIN
-$ ELSE
-$ GOTO FILE_DONE
-$ ENDIF
-$!
-$! End The File List Check.
-$!
-$ ENDIF
-$!
-$! Increment The Counter.
-$!
-$ FILE_COUNTER = FILE_COUNTER + 1
-$!
-$! Create The Source File Name.
-$!
-$ TMP_FILE_NAME = F$ELEMENT(1,"]",FILE_NAME)
-$ IF TMP_FILE_NAME .EQS. "]" THEN TMP_FILE_NAME = FILE_NAME
-$ IF F$ELEMENT(0,".",TMP_FILE_NAME) .EQS. TMP_FILE_NAME THEN -
- FILE_NAME = FILE_NAME + ".c"
-$ IF (MODULE_NAME.NES."")
-$ THEN
-$ SOURCE_FILE = "SYS$DISK:[." + MODULE_NAME+ "]" + FILE_NAME
-$ ELSE
-$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME
-$ ENDIF
-$ SOURCE_FILE = SOURCE_FILE - "]["
-$!
-$! Create The Object File Name.
-$!
-$ OBJECT_FILE = OBJ_DIR + F$PARSE(FILE_NAME,,,"NAME","SYNTAX_ONLY") + ".OBJ"
-$ ON WARNING THEN GOTO NEXT_FILE
-$!
-$! Check To See If The File We Want To Compile Is Actually There.
-$!
-$ IF (F$SEARCH(SOURCE_FILE).EQS."")
-$ THEN
-$!
-$! Tell The User That The File Doesn't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Doesn't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ GOTO EXIT
-$!
-$! End The File Exist Check.
-$!
-$ ENDIF
-$!
-$! Tell The User We Are Compiling The File.
-$!
-$ IF (MODULE_NAME.EQS."")
-$ THEN
-$ WRITE SYS$OUTPUT "Compiling The ",FILE_NAME," File. (",BUILDALL,",",STATE,")"
-$ ENDIF
-$ IF (MODULE_NAME.NES."")
-$ THEN
-$ WRITE SYS$OUTPUT " ",FILE_NAME,""
-$ ENDIF
-$!
-$! Compile The File.
-$!
-$ ON ERROR THEN GOTO NEXT_FILE
-$ FILE_NAME0 = F$ELEMENT(0,".",FILE_NAME)
-$ IF FILE_NAME - ".mar" .NES. FILE_NAME
-$ THEN
-$ MACRO/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ELSE
-$ IF COMPILEWITH_CC3 - FILE_NAME0 .NES. COMPILEWITH_CC3
-$ THEN
-$ CC3/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ELSE
-$ IF COMPILEWITH_CC4 - FILE_NAME0 .NES. COMPILEWITH_CC4
-$ THEN
-$ CC4/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ELSE
-$ IF COMPILEWITH_CC5 - FILE_NAME0 .NES. COMPILEWITH_CC5
-$ THEN
-$ CC5/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ELSE
-$ IF COMPILEWITH_CC6 - FILE_NAME0 .NES. COMPILEWITH_CC6
-$ THEN
-$ CC6/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ELSE
-$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$ IF STATE .EQS. "LIB"
-$ THEN
-$!
-$! Add It To The Library.
-$!
-$ LIBRARY/REPLACE 'LIB_NAME' 'OBJECT_FILE'
-$!
-$! Time To Clean Up The Object File.
-$!
-$ DELETE 'OBJECT_FILE';*
-$ ENDIF
-$!
-$! Go Back And Do It Again.
-$!
-$ GOTO NEXT_FILE
-$!
-$! All Done With This Library Part.
-$!
-$ FILE_DONE:
-$!
-$! Time To Build Some Applications
-$!
-$ IF F$TYPE('APPS_MODULE') .NES. "" .AND. BUILDALL .NES. "LIBRARY"
-$ THEN
-$ APPLICATION_COUNTER = 0
-$ NEXT_APPLICATION:
-$ APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE')
-$ IF APPLICATION .EQS. ";" THEN GOTO APPLICATION_DONE
-$
-$ APPLICATION_COUNTER = APPLICATION_COUNTER + 1
-$ APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION)
-$ APPLICATION = F$ELEMENT(0,"/",APPLICATION)
-$
-$! WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*"
-$! SHOW SYMBOL APPLICATION*
-$!
-$! Tell the user what happens
-$!
-$ WRITE SYS$OUTPUT " ",APPLICATION,".exe"
-$!
-$! Link The Program.
-$!
-$ ON ERROR THEN GOTO NEXT_APPLICATION
-$!
-$! Check To See If We Are To Link With A Specific TCP/IP Library.
-$!
-$ IF (TCPIP_LIB.NES."")
-$ THEN
-$!
-$! Link With A TCP/IP Library.
-$!
-$ LINK/'DEBUGGER'/'TRACEBACK'/EXE='EXE_DIR''APPLICATION'.EXE -
- 'OBJ_DIR''APPLICATION_OBJECTS', -
- 'CRYPTO_LIB'/LIBRARY, -
- 'TCPIP_LIB','OPT_FILE'/OPTION
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Don't Link With A TCP/IP Library.
-$!
-$ LINK/'DEBUGGER'/'TRACEBACK'/EXE='EXE_DIR''APPLICATION'.EXE -
- 'OBJ_DIR''APPLICATION_OBJECTS',-
- 'CRYPTO_LIB'/LIBRARY, -
- 'OPT_FILE'/OPTION
-$!
-$! End The TCP/IP Library Check.
-$!
-$ ENDIF
-$ GOTO NEXT_APPLICATION
-$ APPLICATION_DONE:
-$ ENDIF
-$!
-$! Go Back And Get The Next Module.
-$!
-$ GOTO MODULE_NEXT
-$!
-$! All Done With This Module.
-$!
-$ MODULE_DONE:
-$!
-$! Tell The User That We Are All Done.
-$!
-$ WRITE SYS$OUTPUT "All Done..."
-$ EXIT:
-$ GOSUB CLEANUP
-$ EXIT
-$!
-$! Check For The Link Option FIle.
-$!
-$ CHECK_OPT_FILE:
-$!
-$! Check To See If We Need To Make A VAX C Option File.
-$!
-$ IF (COMPILER.EQS."VAXC")
-$ THEN
-$!
-$! Check To See If We Already Have A VAX C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A VAX C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable VAX C Runtime Library.
-!
-SYS$SHARE:VAXCRTL.EXE/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The VAXC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A GNU C Option File.
-$!
-$ IF (COMPILER.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If We Already Have A GNU C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A GNU C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable C Runtime Library.
-!
-GNU_CC:[000000]GCCLIB/LIBRARY
-SYS$SHARE:VAXCRTL/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A DEC C Option File.
-$!
-$ IF (COMPILER.EQS."DECC")
-$ THEN
-$!
-$! Check To See If We Already Have A DEC C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! Figure Out If We Need A non-VAX Or A VAX Linker Option File.
-$!
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$!
-$! We Need A DEC C Linker Option File For VAX.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable DEC C Runtime Library.
-!
-SYS$SHARE:DECC$SHR.EXE/SHARE
-$EOD
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Create The non-VAX Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File For non-VAX To Link Agianst
-! The Sharable C Runtime Library.
-!
-SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
-SYS$SHARE:CMA$OPEN_RTL/SHARE
-$EOD
-$!
-$! End The DEC C Option File Check.
-$!
-$ ENDIF
-$!
-$! End The Option File Search.
-$!
-$ ENDIF
-$!
-$! End The DEC C Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What Linker Option File We Are Using.
-$!
-$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
-$!
-$! Time To RETURN.
-$!
-$ RETURN
-$!
-$! Check The User's Options.
-$!
-$ CHECK_OPTIONS:
-$!
-$! Check To See If P1 Is Blank.
-$!
-$ IF (P1.EQS."ALL")
-$ THEN
-$!
-$! P1 Is Blank, So Build Everything.
-$!
-$ BUILDALL = "TRUE"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Else, Check To See If P1 Has A Valid Argument.
-$!
-$ IF (P1.EQS."LIBRARY").OR.(P1.EQS."APPS")
-$ THEN
-$!
-$! A Valid Argument.
-$!
-$ BUILDALL = P1
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALL : Just Build Everything."
-$ WRITE SYS$OUTPUT " LIBRARY : To Compile Just The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
-$ WRITE SYS$OUTPUT " APPS : To Compile Just The [.xxx.EXE.CRYPTO]*.EXE Programs."
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALPHA : Alpha Architecture."
-$ WRITE SYS$OUTPUT " IA64 : IA64 Architecture."
-$ WRITE SYS$OUTPUT " VAX : VAX Architecture."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P1 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P2 Is Blank.
-$!
-$ IF (P2.EQS."NODEBUG")
-$ THEN
-$!
-$! P2 Is NODEBUG, So Compile Without The Debugger Information.
-$!
-$ DEBUGGER = "NODEBUG"
-$ TRACEBACK = "NOTRACEBACK"
-$ GCC_OPTIMIZE = "OPTIMIZE"
-$ CC_OPTIMIZE = "OPTIMIZE"
-$ MACRO_OPTIMIZE = "OPTIMIZE"
-$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
-$ ELSE
-$!
-$! Check To See If We Are To Compile With Debugger Information.
-$!
-$ IF (P2.EQS."DEBUG")
-$ THEN
-$!
-$! Compile With Debugger Information.
-$!
-$ DEBUGGER = "DEBUG"
-$ TRACEBACK = "TRACEBACK"
-$ GCC_OPTIMIZE = "NOOPTIMIZE"
-$ CC_OPTIMIZE = "NOOPTIMIZE"
-$ MACRO_OPTIMIZE = "NOOPTIMIZE"
-$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
-$ ELSE
-$!
-$! They Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
-$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P2 Check.
-$!
-$ ENDIF
-$!
-$! Special Threads For OpenVMS v7.1 Or Later
-$!
-$! Written By: Richard Levitte
-$! richard@levitte.org
-$!
-$!
-$! Check To See If We Have A Option For P5.
-$!
-$ IF (P5.EQS."")
-$ THEN
-$!
-$! Get The Version Of VMS We Are Using.
-$!
-$ ISSEVEN :=
-$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
-$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
-$!
-$! Check To See If The VMS Version Is v7.1 Or Later.
-$!
-$ IF (TMP.GE.71)
-$ THEN
-$!
-$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
-$!
-$ ISSEVEN := ,PTHREAD_USE_D4
-$!
-$! End The VMS Version Check.
-$!
-$ ENDIF
-$!
-$! End The P5 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P7 Is Blank.
-$!
-$ IF (P7.EQS."")
-$ THEN
-$ POINTER_SIZE = ""
-$ ELSE
-$!
-$! Check is P7 Is Valid
-$!
-$ IF (P7.EQS."32")
-$ THEN
-$ POINTER_SIZE = "/POINTER_SIZE=32"
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ LIB32 = ""
-$ ELSE
-$ LIB32 = "32"
-$ ENDIF
-$ ELSE
-$ IF (P7.EQS."64")
-$ THEN
-$ LIB32 = ""
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ POINTER_SIZE = "/POINTER_SIZE=32"
-$ ELSE
-$ POINTER_SIZE = "/POINTER_SIZE=64"
-$ ENDIF
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P7," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " 32 : Compile with 32 bit pointer size"
-$ WRITE SYS$OUTPUT " 64 : Compile with 64 bit pointer size"
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ GOTO TIDY
-$!
-$! End The Valid Arguement Check.
-$!
-$ ENDIF
-$ ENDIF
-$!
-$! End The P7 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P3 Is Blank.
-$!
-$ IF (P3.EQS."")
-$ THEN
-$!
-$! O.K., The User Didn't Specify A Compiler, Let's Try To
-$! Find Out Which One To Use.
-$!
-$! Check To See If We Have GNU C.
-$!
-$ IF (F$TRNLNM("GNU_CC").NES."")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ P3 = "GNUC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Check To See If We Have VAXC Or DECC.
-$!
-$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ P3 = "DECC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ P3 = "VAXC"
-$!
-$! End The VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The DECC & VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The Compiler Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Have A Option For P4.
-$!
-$ IF (P4.EQS."")
-$ THEN
-$!
-$! Find out what socket library we have available
-$!
-$ IF F$PARSE("SOCKETSHR:") .NES. ""
-$ THEN
-$!
-$! We have SOCKETSHR, and it is my opinion that it's the best to use.
-$!
-$ P4 = "SOCKETSHR"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
-$!
-$! Else, let's look for something else
-$!
-$ ELSE
-$!
-$! Like UCX (the reason to do this before Multinet is that the UCX
-$! emulation is easier to use...)
-$!
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
- .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
- .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
-$ THEN
-$!
-$! Last resort: a UCX or UCX-compatible library
-$!
-$ P4 = "UCX"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
-$!
-$! That was all...
-$!
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$!
-$! Set Up Initial CC Definitions, Possibly With User Ones
-$!
-$ CCDEFS = "TCPIP_TYPE_''P4',DSO_VMS"
-$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
-$ CCEXTRAFLAGS = ""
-$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
-$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
-$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
- CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
-$!
-$! Check To See If The User Entered A Valid Paramter.
-$!
-$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If The User Wanted DECC.
-$!
-$ IF (P3.EQS."DECC")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ COMPILER = "DECC"
-$!
-$! Tell The User We Are Using DECC.
-$!
-$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
-$!
-$! Use DECC...
-$!
-$ CC = "CC"
-$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
- THEN CC = "CC/DECC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89''POINTER_SIZE'" + -
- "/NOLIST/PREFIX=ALL" + -
- "/INCLUDE=(SYS$DISK:[._''ARCH'],SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.EVP],SYS$DISK:[.ASN1])" + -
- CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
-$!
-$! End DECC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use VAXC.
-$!
-$ IF (P3.EQS."VAXC")
-$ THEN
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ COMPILER = "VAXC"
-$!
-$! Tell The User We Are Using VAX C.
-$!
-$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
-$!
-$! Compile Using VAXC.
-$!
-$ CC = "CC"
-$ IF ARCH.NES."VAX"
-$ THEN
-$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
-$ EXIT
-$ ENDIF
-$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=(SYS$DISK:[._''ARCH'],SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.EVP],SYS$DISK:[.ASN1])" + -
- CCEXTRAFLAGS
-$ CCDEFS = """VAXC""," + CCDEFS
-$!
-$! Define <sys> As SYS$COMMON:[SYSLIB]
-$!
-$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
-$!
-$! End VAXC Check
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use GNU C.
-$!
-$ IF (P3.EQS."GNUC")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ COMPILER = "GNUC"
-$!
-$! Tell The User We Are Using GNUC.
-$!
-$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
-$!
-$! Use GNU C...
-$!
-$ CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=(SYS$DISK:[._''ARCH'],SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.EVP],SYS$DISK:[.ASN1])" + -
- CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Set up default defines
-$!
-$ CCDEFS = """FLAT_INC=1""," + CCDEFS
-$!
-$! Finish up the definition of CC.
-$!
-$ IF COMPILER .EQS. "DECC"
-$ THEN
-$ IF CCDISABLEWARNINGS .EQS. ""
-$ THEN
-$ CC4DISABLEWARNINGS = "DOLLARID"
-$ CC6DISABLEWARNINGS = "MIXLINKAGE"
-$ ELSE
-$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
-$ CC6DISABLEWARNINGS = CCDISABLEWARNINGS + ",MIXLINKAGE"
-$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
-$ ENDIF
-$ CC4DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
-$ CC6DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC6DISABLEWARNINGS + "))"
-$ ELSE
-$ CCDISABLEWARNINGS = ""
-$ CC4DISABLEWARNINGS = ""
-$ CC6DISABLEWARNINGS = ""
-$ ENDIF
-$ CC3 = CC + "/DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS
-$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
-$ IF ARCH .EQS. "VAX" .AND. COMPILER .EQS. "DECC" .AND. P2 .NES. "DEBUG"
-$ THEN
-$ CC5 = CC + "/OPTIMIZE=NODISJOINT"
-$ ELSE
-$ CC5 = CC + "/NOOPTIMIZE"
-$ ENDIF
-$ CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
-$ CC6 = CC - CCDISABLEWARNINGS + CC6DISABLEWARNINGS
-$!
-$! Show user the result
-$!
-$ WRITE/SYMBOL SYS$OUTPUT "Main C Compiling Command: ",CC
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
-$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
-$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! Build a MACRO command for the architecture at hand
-$!
-$ IF ARCH .EQS. "VAX" THEN MACRO = "MACRO/''DEBUGGER'"
-$ IF ARCH .NES. "VAX" THEN MACRO = "MACRO/MIGRATION/''DEBUGGER'/''MACRO_OPTIMIZE'"
-$!
-$! Show user the result
-$!
-$ WRITE/SYMBOL SYS$OUTPUT "Main MACRO Compiling Command: ",MACRO
-$!
-$! Time to check the contents, and to make sure we get the correct library.
-$!
-$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" -
- .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE"
-$ THEN
-$!
-$! Check to see if SOCKETSHR was chosen
-$!
-$ IF P4.EQS."SOCKETSHR"
-$ THEN
-$!
-$! Set the library to use SOCKETSHR
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT"
-$!
-$! Done with SOCKETSHR
-$!
-$ ENDIF
-$!
-$! Check to see if MULTINET was chosen
-$!
-$ IF P4.EQS."MULTINET"
-$ THEN
-$!
-$! Set the library to use UCX emulation.
-$!
-$ P4 = "UCX"
-$!
-$! Done with MULTINET
-$!
-$ ENDIF
-$!
-$! Check to see if UCX was chosen
-$!
-$ IF P4.EQS."UCX"
-$ THEN
-$!
-$! Set the library to use UCX.
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT"
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
-$ THEN
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT/OPT"
-$ ELSE
-$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
- TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT/OPT"
-$ ENDIF
-$!
-$! Done with UCX
-$!
-$ ENDIF
-$!
-$! Check to see if TCPIP was chosen
-$!
-$ IF P4.EQS."TCPIP"
-$ THEN
-$!
-$! Set the library to use TCPIP (post UCX).
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT"
-$!
-$! Done with TCPIP
-$!
-$ ENDIF
-$!
-$! Check to see if NONE was chosen
-$!
-$ IF P4.EQS."NONE"
-$ THEN
-$!
-$! Do not use a TCPIP library.
-$!
-$ TCPIP_LIB = ""
-$!
-$! Done with TCPIP
-$!
-$ ENDIF
-$!
-$! Print info
-$!
-$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P4," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
-$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
-$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! Done with TCP/IP libraries
-$!
-$ ENDIF
-$!
-$! Check if the user wanted to compile just a subset of all the encryption
-$! methods.
-$!
-$ IF P6 .NES. ""
-$ THEN
-$ ENCRYPT_TYPES = P6
-$ ENDIF
-$!
-$! Time To RETURN...
-$!
-$ RETURN
-$!
-$ INITIALISE:
-$!
-$! Save old value of the logical name OPENSSL
-$!
-$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
-$!
-$! Save directory information
-$!
-$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
-$ __HERE = F$EDIT(__HERE,"UPCASE")
-$ __TOP = __HERE - "CRYPTO]"
-$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
-$!
-$! Set up the logical name OPENSSL to point at the include directory
-$!
-$ DEFINE OPENSSL/NOLOG '__INCLUDE'
-$!
-$! Done
-$!
-$ RETURN
-$!
-$ CLEANUP:
-$!
-$! Restore the logical name OPENSSL if it had a value
-$!
-$ IF __SAVE_OPENSSL .EQS. ""
-$ THEN
-$ DEASSIGN OPENSSL
-$ ELSE
-$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
-$ ENDIF
-$!
-$! Done
-$!
-$ RETURN
+$!
+$! CRYPTO-LIB.COM
+$! Written By: Robert Byer
+$! Vice-President
+$! A-Com Computing, Inc.
+$! byer@mail.all-net.net
+$!
+$! Changes by Richard Levitte <richard@levitte.org>
+$! Zoltan Arpadffy <arpadffy@polarhome.com>
+$!
+$! This command files compiles and creates the "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB"
+$! library for OpenSSL. The "xxx" denotes the machine architecture, ALPHA,
+$! IA64 or VAX.
+$!
+$! It was re-written so it would try to determine what "C" compiler to use
+$! or you can specify which "C" compiler to use.
+$!
+$! Specify the following as P1 to build just that part or ALL to just
+$! build everything.
+$!
+$! LIBRARY To just compile the [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
+$! APPS To just compile the [.xxx.EXE.CRYPTO]*.EXE
+$! ALL To do both LIBRARY and APPS
+$!
+$! Specify DEBUG or NODEBUG as P2 to compile with or without debugger
+$! information.
+$!
+$! Specify which compiler at P3 to try to compile under.
+$!
+$! VAXC For VAX C.
+$! DECC For DEC C.
+$! GNUC For GNU C.
+$!
+$! If you don't specify a compiler, it will try to determine which
+$! "C" compiler to use.
+$!
+$! P4, if defined, sets a TCP/IP library to use, through one of the following
+$! keywords:
+$!
+$! UCX For UCX
+$! TCPIP For TCPIP (post UCX)
+$! SOCKETSHR For SOCKETSHR+NETLIB
+$!
+$! P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$! P6, if defined, sets a choice of crypto methods to compile.
+$! WARNING: this should only be done to recompile some part of an already
+$! fully compiled library.
+$!
+$! For 64 bit architectures (Alpha and IA64), specify the pointer size as P7.
+$! For 32 bit architectures (VAX), P7 is ignored.
+$! Currently supported values are:
+$!
+$! 32 To ge a library compiled with /POINTER_SIZE=32
+$! 64 To ge a library compiled with /POINTER_SIZE=64
+$!
+$!
+$! Define A TCP/IP Library That We Will Need To Link To.
+$! (That Is, If We Need To Link To One.)
+$!
+$ TCPIP_LIB = ""
+$!
+$! Check Which Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$! The Architecture Is VAX
+$!
+$ ARCH = "VAX"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$! Define The Different Encryption Types.
+$! NOTE: Some might think this list ugly. However, it's made this way to
+$! reflect the SDIRS variable in [-]Makefile.org as closely as possible,
+$! thereby making it fairly easy to verify that the lists are the same.
+$!
+$ ET_WHIRLPOOL = "WHRLPOOL"
+$ IF ARCH .EQS. "VAX" THEN ET_WHIRLPOOL = ""
+$ ENCRYPT_TYPES = "Basic,"+ -
+ "OBJECTS,"+ -
+ "MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,"+ET_WHIRLPOOL+","+ -
+ "DES,AES,RC2,RC4,RC5,IDEA,BF,CAST,CAMELLIA,SEED,MODES,"+ -
+ "BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,"+ -
+ "BUFFER,BIO,STACK,LHASH,RAND,ERR,"+ -
+ "EVP,EVP_2,EVP_3,ASN1,ASN1_2,PEM,X509,X509V3,"+ -
+ "CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,UI,KRB5,"+ -
+ "STORE,CMS,PQUEUE,TS,JPAKE"
+$! Define The OBJ Directory.
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.CRYPTO]
+$!
+$! Define The EXE Directory.
+$!
+$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.CRYPTO]
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Initialise logical names and such
+$!
+$ GOSUB INITIALISE
+$!
+$! Tell The User What Kind of Machine We Run On.
+$!
+$ WRITE SYS$OUTPUT "Compiling On A ",ARCH," Machine."
+$!
+$!
+$! Check To See If The Architecture Specific OBJ Directory Exists.
+$!
+$ IF (F$PARSE(OBJ_DIR).EQS."")
+$ THEN
+$!
+$! It Dosen't Exist, So Create It.
+$!
+$ CREATE/DIR 'OBJ_DIR'
+$!
+$! End The Architecture Specific OBJ Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If The Architecture Specific Directory Exists.
+$!
+$ IF (F$PARSE(EXE_DIR).EQS."")
+$ THEN
+$!
+$! It Dosen't Exist, So Create It.
+$!
+$ CREATE/DIRECTORY 'EXE_DIR'
+$!
+$! End The Architecture Specific Directory Check.
+$!
+$ ENDIF
+$!
+$! Define The Library Name.
+$!
+$ LIB_NAME := 'EXE_DIR'LIBCRYPTO'LIB32'.OLB
+$!
+$! Define The CRYPTO-LIB We Are To Use.
+$!
+$ CRYPTO_LIB := 'EXE_DIR'LIBCRYPTO'LIB32'.OLB
+$!
+$! Check To See If We Already Have A "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" Library...
+$!
+$ IF (F$SEARCH(LIB_NAME).EQS."")
+$ THEN
+$!
+$! Guess Not, Create The Library.
+$!
+$ LIBRARY/CREATE/OBJECT 'LIB_NAME'
+$!
+$! End The Library Check.
+$!
+$ ENDIF
+$!
+$! Build our options file for the application
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Define The Different Encryption "library" Strings.
+$!
+$ APPS_DES = "DES/DES,CBC3_ENC"
+$ APPS_PKCS7 = "ENC/ENC;DEC/DEC;SIGN/SIGN;VERIFY/VERIFY,EXAMPLE"
+$
+$ LIB_ = "cryptlib,mem,mem_clr,mem_dbg,cversion,ex_data,cpt_err,ebcdic,uid,o_time,o_str,o_dir"
+$ LIB_MD2 = "md2_dgst,md2_one"
+$ LIB_MD4 = "md4_dgst,md4_one"
+$ LIB_MD5 = "md5_dgst,md5_one"
+$ LIB_SHA = "sha_dgst,sha1dgst,sha_one,sha1_one,sha256,sha512"
+$ LIB_MDC2 = "mdc2dgst,mdc2_one"
+$ LIB_HMAC = "hmac,hm_ameth,hm_pmeth"
+$ LIB_RIPEMD = "rmd_dgst,rmd_one"
+$ LIB_WHRLPOOL = "wp_dgst,wp_block"
+$ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ -
+ "ecb3_enc,cfb64enc,cfb64ede,cfb_enc,ofb64ede,"+ -
+ "enc_read,enc_writ,ofb64enc,"+ -
+ "ofb_enc,str2key,pcbc_enc,qud_cksm,rand_key,"+ -
+ "des_enc,fcrypt_b,"+ -
+ "fcrypt,xcbc_enc,rpc_enc,cbc_cksm,"+ -
+ "ede_cbcm_enc,des_old,des_old2,read2pwd"
+$ LIB_RC2 = "rc2_ecb,rc2_skey,rc2_cbc,rc2cfb64,rc2ofb64"
+$ LIB_RC4 = "rc4_skey,rc4_enc"
+$ LIB_RC5 = "rc5_skey,rc5_ecb,rc5_enc,rc5cfb64,rc5ofb64"
+$ LIB_IDEA = "i_cbc,i_cfb64,i_ofb64,i_ecb,i_skey"
+$ LIB_BF = "bf_skey,bf_ecb,bf_enc,bf_cfb64,bf_ofb64"
+$ LIB_CAST = "c_skey,c_ecb,c_enc,c_cfb64,c_ofb64"
+$ LIB_CAMELLIA = "camellia,cmll_misc,cmll_ecb,cmll_cbc,cmll_ofb,"+ -
+ "cmll_cfb,cmll_ctr"
+$ LIB_SEED = "seed,seed_ecb,seed_cbc,seed_cfb,seed_ofb"
+$ LIB_MODES = "cbc128,ctr128,cfb128,ofb128,cts128"
+$ LIB_BN_ASM = "[.asm]vms.mar,vms-helper"
+$ IF F$TRNLNM("OPENSSL_NO_ASM") .OR. ARCH .NES. "VAX" THEN -
+ LIB_BN_ASM = "bn_asm"
+$ LIB_BN = "bn_add,bn_div,bn_exp,bn_lib,bn_ctx,bn_mul,bn_mod,"+ -
+ "bn_print,bn_rand,bn_shift,bn_word,bn_blind,"+ -
+ "bn_kron,bn_sqrt,bn_gcd,bn_prime,bn_err,bn_sqr,"+LIB_BN_ASM+","+ -
+ "bn_recp,bn_mont,bn_mpi,bn_exp2,bn_gf2m,bn_nist,"+ -
+ "bn_depr,bn_const"
+$ LIB_EC = "ec_lib,ecp_smpl,ecp_mont,ecp_nist,ec_cvt,ec_mult,"+ -
+ "ec_err,ec_curve,ec_check,ec_print,ec_asn1,ec_key,"+ -
+ "ec2_smpl,ec2_mult,ec_ameth,ec_pmeth,eck_prn"
+$ LIB_RSA = "rsa_eay,rsa_gen,rsa_lib,rsa_sign,rsa_saos,rsa_err,"+ -
+ "rsa_pk1,rsa_ssl,rsa_none,rsa_oaep,rsa_chk,rsa_null,"+ -
+ "rsa_pss,rsa_x931,rsa_asn1,rsa_depr,rsa_ameth,rsa_prn,"+ -
+ "rsa_pmeth"
+$ LIB_DSA = "dsa_gen,dsa_key,dsa_lib,dsa_asn1,dsa_vrf,dsa_sign,"+ -
+ "dsa_err,dsa_ossl,dsa_depr,dsa_ameth,dsa_pmeth,dsa_prn"
+$ LIB_ECDSA = "ecs_lib,ecs_asn1,ecs_ossl,ecs_sign,ecs_vrf,ecs_err"
+$ LIB_DH = "dh_asn1,dh_gen,dh_key,dh_lib,dh_check,dh_err,dh_depr,"+ -
+ "dh_ameth,dh_pmeth,dh_prn"
+$ LIB_ECDH = "ech_lib,ech_ossl,ech_key,ech_err"
+$ LIB_DSO = "dso_dl,dso_dlfcn,dso_err,dso_lib,dso_null,"+ -
+ "dso_openssl,dso_win32,dso_vms,dso_beos"
+$ LIB_ENGINE = "eng_err,eng_lib,eng_list,eng_init,eng_ctrl,"+ -
+ "eng_table,eng_pkey,eng_fat,eng_all,"+ -
+ "tb_rsa,tb_dsa,tb_ecdsa,tb_dh,tb_ecdh,tb_rand,tb_store,"+ -
+ "tb_cipher,tb_digest,tb_pkmeth,tb_asnmth,"+ -
+ "eng_openssl,eng_dyn,eng_cnf,eng_cryptodev"
+$ LIB_AES = "aes_core,aes_misc,aes_ecb,aes_cbc,aes_cfb,aes_ofb,aes_ctr,"+ -
+ "aes_ige,aes_wrap"
+$ LIB_BUFFER = "buffer,buf_err"
+$ LIB_BIO = "bio_lib,bio_cb,bio_err,"+ -
+ "bss_mem,bss_null,bss_fd,"+ -
+ "bss_file,bss_sock,bss_conn,"+ -
+ "bf_null,bf_buff,b_print,b_dump,"+ -
+ "b_sock,bss_acpt,bf_nbio,bss_rtcp,bss_bio,bss_log,"+ -
+ "bss_dgram,"+ -
+ "bf_lbuf"
+$ LIB_STACK = "stack"
+$ LIB_LHASH = "lhash,lh_stats"
+$ LIB_RAND = "md_rand,randfile,rand_lib,rand_err,rand_egd,"+ -
+ "rand_vms"
+$ LIB_ERR = "err,err_all,err_prn"
+$ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err,obj_xref"
+$ LIB_EVP = "encode,digest,evp_enc,evp_key,evp_acnf,"+ -
+ "e_des,e_bf,e_idea,e_des3,e_camellia,"+ -
+ "e_rc4,e_aes,names,e_seed,"+ -
+ "e_xcbc_d,e_rc2,e_cast,e_rc5"
+$ LIB_EVP_2 = "m_null,m_md2,m_md4,m_md5,m_sha,m_sha1,m_wp," + -
+ "m_dss,m_dss1,m_mdc2,m_ripemd,m_ecdsa,"+ -
+ "p_open,p_seal,p_sign,p_verify,p_lib,p_enc,p_dec,"+ -
+ "bio_md,bio_b64,bio_enc,evp_err,e_null,"+ -
+ "c_all,c_allc,c_alld,evp_lib,bio_ok,"+-
+ "evp_pkey,evp_pbe,p5_crpt,p5_crpt2"
+$ LIB_EVP_3 = "e_old,pmeth_lib,pmeth_fn,pmeth_gn,m_sigver"
+$ LIB_ASN1 = "a_object,a_bitstr,a_utctm,a_gentm,a_time,a_int,a_octet,"+ -
+ "a_print,a_type,a_set,a_dup,a_d2i_fp,a_i2d_fp,"+ -
+ "a_enum,a_utf8,a_sign,a_digest,a_verify,a_mbstr,a_strex,"+ -
+ "x_algor,x_val,x_pubkey,x_sig,x_req,x_attrib,x_bignum,"+ -
+ "x_long,x_name,x_x509,x_x509a,x_crl,x_info,x_spki,nsseq,"+ -
+ "x_nx509,d2i_pu,d2i_pr,i2d_pu,i2d_pr"
+$ LIB_ASN1_2 = "t_req,t_x509,t_x509a,t_crl,t_pkey,t_spki,t_bitst,"+ -
+ "tasn_new,tasn_fre,tasn_enc,tasn_dec,tasn_utl,tasn_typ,"+ -
+ "tasn_prn,ameth_lib,"+ -
+ "f_int,f_string,n_pkey,"+ -
+ "f_enum,x_pkey,a_bool,x_exten,bio_asn1,bio_ndef,asn_mime,"+ -
+ "asn1_gen,asn1_par,asn1_lib,asn1_err,a_bytes,a_strnid,"+ -
+ "evp_asn1,asn_pack,p5_pbe,p5_pbev2,p8_pkey,asn_moid"
+$ LIB_PEM = "pem_sign,pem_seal,pem_info,pem_lib,pem_all,pem_err,"+ -
+ "pem_x509,pem_xaux,pem_oth,pem_pk8,pem_pkey,pvkfmt"
+$ LIB_X509 = "x509_def,x509_d2,x509_r2x,x509_cmp,"+ -
+ "x509_obj,x509_req,x509spki,x509_vfy,"+ -
+ "x509_set,x509cset,x509rset,x509_err,"+ -
+ "x509name,x509_v3,x509_ext,x509_att,"+ -
+ "x509type,x509_lu,x_all,x509_txt,"+ -
+ "x509_trs,by_file,by_dir,x509_vpm"
+$ LIB_X509V3 = "v3_bcons,v3_bitst,v3_conf,v3_extku,v3_ia5,v3_lib,"+ -
+ "v3_prn,v3_utl,v3err,v3_genn,v3_alt,v3_skey,v3_akey,v3_pku,"+ -
+ "v3_int,v3_enum,v3_sxnet,v3_cpols,v3_crld,v3_purp,v3_info,"+ -
+ "v3_ocsp,v3_akeya,v3_pmaps,v3_pcons,v3_ncons,v3_pcia,v3_pci,"+ -
+ "pcy_cache,pcy_node,pcy_data,pcy_map,pcy_tree,pcy_lib,"+ -
+ "v3_asid,v3_addr"
+$ LIB_CONF = "conf_err,conf_lib,conf_api,conf_def,conf_mod,conf_mall,conf_sap"
+$ LIB_TXT_DB = "txt_db"
+$ LIB_PKCS7 = "pk7_asn1,pk7_lib,pkcs7err,pk7_doit,pk7_smime,pk7_attr,"+ -
+ "pk7_mime,bio_pk7"
+$ LIB_PKCS12 = "p12_add,p12_asn,p12_attr,p12_crpt,p12_crt,p12_decr,"+ -
+ "p12_init,p12_key,p12_kiss,p12_mutl,"+ -
+ "p12_utl,p12_npas,pk12err,p12_p8d,p12_p8e"
+$ LIB_COMP = "comp_lib,comp_err,"+ -
+ "c_rle,c_zlib"
+$ LIB_OCSP = "ocsp_asn,ocsp_ext,ocsp_ht,ocsp_lib,ocsp_cl,"+ -
+ "ocsp_srv,ocsp_prn,ocsp_vfy,ocsp_err"
+$ LIB_UI_COMPAT = ",ui_compat"
+$ LIB_UI = "ui_err,ui_lib,ui_openssl,ui_util"+LIB_UI_COMPAT
+$ LIB_KRB5 = "krb5_asn"
+$ LIB_STORE = "str_err,str_lib,str_meth,str_mem"
+$ LIB_CMS = "cms_lib,cms_asn1,cms_att,cms_io,cms_smime,cms_err,"+ -
+ "cms_sd,cms_dd,cms_cd,cms_env,cms_enc,cms_ess"
+$ LIB_PQUEUE = "pqueue"
+$ LIB_TS = "ts_err,ts_req_utils,ts_req_print,ts_rsp_utils,ts_rsp_print,"+ -
+ "ts_rsp_sign,ts_rsp_verify,ts_verify_ctx,ts_lib,ts_conf,"+ -
+ "ts_asn1"
+$ LIB_JPAKE = "jpake,jpake_err"
+$!
+$! Setup exceptional compilations
+$!
+$ ! Add definitions for no threads on OpenVMS 7.1 and higher
+$ COMPILEWITH_CC3 = ",bss_rtcp,"
+$ ! Disable the DOLLARID warning
+$ COMPILEWITH_CC4 = ",a_utctm,bss_log,o_time,o_dir"
+$ ! Disable disjoint optimization
+$ COMPILEWITH_CC5 = ",md2_dgst,md4_dgst,md5_dgst,mdc2dgst," + -
+ "seed,sha_dgst,sha1dgst,rmd_dgst,bf_enc,"
+$ ! Disable the MIXLINKAGE warning
+$ COMPILEWITH_CC6 = ",enc_read,set_key,"
+$!
+$! Figure Out What Other Modules We Are To Build.
+$!
+$ BUILD_SET:
+$!
+$! Define A Module Counter.
+$!
+$ MODULE_COUNTER = 0
+$!
+$! Top Of The Loop.
+$!
+$ MODULE_NEXT:
+$!
+$! Extract The Module Name From The Encryption List.
+$!
+$ MODULE_NAME = F$ELEMENT(MODULE_COUNTER,",",ENCRYPT_TYPES)
+$ IF MODULE_NAME.EQS."Basic" THEN MODULE_NAME = ""
+$ MODULE_NAME1 = MODULE_NAME
+$!
+$! Check To See If We Are At The End Of The Module List.
+$!
+$ IF (MODULE_NAME.EQS.",")
+$ THEN
+$!
+$! We Are At The End Of The Module List, Go To MODULE_DONE.
+$!
+$ GOTO MODULE_DONE
+$!
+$! End The Module List Check.
+$!
+$ ENDIF
+$!
+$! Increment The Moudle Counter.
+$!
+$ MODULE_COUNTER = MODULE_COUNTER + 1
+$!
+$! Create The Library and Apps Module Names.
+$!
+$ LIB_MODULE = "LIB_" + MODULE_NAME
+$ APPS_MODULE = "APPS_" + MODULE_NAME
+$ IF (F$EXTRACT(0,5,MODULE_NAME).EQS."ASN1_")
+$ THEN
+$ MODULE_NAME = "ASN1"
+$ ENDIF
+$ IF (F$EXTRACT(0,4,MODULE_NAME).EQS."EVP_")
+$ THEN
+$ MODULE_NAME = "EVP"
+$ ENDIF
+$!
+$! Set state (can be LIB and APPS)
+$!
+$ STATE = "LIB"
+$ IF BUILDALL .EQS. "APPS" THEN STATE = "APPS"
+$!
+$! Check if the library module name actually is defined
+$!
+$ IF F$TYPE('LIB_MODULE') .EQS. ""
+$ THEN
+$ WRITE SYS$ERROR ""
+$ WRITE SYS$ERROR "The module ",MODULE_NAME1," does not exist. Continuing..."
+$ WRITE SYS$ERROR ""
+$ GOTO MODULE_NEXT
+$ ENDIF
+$!
+$! Top Of The Module Loop.
+$!
+$ MODULE_AGAIN:
+$!
+$! Tell The User What Module We Are Building.
+$!
+$ IF (MODULE_NAME1.NES."")
+$ THEN
+$ IF STATE .EQS. "LIB"
+$ THEN
+$ WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Library Files. (",BUILDALL,",",STATE,")"
+$ ELSE IF F$TYPE('APPS_MODULE') .NES. ""
+$ THEN
+$ WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Applications. (",BUILDALL,",",STATE,")"
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$!
+$! Define A File Counter And Set It To "0".
+$!
+$ FILE_COUNTER = 0
+$ APPLICATION = ""
+$ APPLICATION_COUNTER = 0
+$!
+$! Top Of The File Loop.
+$!
+$ NEXT_FILE:
+$!
+$! Look in the LIB_MODULE is we're in state LIB
+$!
+$ IF STATE .EQS. "LIB"
+$ THEN
+$!
+$! O.K, Extract The File Name From The File List.
+$!
+$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",'LIB_MODULE')
+$!
+$! else
+$!
+$ ELSE
+$ FILE_NAME = ","
+$!
+$ IF F$TYPE('APPS_MODULE') .NES. ""
+$ THEN
+$!
+$! Extract The File Name From The File List.
+$! This part is a bit more complicated.
+$!
+$ IF APPLICATION .EQS. ""
+$ THEN
+$ APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE')
+$ APPLICATION_COUNTER = APPLICATION_COUNTER + 1
+$ APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION)
+$ APPLICATION = F$ELEMENT(0,"/",APPLICATION)
+$ FILE_COUNTER = 0
+$ ENDIF
+$
+$! WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*"
+$! SHOW SYMBOL APPLICATION*
+$!
+$ IF APPLICATION .NES. ";"
+$ THEN
+$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",APPLICATION_OBJECTS)
+$ IF FILE_NAME .EQS. ","
+$ THEN
+$ APPLICATION = ""
+$ GOTO NEXT_FILE
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$!
+$! Check To See If We Are At The End Of The File List.
+$!
+$ IF (FILE_NAME.EQS.",")
+$ THEN
+$!
+$! We Are At The End Of The File List, Change State Or Goto FILE_DONE.
+$!
+$ IF STATE .EQS. "LIB" .AND. BUILDALL .NES. "LIBRARY"
+$ THEN
+$ STATE = "APPS"
+$ GOTO MODULE_AGAIN
+$ ELSE
+$ GOTO FILE_DONE
+$ ENDIF
+$!
+$! End The File List Check.
+$!
+$ ENDIF
+$!
+$! Increment The Counter.
+$!
+$ FILE_COUNTER = FILE_COUNTER + 1
+$!
+$! Create The Source File Name.
+$!
+$ TMP_FILE_NAME = F$ELEMENT(1,"]",FILE_NAME)
+$ IF TMP_FILE_NAME .EQS. "]" THEN TMP_FILE_NAME = FILE_NAME
+$ IF F$ELEMENT(0,".",TMP_FILE_NAME) .EQS. TMP_FILE_NAME THEN -
+ FILE_NAME = FILE_NAME + ".c"
+$ IF (MODULE_NAME.NES."")
+$ THEN
+$ SOURCE_FILE = "SYS$DISK:[." + MODULE_NAME+ "]" + FILE_NAME
+$ ELSE
+$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME
+$ ENDIF
+$ SOURCE_FILE = SOURCE_FILE - "]["
+$!
+$! Create The Object File Name.
+$!
+$ OBJECT_FILE = OBJ_DIR + F$PARSE(FILE_NAME,,,"NAME","SYNTAX_ONLY") + ".OBJ"
+$ ON WARNING THEN GOTO NEXT_FILE
+$!
+$! Check To See If The File We Want To Compile Is Actually There.
+$!
+$ IF (F$SEARCH(SOURCE_FILE).EQS."")
+$ THEN
+$!
+$! Tell The User That The File Doesn't Exist.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Doesn't Exist."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Exit The Build.
+$!
+$ GOTO EXIT
+$!
+$! End The File Exist Check.
+$!
+$ ENDIF
+$!
+$! Tell The User We Are Compiling The File.
+$!
+$ IF (MODULE_NAME.EQS."")
+$ THEN
+$ WRITE SYS$OUTPUT "Compiling The ",FILE_NAME," File. (",BUILDALL,",",STATE,")"
+$ ENDIF
+$ IF (MODULE_NAME.NES."")
+$ THEN
+$ WRITE SYS$OUTPUT " ",FILE_NAME,""
+$ ENDIF
+$!
+$! Compile The File.
+$!
+$ ON ERROR THEN GOTO NEXT_FILE
+$ FILE_NAME0 = F$ELEMENT(0,".",FILE_NAME)
+$ IF FILE_NAME - ".mar" .NES. FILE_NAME
+$ THEN
+$ MACRO/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ELSE
+$ IF COMPILEWITH_CC3 - FILE_NAME0 .NES. COMPILEWITH_CC3
+$ THEN
+$ CC3/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ELSE
+$ IF COMPILEWITH_CC4 - FILE_NAME0 .NES. COMPILEWITH_CC4
+$ THEN
+$ CC4/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ELSE
+$ IF COMPILEWITH_CC5 - FILE_NAME0 .NES. COMPILEWITH_CC5
+$ THEN
+$ CC5/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ELSE
+$ IF COMPILEWITH_CC6 - FILE_NAME0 .NES. COMPILEWITH_CC6
+$ THEN
+$ CC6/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ELSE
+$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$ IF STATE .EQS. "LIB"
+$ THEN
+$!
+$! Add It To The Library.
+$!
+$ LIBRARY/REPLACE 'LIB_NAME' 'OBJECT_FILE'
+$!
+$! Time To Clean Up The Object File.
+$!
+$ DELETE 'OBJECT_FILE';*
+$ ENDIF
+$!
+$! Go Back And Do It Again.
+$!
+$ GOTO NEXT_FILE
+$!
+$! All Done With This Library Part.
+$!
+$ FILE_DONE:
+$!
+$! Time To Build Some Applications
+$!
+$ IF F$TYPE('APPS_MODULE') .NES. "" .AND. BUILDALL .NES. "LIBRARY"
+$ THEN
+$ APPLICATION_COUNTER = 0
+$ NEXT_APPLICATION:
+$ APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE')
+$ IF APPLICATION .EQS. ";" THEN GOTO APPLICATION_DONE
+$
+$ APPLICATION_COUNTER = APPLICATION_COUNTER + 1
+$ APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION)
+$ APPLICATION = F$ELEMENT(0,"/",APPLICATION)
+$
+$! WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*"
+$! SHOW SYMBOL APPLICATION*
+$!
+$! Tell the user what happens
+$!
+$ WRITE SYS$OUTPUT " ",APPLICATION,".exe"
+$!
+$! Link The Program.
+$!
+$ ON ERROR THEN GOTO NEXT_APPLICATION
+$!
+$! Check To See If We Are To Link With A Specific TCP/IP Library.
+$!
+$ IF (TCPIP_LIB.NES."")
+$ THEN
+$!
+$! Link With A TCP/IP Library.
+$!
+$ LINK/'DEBUGGER'/'TRACEBACK'/EXE='EXE_DIR''APPLICATION'.EXE -
+ 'OBJ_DIR''APPLICATION_OBJECTS', -
+ 'CRYPTO_LIB'/LIBRARY, -
+ 'TCPIP_LIB','OPT_FILE'/OPTION
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Don't Link With A TCP/IP Library.
+$!
+$ LINK/'DEBUGGER'/'TRACEBACK'/EXE='EXE_DIR''APPLICATION'.EXE -
+ 'OBJ_DIR''APPLICATION_OBJECTS',-
+ 'CRYPTO_LIB'/LIBRARY, -
+ 'OPT_FILE'/OPTION
+$!
+$! End The TCP/IP Library Check.
+$!
+$ ENDIF
+$ GOTO NEXT_APPLICATION
+$ APPLICATION_DONE:
+$ ENDIF
+$!
+$! Go Back And Get The Next Module.
+$!
+$ GOTO MODULE_NEXT
+$!
+$! All Done With This Module.
+$!
+$ MODULE_DONE:
+$!
+$! Tell The User That We Are All Done.
+$!
+$ WRITE SYS$OUTPUT "All Done..."
+$ EXIT:
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$! Check To See If We Already Have A VAX C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A VAX C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE/SHARE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If We Already Have A GNU C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A GNU C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB/LIBRARY
+SYS$SHARE:VAXCRTL/SHARE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$! Check To See If We Already Have A DEC C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! Figure Out If We Need A non-VAX Or A VAX Linker Option File.
+$!
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$!
+$! We Need A DEC C Linker Option File For VAX.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE/SHARE
+$EOD
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Create The non-VAX Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Agianst
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
+SYS$SHARE:CMA$OPEN_RTL/SHARE
+$EOD
+$!
+$! End The DEC C Option File Check.
+$!
+$ ENDIF
+$!
+$! End The Option File Search.
+$!
+$ ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."ALL")
+$ THEN
+$!
+$! P1 Is Blank, So Build Everything.
+$!
+$ BUILDALL = "TRUE"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Else, Check To See If P1 Has A Valid Argument.
+$!
+$ IF (P1.EQS."LIBRARY").OR.(P1.EQS."APPS")
+$ THEN
+$!
+$! A Valid Argument.
+$!
+$ BUILDALL = P1
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " ALL : Just Build Everything."
+$ WRITE SYS$OUTPUT " LIBRARY : To Compile Just The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
+$ WRITE SYS$OUTPUT " APPS : To Compile Just The [.xxx.EXE.CRYPTO]*.EXE Programs."
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " ALPHA : Alpha Architecture."
+$ WRITE SYS$OUTPUT " IA64 : IA64 Architecture."
+$ WRITE SYS$OUTPUT " VAX : VAX Architecture."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P2 Is Blank.
+$!
+$ IF (P2.EQS."NODEBUG")
+$ THEN
+$!
+$! P2 Is NODEBUG, So Compile Without The Debugger Information.
+$!
+$ DEBUGGER = "NODEBUG"
+$ TRACEBACK = "NOTRACEBACK"
+$ GCC_OPTIMIZE = "OPTIMIZE"
+$ CC_OPTIMIZE = "OPTIMIZE"
+$ MACRO_OPTIMIZE = "OPTIMIZE"
+$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$ ELSE
+$!
+$! Check To See If We Are To Compile With Debugger Information.
+$!
+$ IF (P2.EQS."DEBUG")
+$ THEN
+$!
+$! Compile With Debugger Information.
+$!
+$ DEBUGGER = "DEBUG"
+$ TRACEBACK = "TRACEBACK"
+$ GCC_OPTIMIZE = "NOOPTIMIZE"
+$ CC_OPTIMIZE = "NOOPTIMIZE"
+$ MACRO_OPTIMIZE = "NOOPTIMIZE"
+$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$ ELSE
+$!
+$! They Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
+$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! End The P2 Check.
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By: Richard Levitte
+$! richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P5.
+$!
+$ IF (P5.EQS."")
+$ THEN
+$!
+$! Get The Version Of VMS We Are Using.
+$!
+$ ISSEVEN :=
+$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$! Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$ IF (TMP.GE.71)
+$ THEN
+$!
+$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$ ISSEVEN := ,PTHREAD_USE_D4
+$!
+$! End The VMS Version Check.
+$!
+$ ENDIF
+$!
+$! End The P5 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P7 Is Blank.
+$!
+$ IF (P7.EQS."")
+$ THEN
+$ POINTER_SIZE = ""
+$ ELSE
+$!
+$! Check is P7 Is Valid
+$!
+$ IF (P7.EQS."32")
+$ THEN
+$ POINTER_SIZE = "/POINTER_SIZE=32"
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ LIB32 = ""
+$ ELSE
+$ LIB32 = "32"
+$ ENDIF
+$ ELSE
+$ IF (P7.EQS."64")
+$ THEN
+$ LIB32 = ""
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ POINTER_SIZE = "/POINTER_SIZE=32"
+$ ELSE
+$ POINTER_SIZE = "/POINTER_SIZE=64"
+$ ENDIF
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P7," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " 32 : Compile with 32 bit pointer size"
+$ WRITE SYS$OUTPUT " 64 : Compile with 64 bit pointer size"
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ GOTO TIDY
+$!
+$! End The Valid Arguement Check.
+$!
+$ ENDIF
+$ ENDIF
+$!
+$! End The P7 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P3 Is Blank.
+$!
+$ IF (P3.EQS."")
+$ THEN
+$!
+$! O.K., The User Didn't Specify A Compiler, Let's Try To
+$! Find Out Which One To Use.
+$!
+$! Check To See If We Have GNU C.
+$!
+$ IF (F$TRNLNM("GNU_CC").NES."")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ P3 = "GNUC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Check To See If We Have VAXC Or DECC.
+$!
+$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ P3 = "DECC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ P3 = "VAXC"
+$!
+$! End The VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The DECC & VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For P4.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$! Find out what socket library we have available
+$!
+$ IF F$PARSE("SOCKETSHR:") .NES. ""
+$ THEN
+$!
+$! We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$ P4 = "SOCKETSHR"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$! Else, let's look for something else
+$!
+$ ELSE
+$!
+$! Like UCX (the reason to do this before Multinet is that the UCX
+$! emulation is easier to use...)
+$!
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+ .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+ .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$ THEN
+$!
+$! Last resort: a UCX or UCX-compatible library
+$!
+$ P4 = "UCX"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$! That was all...
+$!
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "TCPIP_TYPE_''P4',DSO_VMS"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+ CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If The User Entered A Valid Paramter.
+$!
+$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If The User Wanted DECC.
+$!
+$ IF (P3.EQS."DECC")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ COMPILER = "DECC"
+$!
+$! Tell The User We Are Using DECC.
+$!
+$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$! Use DECC...
+$!
+$ CC = "CC"
+$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+ THEN CC = "CC/DECC"
+$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89''POINTER_SIZE'" + -
+ "/NOLIST/PREFIX=ALL" + -
+ "/INCLUDE=(SYS$DISK:[._''ARCH'],SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.EVP],SYS$DISK:[.ASN1])" + -
+ CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
+$!
+$! End DECC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use VAXC.
+$!
+$ IF (P3.EQS."VAXC")
+$ THEN
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ COMPILER = "VAXC"
+$!
+$! Tell The User We Are Using VAX C.
+$!
+$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$! Compile Using VAXC.
+$!
+$ CC = "CC"
+$ IF ARCH.NES."VAX"
+$ THEN
+$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
+$ EXIT
+$ ENDIF
+$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
+$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[._''ARCH'],SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.EVP],SYS$DISK:[.ASN1])" + -
+ CCEXTRAFLAGS
+$ CCDEFS = """VAXC""," + CCDEFS
+$!
+$! Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
+$!
+$! End VAXC Check
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use GNU C.
+$!
+$ IF (P3.EQS."GNUC")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ COMPILER = "GNUC"
+$!
+$! Tell The User We Are Using GNUC.
+$!
+$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$! Use GNU C...
+$!
+$ CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[._''ARCH'],SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.EVP],SYS$DISK:[.ASN1])" + -
+ CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Set up default defines
+$!
+$ CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$! Finish up the definition of CC.
+$!
+$ IF COMPILER .EQS. "DECC"
+$ THEN
+$ IF CCDISABLEWARNINGS .EQS. ""
+$ THEN
+$ CC4DISABLEWARNINGS = "DOLLARID"
+$ CC6DISABLEWARNINGS = "MIXLINKAGE"
+$ ELSE
+$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
+$ CC6DISABLEWARNINGS = CCDISABLEWARNINGS + ",MIXLINKAGE"
+$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$ ENDIF
+$ CC4DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
+$ CC6DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC6DISABLEWARNINGS + "))"
+$ ELSE
+$ CCDISABLEWARNINGS = ""
+$ CC4DISABLEWARNINGS = ""
+$ CC6DISABLEWARNINGS = ""
+$ ENDIF
+$ CC3 = CC + "/DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS
+$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$ IF ARCH .EQS. "VAX" .AND. COMPILER .EQS. "DECC" .AND. P2 .NES. "DEBUG"
+$ THEN
+$ CC5 = CC + "/OPTIMIZE=NODISJOINT"
+$ ELSE
+$ CC5 = CC + "/NOOPTIMIZE"
+$ ENDIF
+$ CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
+$ CC6 = CC - CCDISABLEWARNINGS + CC6DISABLEWARNINGS
+$!
+$! Show user the result
+$!
+$ WRITE/SYMBOL SYS$OUTPUT "Main C Compiling Command: ",CC
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
+$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
+$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! Build a MACRO command for the architecture at hand
+$!
+$ IF ARCH .EQS. "VAX" THEN MACRO = "MACRO/''DEBUGGER'"
+$ IF ARCH .NES. "VAX" THEN MACRO = "MACRO/MIGRATION/''DEBUGGER'/''MACRO_OPTIMIZE'"
+$!
+$! Show user the result
+$!
+$ WRITE/SYMBOL SYS$OUTPUT "Main MACRO Compiling Command: ",MACRO
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" -
+ .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE"
+$ THEN
+$!
+$! Check to see if SOCKETSHR was chosen
+$!
+$ IF P4.EQS."SOCKETSHR"
+$ THEN
+$!
+$! Set the library to use SOCKETSHR
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT"
+$!
+$! Done with SOCKETSHR
+$!
+$ ENDIF
+$!
+$! Check to see if MULTINET was chosen
+$!
+$ IF P4.EQS."MULTINET"
+$ THEN
+$!
+$! Set the library to use UCX emulation.
+$!
+$ P4 = "UCX"
+$!
+$! Done with MULTINET
+$!
+$ ENDIF
+$!
+$! Check to see if UCX was chosen
+$!
+$ IF P4.EQS."UCX"
+$ THEN
+$!
+$! Set the library to use UCX.
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT"
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$ THEN
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT/OPT"
+$ ELSE
+$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT/OPT"
+$ ENDIF
+$!
+$! Done with UCX
+$!
+$ ENDIF
+$!
+$! Check to see if TCPIP was chosen
+$!
+$ IF P4.EQS."TCPIP"
+$ THEN
+$!
+$! Set the library to use TCPIP (post UCX).
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT"
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Check to see if NONE was chosen
+$!
+$ IF P4.EQS."NONE"
+$ THEN
+$!
+$! Do not use a TCPIP library.
+$!
+$ TCPIP_LIB = ""
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Print info
+$!
+$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P4," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
+$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
+$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Check if the user wanted to compile just a subset of all the encryption
+$! methods.
+$!
+$ IF P6 .NES. ""
+$ THEN
+$ ENCRYPT_TYPES = P6
+$ ENDIF
+$!
+$! Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "CRYPTO]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL/NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the logical name OPENSSL if it had a value
+$!
+$ IF __SAVE_OPENSSL .EQS. ""
+$ THEN
+$ DEASSIGN OPENSSL
+$ ELSE
+$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
+$ ENDIF
+$!
+$! Done
+$!
+$ RETURN
diff --git a/openssl/crypto/dsa/dsa_ossl.c b/openssl/crypto/dsa/dsa_ossl.c
index 927f6e2b8..a3ddd7d28 100644
--- a/openssl/crypto/dsa/dsa_ossl.c
+++ b/openssl/crypto/dsa/dsa_ossl.c
@@ -1,398 +1,398 @@
-/* crypto/dsa/dsa_ossl.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/bn.h>
-#include <openssl/sha.h>
-#include <openssl/dsa.h>
-#include <openssl/rand.h>
-#include <openssl/asn1.h>
-
-static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
-static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
-static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
- DSA *dsa);
-static int dsa_init(DSA *dsa);
-static int dsa_finish(DSA *dsa);
-
-static DSA_METHOD openssl_dsa_meth = {
-"OpenSSL DSA method",
-dsa_do_sign,
-dsa_sign_setup,
-dsa_do_verify,
-NULL, /* dsa_mod_exp, */
-NULL, /* dsa_bn_mod_exp, */
-dsa_init,
-dsa_finish,
-0,
-NULL,
-NULL,
-NULL
-};
-
-/* These macro wrappers replace attempts to use the dsa_mod_exp() and
- * bn_mod_exp() handlers in the DSA_METHOD structure. We avoid the problem of
- * having a the macro work as an expression by bundling an "err_instr". So;
- *
- * if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx,
- * dsa->method_mont_p)) goto err;
- *
- * can be replaced by;
- *
- * DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, &k, dsa->p, ctx,
- * dsa->method_mont_p);
- */
-
-#define DSA_MOD_EXP(err_instr,dsa,rr,a1,p1,a2,p2,m,ctx,in_mont) \
- do { \
- int _tmp_res53; \
- if((dsa)->meth->dsa_mod_exp) \
- _tmp_res53 = (dsa)->meth->dsa_mod_exp((dsa), (rr), (a1), (p1), \
- (a2), (p2), (m), (ctx), (in_mont)); \
- else \
- _tmp_res53 = BN_mod_exp2_mont((rr), (a1), (p1), (a2), (p2), \
- (m), (ctx), (in_mont)); \
- if(!_tmp_res53) err_instr; \
- } while(0)
-#define DSA_BN_MOD_EXP(err_instr,dsa,r,a,p,m,ctx,m_ctx) \
- do { \
- int _tmp_res53; \
- if((dsa)->meth->bn_mod_exp) \
- _tmp_res53 = (dsa)->meth->bn_mod_exp((dsa), (r), (a), (p), \
- (m), (ctx), (m_ctx)); \
- else \
- _tmp_res53 = BN_mod_exp_mont((r), (a), (p), (m), (ctx), (m_ctx)); \
- if(!_tmp_res53) err_instr; \
- } while(0)
-
-const DSA_METHOD *DSA_OpenSSL(void)
-{
- return &openssl_dsa_meth;
-}
-
-static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
- {
- BIGNUM *kinv=NULL,*r=NULL,*s=NULL;
- BIGNUM m;
- BIGNUM xr;
- BN_CTX *ctx=NULL;
- int reason=ERR_R_BN_LIB;
- DSA_SIG *ret=NULL;
-
- BN_init(&m);
- BN_init(&xr);
-
- if (!dsa->p || !dsa->q || !dsa->g)
- {
- reason=DSA_R_MISSING_PARAMETERS;
- goto err;
- }
-
- s=BN_new();
- if (s == NULL) goto err;
- ctx=BN_CTX_new();
- if (ctx == NULL) goto err;
-
- if ((dsa->kinv == NULL) || (dsa->r == NULL))
- {
- if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
- }
- else
- {
- kinv=dsa->kinv;
- dsa->kinv=NULL;
- r=dsa->r;
- dsa->r=NULL;
- }
-
-
- if (dlen > BN_num_bytes(dsa->q))
- /* if the digest length is greater than the size of q use the
- * BN_num_bits(dsa->q) leftmost bits of the digest, see
- * fips 186-3, 4.2 */
- dlen = BN_num_bytes(dsa->q);
- if (BN_bin2bn(dgst,dlen,&m) == NULL)
- goto err;
-
- /* Compute s = inv(k) (m + xr) mod q */
- if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
- if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */
- if (BN_cmp(s,dsa->q) > 0)
- if (!BN_sub(s,s,dsa->q)) goto err;
- if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
-
- ret=DSA_SIG_new();
- if (ret == NULL) goto err;
- ret->r = r;
- ret->s = s;
-
-err:
- if (!ret)
- {
- DSAerr(DSA_F_DSA_DO_SIGN,reason);
- BN_free(r);
- BN_free(s);
- }
- if (ctx != NULL) BN_CTX_free(ctx);
- BN_clear_free(&m);
- BN_clear_free(&xr);
- if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
- BN_clear_free(kinv);
- return(ret);
- }
-
-static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
- {
- BN_CTX *ctx;
- BIGNUM k,kq,*K,*kinv=NULL,*r=NULL;
- int ret=0;
-
- if (!dsa->p || !dsa->q || !dsa->g)
- {
- DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS);
- return 0;
- }
-
- BN_init(&k);
- BN_init(&kq);
-
- if (ctx_in == NULL)
- {
- if ((ctx=BN_CTX_new()) == NULL) goto err;
- }
- else
- ctx=ctx_in;
-
- if ((r=BN_new()) == NULL) goto err;
-
- /* Get random k */
- do
- if (!BN_rand_range(&k, dsa->q)) goto err;
- while (BN_is_zero(&k));
- if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
- {
- BN_set_flags(&k, BN_FLG_CONSTTIME);
- }
-
- if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
- {
- if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
- CRYPTO_LOCK_DSA,
- dsa->p, ctx))
- goto err;
- }
-
- /* Compute r = (g^k mod p) mod q */
-
- if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
- {
- if (!BN_copy(&kq, &k)) goto err;
-
- /* We do not want timing information to leak the length of k,
- * so we compute g^k using an equivalent exponent of fixed length.
- *
- * (This is a kludge that we need because the BN_mod_exp_mont()
- * does not let us specify the desired timing behaviour.) */
-
- if (!BN_add(&kq, &kq, dsa->q)) goto err;
- if (BN_num_bits(&kq) <= BN_num_bits(dsa->q))
- {
- if (!BN_add(&kq, &kq, dsa->q)) goto err;
- }
-
- K = &kq;
- }
- else
- {
- K = &k;
- }
- DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx,
- dsa->method_mont_p);
- if (!BN_mod(r,r,dsa->q,ctx)) goto err;
-
- /* Compute part of 's = inv(k) (m + xr) mod q' */
- if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err;
-
- if (*kinvp != NULL) BN_clear_free(*kinvp);
- *kinvp=kinv;
- kinv=NULL;
- if (*rp != NULL) BN_clear_free(*rp);
- *rp=r;
- ret=1;
-err:
- if (!ret)
- {
- DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
- if (r != NULL)
- BN_clear_free(r);
- }
- if (ctx_in == NULL) BN_CTX_free(ctx);
- BN_clear_free(&k);
- BN_clear_free(&kq);
- return(ret);
- }
-
-static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
- DSA *dsa)
- {
- BN_CTX *ctx;
- BIGNUM u1,u2,t1;
- BN_MONT_CTX *mont=NULL;
- int ret = -1, i;
- if (!dsa->p || !dsa->q || !dsa->g)
- {
- DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
- return -1;
- }
-
- i = BN_num_bits(dsa->q);
- /* fips 186-3 allows only different sizes for q */
- if (i != 160 && i != 224 && i != 256)
- {
- DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
- return -1;
- }
-
- if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS)
- {
- DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE);
- return -1;
- }
- BN_init(&u1);
- BN_init(&u2);
- BN_init(&t1);
-
- if ((ctx=BN_CTX_new()) == NULL) goto err;
-
- if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
- BN_ucmp(sig->r, dsa->q) >= 0)
- {
- ret = 0;
- goto err;
- }
- if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
- BN_ucmp(sig->s, dsa->q) >= 0)
- {
- ret = 0;
- goto err;
- }
-
- /* Calculate W = inv(S) mod Q
- * save W in u2 */
- if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
-
- /* save M in u1 */
- if (dgst_len > (i >> 3))
- /* if the digest length is greater than the size of q use the
- * BN_num_bits(dsa->q) leftmost bits of the digest, see
- * fips 186-3, 4.2 */
- dgst_len = (i >> 3);
- if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
-
- /* u1 = M * w mod q */
- if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err;
-
- /* u2 = r * w mod q */
- if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;
-
-
- if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
- {
- mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
- CRYPTO_LOCK_DSA, dsa->p, ctx);
- if (!mont)
- goto err;
- }
-
-
- DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, mont);
- /* BN_copy(&u1,&t1); */
- /* let u1 = u1 mod q */
- if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;
-
- /* V is now in u1. If the signature is correct, it will be
- * equal to R. */
- ret=(BN_ucmp(&u1, sig->r) == 0);
-
- err:
- /* XXX: surely this is wrong - if ret is 0, it just didn't verify;
- there is no error in BN. Test should be ret == -1 (Ben) */
- if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
- if (ctx != NULL) BN_CTX_free(ctx);
- BN_free(&u1);
- BN_free(&u2);
- BN_free(&t1);
- return(ret);
- }
-
-static int dsa_init(DSA *dsa)
-{
- dsa->flags|=DSA_FLAG_CACHE_MONT_P;
- return(1);
-}
-
-static int dsa_finish(DSA *dsa)
-{
- if(dsa->method_mont_p)
- BN_MONT_CTX_free(dsa->method_mont_p);
- return(1);
-}
-
+/* crypto/dsa/dsa_ossl.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/sha.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+#include <openssl/asn1.h>
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
+static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+ DSA *dsa);
+static int dsa_init(DSA *dsa);
+static int dsa_finish(DSA *dsa);
+
+static DSA_METHOD openssl_dsa_meth = {
+"OpenSSL DSA method",
+dsa_do_sign,
+dsa_sign_setup,
+dsa_do_verify,
+NULL, /* dsa_mod_exp, */
+NULL, /* dsa_bn_mod_exp, */
+dsa_init,
+dsa_finish,
+0,
+NULL,
+NULL,
+NULL
+};
+
+/* These macro wrappers replace attempts to use the dsa_mod_exp() and
+ * bn_mod_exp() handlers in the DSA_METHOD structure. We avoid the problem of
+ * having a the macro work as an expression by bundling an "err_instr". So;
+ *
+ * if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx,
+ * dsa->method_mont_p)) goto err;
+ *
+ * can be replaced by;
+ *
+ * DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, &k, dsa->p, ctx,
+ * dsa->method_mont_p);
+ */
+
+#define DSA_MOD_EXP(err_instr,dsa,rr,a1,p1,a2,p2,m,ctx,in_mont) \
+ do { \
+ int _tmp_res53; \
+ if((dsa)->meth->dsa_mod_exp) \
+ _tmp_res53 = (dsa)->meth->dsa_mod_exp((dsa), (rr), (a1), (p1), \
+ (a2), (p2), (m), (ctx), (in_mont)); \
+ else \
+ _tmp_res53 = BN_mod_exp2_mont((rr), (a1), (p1), (a2), (p2), \
+ (m), (ctx), (in_mont)); \
+ if(!_tmp_res53) err_instr; \
+ } while(0)
+#define DSA_BN_MOD_EXP(err_instr,dsa,r,a,p,m,ctx,m_ctx) \
+ do { \
+ int _tmp_res53; \
+ if((dsa)->meth->bn_mod_exp) \
+ _tmp_res53 = (dsa)->meth->bn_mod_exp((dsa), (r), (a), (p), \
+ (m), (ctx), (m_ctx)); \
+ else \
+ _tmp_res53 = BN_mod_exp_mont((r), (a), (p), (m), (ctx), (m_ctx)); \
+ if(!_tmp_res53) err_instr; \
+ } while(0)
+
+const DSA_METHOD *DSA_OpenSSL(void)
+{
+ return &openssl_dsa_meth;
+}
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+ {
+ BIGNUM *kinv=NULL,*r=NULL,*s=NULL;
+ BIGNUM m;
+ BIGNUM xr;
+ BN_CTX *ctx=NULL;
+ int reason=ERR_R_BN_LIB;
+ DSA_SIG *ret=NULL;
+
+ BN_init(&m);
+ BN_init(&xr);
+
+ if (!dsa->p || !dsa->q || !dsa->g)
+ {
+ reason=DSA_R_MISSING_PARAMETERS;
+ goto err;
+ }
+
+ s=BN_new();
+ if (s == NULL) goto err;
+ ctx=BN_CTX_new();
+ if (ctx == NULL) goto err;
+
+ if ((dsa->kinv == NULL) || (dsa->r == NULL))
+ {
+ if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
+ }
+ else
+ {
+ kinv=dsa->kinv;
+ dsa->kinv=NULL;
+ r=dsa->r;
+ dsa->r=NULL;
+ }
+
+
+ if (dlen > BN_num_bytes(dsa->q))
+ /* if the digest length is greater than the size of q use the
+ * BN_num_bits(dsa->q) leftmost bits of the digest, see
+ * fips 186-3, 4.2 */
+ dlen = BN_num_bytes(dsa->q);
+ if (BN_bin2bn(dgst,dlen,&m) == NULL)
+ goto err;
+
+ /* Compute s = inv(k) (m + xr) mod q */
+ if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
+ if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */
+ if (BN_cmp(s,dsa->q) > 0)
+ if (!BN_sub(s,s,dsa->q)) goto err;
+ if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
+
+ ret=DSA_SIG_new();
+ if (ret == NULL) goto err;
+ ret->r = r;
+ ret->s = s;
+
+err:
+ if (!ret)
+ {
+ DSAerr(DSA_F_DSA_DO_SIGN,reason);
+ BN_free(r);
+ BN_free(s);
+ }
+ if (ctx != NULL) BN_CTX_free(ctx);
+ BN_clear_free(&m);
+ BN_clear_free(&xr);
+ if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
+ BN_clear_free(kinv);
+ return(ret);
+ }
+
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+ {
+ BN_CTX *ctx;
+ BIGNUM k,kq,*K,*kinv=NULL,*r=NULL;
+ int ret=0;
+
+ if (!dsa->p || !dsa->q || !dsa->g)
+ {
+ DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS);
+ return 0;
+ }
+
+ BN_init(&k);
+ BN_init(&kq);
+
+ if (ctx_in == NULL)
+ {
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+ }
+ else
+ ctx=ctx_in;
+
+ if ((r=BN_new()) == NULL) goto err;
+
+ /* Get random k */
+ do
+ if (!BN_rand_range(&k, dsa->q)) goto err;
+ while (BN_is_zero(&k));
+ if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
+ {
+ BN_set_flags(&k, BN_FLG_CONSTTIME);
+ }
+
+ if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
+ {
+ if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
+ CRYPTO_LOCK_DSA,
+ dsa->p, ctx))
+ goto err;
+ }
+
+ /* Compute r = (g^k mod p) mod q */
+
+ if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
+ {
+ if (!BN_copy(&kq, &k)) goto err;
+
+ /* We do not want timing information to leak the length of k,
+ * so we compute g^k using an equivalent exponent of fixed length.
+ *
+ * (This is a kludge that we need because the BN_mod_exp_mont()
+ * does not let us specify the desired timing behaviour.) */
+
+ if (!BN_add(&kq, &kq, dsa->q)) goto err;
+ if (BN_num_bits(&kq) <= BN_num_bits(dsa->q))
+ {
+ if (!BN_add(&kq, &kq, dsa->q)) goto err;
+ }
+
+ K = &kq;
+ }
+ else
+ {
+ K = &k;
+ }
+ DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx,
+ dsa->method_mont_p);
+ if (!BN_mod(r,r,dsa->q,ctx)) goto err;
+
+ /* Compute part of 's = inv(k) (m + xr) mod q' */
+ if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err;
+
+ if (*kinvp != NULL) BN_clear_free(*kinvp);
+ *kinvp=kinv;
+ kinv=NULL;
+ if (*rp != NULL) BN_clear_free(*rp);
+ *rp=r;
+ ret=1;
+err:
+ if (!ret)
+ {
+ DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
+ if (r != NULL)
+ BN_clear_free(r);
+ }
+ if (ctx_in == NULL) BN_CTX_free(ctx);
+ BN_clear_free(&k);
+ BN_clear_free(&kq);
+ return(ret);
+ }
+
+static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+ DSA *dsa)
+ {
+ BN_CTX *ctx;
+ BIGNUM u1,u2,t1;
+ BN_MONT_CTX *mont=NULL;
+ int ret = -1, i;
+ if (!dsa->p || !dsa->q || !dsa->g)
+ {
+ DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
+ return -1;
+ }
+
+ i = BN_num_bits(dsa->q);
+ /* fips 186-3 allows only different sizes for q */
+ if (i != 160 && i != 224 && i != 256)
+ {
+ DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
+ return -1;
+ }
+
+ if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS)
+ {
+ DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE);
+ return -1;
+ }
+ BN_init(&u1);
+ BN_init(&u2);
+ BN_init(&t1);
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+ if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
+ BN_ucmp(sig->r, dsa->q) >= 0)
+ {
+ ret = 0;
+ goto err;
+ }
+ if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
+ BN_ucmp(sig->s, dsa->q) >= 0)
+ {
+ ret = 0;
+ goto err;
+ }
+
+ /* Calculate W = inv(S) mod Q
+ * save W in u2 */
+ if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
+
+ /* save M in u1 */
+ if (dgst_len > (i >> 3))
+ /* if the digest length is greater than the size of q use the
+ * BN_num_bits(dsa->q) leftmost bits of the digest, see
+ * fips 186-3, 4.2 */
+ dgst_len = (i >> 3);
+ if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
+
+ /* u1 = M * w mod q */
+ if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err;
+
+ /* u2 = r * w mod q */
+ if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;
+
+
+ if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
+ {
+ mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
+ CRYPTO_LOCK_DSA, dsa->p, ctx);
+ if (!mont)
+ goto err;
+ }
+
+
+ DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, mont);
+ /* BN_copy(&u1,&t1); */
+ /* let u1 = u1 mod q */
+ if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;
+
+ /* V is now in u1. If the signature is correct, it will be
+ * equal to R. */
+ ret=(BN_ucmp(&u1, sig->r) == 0);
+
+ err:
+ /* XXX: surely this is wrong - if ret is 0, it just didn't verify;
+ there is no error in BN. Test should be ret == -1 (Ben) */
+ if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
+ if (ctx != NULL) BN_CTX_free(ctx);
+ BN_free(&u1);
+ BN_free(&u2);
+ BN_free(&t1);
+ return(ret);
+ }
+
+static int dsa_init(DSA *dsa)
+{
+ dsa->flags|=DSA_FLAG_CACHE_MONT_P;
+ return(1);
+}
+
+static int dsa_finish(DSA *dsa)
+{
+ if(dsa->method_mont_p)
+ BN_MONT_CTX_free(dsa->method_mont_p);
+ return(1);
+}
+
diff --git a/openssl/crypto/ec/ec2_smpl.c b/openssl/crypto/ec/ec2_smpl.c
index 1725dd128..af94458ca 100644
--- a/openssl/crypto/ec/ec2_smpl.c
+++ b/openssl/crypto/ec/ec2_smpl.c
@@ -1,1042 +1,1042 @@
-/* crypto/ec/ec2_smpl.c */
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- *
- * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
- * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
- * to the OpenSSL project.
- *
- * The ECC Code is licensed pursuant to the OpenSSL open source
- * license provided below.
- *
- * The software is originally written by Sheueling Chang Shantz and
- * Douglas Stebila of Sun Microsystems Laboratories.
- *
- */
-/* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <openssl/err.h>
-
-#include "ec_lcl.h"
-
-
-const EC_METHOD *EC_GF2m_simple_method(void)
- {
- static const EC_METHOD ret = {
- NID_X9_62_characteristic_two_field,
- ec_GF2m_simple_group_init,
- ec_GF2m_simple_group_finish,
- ec_GF2m_simple_group_clear_finish,
- ec_GF2m_simple_group_copy,
- ec_GF2m_simple_group_set_curve,
- ec_GF2m_simple_group_get_curve,
- ec_GF2m_simple_group_get_degree,
- ec_GF2m_simple_group_check_discriminant,
- ec_GF2m_simple_point_init,
- ec_GF2m_simple_point_finish,
- ec_GF2m_simple_point_clear_finish,
- ec_GF2m_simple_point_copy,
- ec_GF2m_simple_point_set_to_infinity,
- 0 /* set_Jprojective_coordinates_GFp */,
- 0 /* get_Jprojective_coordinates_GFp */,
- ec_GF2m_simple_point_set_affine_coordinates,
- ec_GF2m_simple_point_get_affine_coordinates,
- ec_GF2m_simple_set_compressed_coordinates,
- ec_GF2m_simple_point2oct,
- ec_GF2m_simple_oct2point,
- ec_GF2m_simple_add,
- ec_GF2m_simple_dbl,
- ec_GF2m_simple_invert,
- ec_GF2m_simple_is_at_infinity,
- ec_GF2m_simple_is_on_curve,
- ec_GF2m_simple_cmp,
- ec_GF2m_simple_make_affine,
- ec_GF2m_simple_points_make_affine,
-
- /* the following three method functions are defined in ec2_mult.c */
- ec_GF2m_simple_mul,
- ec_GF2m_precompute_mult,
- ec_GF2m_have_precompute_mult,
-
- ec_GF2m_simple_field_mul,
- ec_GF2m_simple_field_sqr,
- ec_GF2m_simple_field_div,
- 0 /* field_encode */,
- 0 /* field_decode */,
- 0 /* field_set_to_one */ };
-
- return &ret;
- }
-
-
-/* Initialize a GF(2^m)-based EC_GROUP structure.
- * Note that all other members are handled by EC_GROUP_new.
- */
-int ec_GF2m_simple_group_init(EC_GROUP *group)
- {
- BN_init(&group->field);
- BN_init(&group->a);
- BN_init(&group->b);
- return 1;
- }
-
-
-/* Free a GF(2^m)-based EC_GROUP structure.
- * Note that all other members are handled by EC_GROUP_free.
- */
-void ec_GF2m_simple_group_finish(EC_GROUP *group)
- {
- BN_free(&group->field);
- BN_free(&group->a);
- BN_free(&group->b);
- }
-
-
-/* Clear and free a GF(2^m)-based EC_GROUP structure.
- * Note that all other members are handled by EC_GROUP_clear_free.
- */
-void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
- {
- BN_clear_free(&group->field);
- BN_clear_free(&group->a);
- BN_clear_free(&group->b);
- group->poly[0] = 0;
- group->poly[1] = 0;
- group->poly[2] = 0;
- group->poly[3] = 0;
- group->poly[4] = 0;
- group->poly[5] = -1;
- }
-
-
-/* Copy a GF(2^m)-based EC_GROUP structure.
- * Note that all other members are handled by EC_GROUP_copy.
- */
-int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
- {
- int i;
- if (!BN_copy(&dest->field, &src->field)) return 0;
- if (!BN_copy(&dest->a, &src->a)) return 0;
- if (!BN_copy(&dest->b, &src->b)) return 0;
- dest->poly[0] = src->poly[0];
- dest->poly[1] = src->poly[1];
- dest->poly[2] = src->poly[2];
- dest->poly[3] = src->poly[3];
- dest->poly[4] = src->poly[4];
- dest->poly[5] = src->poly[5];
- if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
- if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
- for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0;
- for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0;
- return 1;
- }
-
-
-/* Set the curve parameters of an EC_GROUP structure. */
-int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
- const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
- {
- int ret = 0, i;
-
- /* group->field */
- if (!BN_copy(&group->field, p)) goto err;
- i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1;
- if ((i != 5) && (i != 3))
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
- goto err;
- }
-
- /* group->a */
- if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err;
- if(bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
- for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0;
-
- /* group->b */
- if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err;
- if(bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
- for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0;
-
- ret = 1;
- err:
- return ret;
- }
-
-
-/* Get the curve parameters of an EC_GROUP structure.
- * If p, a, or b are NULL then there values will not be set but the method will return with success.
- */
-int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
- {
- int ret = 0;
-
- if (p != NULL)
- {
- if (!BN_copy(p, &group->field)) return 0;
- }
-
- if (a != NULL)
- {
- if (!BN_copy(a, &group->a)) goto err;
- }
-
- if (b != NULL)
- {
- if (!BN_copy(b, &group->b)) goto err;
- }
-
- ret = 1;
-
- err:
- return ret;
- }
-
-
-/* Gets the degree of the field. For a curve over GF(2^m) this is the value m. */
-int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
- {
- return BN_num_bits(&group->field)-1;
- }
-
-
-/* Checks the discriminant of the curve.
- * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
- */
-int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
- {
- int ret = 0;
- BIGNUM *b;
- BN_CTX *new_ctx = NULL;
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- BN_CTX_start(ctx);
- b = BN_CTX_get(ctx);
- if (b == NULL) goto err;
-
- if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) goto err;
-
- /* check the discriminant:
- * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
- */
- if (BN_is_zero(b)) goto err;
-
- ret = 1;
-
-err:
- if (ctx != NULL)
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-/* Initializes an EC_POINT. */
-int ec_GF2m_simple_point_init(EC_POINT *point)
- {
- BN_init(&point->X);
- BN_init(&point->Y);
- BN_init(&point->Z);
- return 1;
- }
-
-
-/* Frees an EC_POINT. */
-void ec_GF2m_simple_point_finish(EC_POINT *point)
- {
- BN_free(&point->X);
- BN_free(&point->Y);
- BN_free(&point->Z);
- }
-
-
-/* Clears and frees an EC_POINT. */
-void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
- {
- BN_clear_free(&point->X);
- BN_clear_free(&point->Y);
- BN_clear_free(&point->Z);
- point->Z_is_one = 0;
- }
-
-
-/* Copy the contents of one EC_POINT into another. Assumes dest is initialized. */
-int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
- {
- if (!BN_copy(&dest->X, &src->X)) return 0;
- if (!BN_copy(&dest->Y, &src->Y)) return 0;
- if (!BN_copy(&dest->Z, &src->Z)) return 0;
- dest->Z_is_one = src->Z_is_one;
-
- return 1;
- }
-
-
-/* Set an EC_POINT to the point at infinity.
- * A point at infinity is represented by having Z=0.
- */
-int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
- {
- point->Z_is_one = 0;
- BN_zero(&point->Z);
- return 1;
- }
-
-
-/* Set the coordinates of an EC_POINT using affine coordinates.
- * Note that the simple implementation only uses affine coordinates.
- */
-int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
- const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
- {
- int ret = 0;
- if (x == NULL || y == NULL)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
-
- if (!BN_copy(&point->X, x)) goto err;
- BN_set_negative(&point->X, 0);
- if (!BN_copy(&point->Y, y)) goto err;
- BN_set_negative(&point->Y, 0);
- if (!BN_copy(&point->Z, BN_value_one())) goto err;
- BN_set_negative(&point->Z, 0);
- point->Z_is_one = 1;
- ret = 1;
-
- err:
- return ret;
- }
-
-
-/* Gets the affine coordinates of an EC_POINT.
- * Note that the simple implementation only uses affine coordinates.
- */
-int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
- BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
- {
- int ret = 0;
-
- if (EC_POINT_is_at_infinity(group, point))
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
- return 0;
- }
-
- if (BN_cmp(&point->Z, BN_value_one()))
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
- if (x != NULL)
- {
- if (!BN_copy(x, &point->X)) goto err;
- BN_set_negative(x, 0);
- }
- if (y != NULL)
- {
- if (!BN_copy(y, &point->Y)) goto err;
- BN_set_negative(y, 0);
- }
- ret = 1;
-
- err:
- return ret;
- }
-
-
-/* Calculates and sets the affine coordinates of an EC_POINT from the given
- * compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
- * Note that the simple implementation only uses affine coordinates.
- *
- * The method is from the following publication:
- *
- * Harper, Menezes, Vanstone:
- * "Public-Key Cryptosystems with Very Small Key Lengths",
- * EUROCRYPT '92, Springer-Verlag LNCS 658,
- * published February 1993
- *
- * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
- * the same method, but claim no priority date earlier than July 29, 1994
- * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
- */
-int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
- const BIGNUM *x_, int y_bit, BN_CTX *ctx)
- {
- BN_CTX *new_ctx = NULL;
- BIGNUM *tmp, *x, *y, *z;
- int ret = 0, z0;
-
- /* clear error queue */
- ERR_clear_error();
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- y_bit = (y_bit != 0) ? 1 : 0;
-
- BN_CTX_start(ctx);
- tmp = BN_CTX_get(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- z = BN_CTX_get(ctx);
- if (z == NULL) goto err;
-
- if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
- if (BN_is_zero(x))
- {
- if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
- }
- else
- {
- if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
- if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
- if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
- if (!BN_GF2m_add(tmp, x, tmp)) goto err;
- if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
- {
- unsigned long err = ERR_peek_last_error();
-
- if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
- {
- ERR_clear_error();
- ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
- }
- else
- ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
- goto err;
- }
- z0 = (BN_is_odd(z)) ? 1 : 0;
- if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
- if (z0 != y_bit)
- {
- if (!BN_GF2m_add(y, y, x)) goto err;
- }
- }
-
- if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-/* Converts an EC_POINT to an octet string.
- * If buf is NULL, the encoded length will be returned.
- * If the length len of buf is smaller than required an error will be returned.
- */
-size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
- unsigned char *buf, size_t len, BN_CTX *ctx)
- {
- size_t ret;
- BN_CTX *new_ctx = NULL;
- int used_ctx = 0;
- BIGNUM *x, *y, *yxi;
- size_t field_len, i, skip;
-
- if ((form != POINT_CONVERSION_COMPRESSED)
- && (form != POINT_CONVERSION_UNCOMPRESSED)
- && (form != POINT_CONVERSION_HYBRID))
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
- goto err;
- }
-
- if (EC_POINT_is_at_infinity(group, point))
- {
- /* encodes to a single 0 octet */
- if (buf != NULL)
- {
- if (len < 1)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
- return 0;
- }
- buf[0] = 0;
- }
- return 1;
- }
-
-
- /* ret := required output buffer length */
- field_len = (EC_GROUP_get_degree(group) + 7) / 8;
- ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
-
- /* if 'buf' is NULL, just return required length */
- if (buf != NULL)
- {
- if (len < ret)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
- goto err;
- }
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- used_ctx = 1;
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- yxi = BN_CTX_get(ctx);
- if (yxi == NULL) goto err;
-
- if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
-
- buf[0] = form;
- if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
- {
- if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
- if (BN_is_odd(yxi)) buf[0]++;
- }
-
- i = 1;
-
- skip = field_len - BN_num_bytes(x);
- if (skip > field_len)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- while (skip > 0)
- {
- buf[i++] = 0;
- skip--;
- }
- skip = BN_bn2bin(x, buf + i);
- i += skip;
- if (i != 1 + field_len)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
- {
- skip = field_len - BN_num_bytes(y);
- if (skip > field_len)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- while (skip > 0)
- {
- buf[i++] = 0;
- skip--;
- }
- skip = BN_bn2bin(y, buf + i);
- i += skip;
- }
-
- if (i != ret)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- }
-
- if (used_ctx)
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
-
- err:
- if (used_ctx)
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return 0;
- }
-
-
-/* Converts an octet string representation to an EC_POINT.
- * Note that the simple implementation only uses affine coordinates.
- */
-int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
- const unsigned char *buf, size_t len, BN_CTX *ctx)
- {
- point_conversion_form_t form;
- int y_bit;
- BN_CTX *new_ctx = NULL;
- BIGNUM *x, *y, *yxi;
- size_t field_len, enc_len;
- int ret = 0;
-
- if (len == 0)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
- return 0;
- }
- form = buf[0];
- y_bit = form & 1;
- form = form & ~1U;
- if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
- && (form != POINT_CONVERSION_UNCOMPRESSED)
- && (form != POINT_CONVERSION_HYBRID))
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
- if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- if (form == 0)
- {
- if (len != 1)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- return EC_POINT_set_to_infinity(group, point);
- }
-
- field_len = (EC_GROUP_get_degree(group) + 7) / 8;
- enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
-
- if (len != enc_len)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- yxi = BN_CTX_get(ctx);
- if (yxi == NULL) goto err;
-
- if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
- if (BN_ucmp(x, &group->field) >= 0)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- goto err;
- }
-
- if (form == POINT_CONVERSION_COMPRESSED)
- {
- if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;
- }
- else
- {
- if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
- if (BN_ucmp(y, &group->field) >= 0)
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- goto err;
- }
- if (form == POINT_CONVERSION_HYBRID)
- {
- if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
- if (y_bit != BN_is_odd(yxi))
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- goto err;
- }
- }
-
- if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
- }
-
- if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
- {
- ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
- goto err;
- }
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-/* Computes a + b and stores the result in r. r could be a or b, a could be b.
- * Uses algorithm A.10.2 of IEEE P1363.
- */
-int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
- {
- BN_CTX *new_ctx = NULL;
- BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
- int ret = 0;
-
- if (EC_POINT_is_at_infinity(group, a))
- {
- if (!EC_POINT_copy(r, b)) return 0;
- return 1;
- }
-
- if (EC_POINT_is_at_infinity(group, b))
- {
- if (!EC_POINT_copy(r, a)) return 0;
- return 1;
- }
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- x0 = BN_CTX_get(ctx);
- y0 = BN_CTX_get(ctx);
- x1 = BN_CTX_get(ctx);
- y1 = BN_CTX_get(ctx);
- x2 = BN_CTX_get(ctx);
- y2 = BN_CTX_get(ctx);
- s = BN_CTX_get(ctx);
- t = BN_CTX_get(ctx);
- if (t == NULL) goto err;
-
- if (a->Z_is_one)
- {
- if (!BN_copy(x0, &a->X)) goto err;
- if (!BN_copy(y0, &a->Y)) goto err;
- }
- else
- {
- if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err;
- }
- if (b->Z_is_one)
- {
- if (!BN_copy(x1, &b->X)) goto err;
- if (!BN_copy(y1, &b->Y)) goto err;
- }
- else
- {
- if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err;
- }
-
-
- if (BN_GF2m_cmp(x0, x1))
- {
- if (!BN_GF2m_add(t, x0, x1)) goto err;
- if (!BN_GF2m_add(s, y0, y1)) goto err;
- if (!group->meth->field_div(group, s, s, t, ctx)) goto err;
- if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
- if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
- if (!BN_GF2m_add(x2, x2, s)) goto err;
- if (!BN_GF2m_add(x2, x2, t)) goto err;
- }
- else
- {
- if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1))
- {
- if (!EC_POINT_set_to_infinity(group, r)) goto err;
- ret = 1;
- goto err;
- }
- if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err;
- if (!BN_GF2m_add(s, s, x1)) goto err;
-
- if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
- if (!BN_GF2m_add(x2, x2, s)) goto err;
- if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
- }
-
- if (!BN_GF2m_add(y2, x1, x2)) goto err;
- if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err;
- if (!BN_GF2m_add(y2, y2, x2)) goto err;
- if (!BN_GF2m_add(y2, y2, y1)) goto err;
-
- if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err;
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-/* Computes 2 * a and stores the result in r. r could be a.
- * Uses algorithm A.10.2 of IEEE P1363.
- */
-int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
- {
- return ec_GF2m_simple_add(group, r, a, a, ctx);
- }
-
-
-int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
- {
- if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
- /* point is its own inverse */
- return 1;
-
- if (!EC_POINT_make_affine(group, point, ctx)) return 0;
- return BN_GF2m_add(&point->Y, &point->X, &point->Y);
- }
-
-
-/* Indicates whether the given point is the point at infinity. */
-int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
- {
- return BN_is_zero(&point->Z);
- }
-
-
-/* Determines whether the given EC_POINT is an actual point on the curve defined
- * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation:
- * y^2 + x*y = x^3 + a*x^2 + b.
- */
-int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
- {
- int ret = -1;
- BN_CTX *new_ctx = NULL;
- BIGNUM *lh, *y2;
- int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
- int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
-
- if (EC_POINT_is_at_infinity(group, point))
- return 1;
-
- field_mul = group->meth->field_mul;
- field_sqr = group->meth->field_sqr;
-
- /* only support affine coordinates */
- if (!point->Z_is_one) goto err;
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return -1;
- }
-
- BN_CTX_start(ctx);
- y2 = BN_CTX_get(ctx);
- lh = BN_CTX_get(ctx);
- if (lh == NULL) goto err;
-
- /* We have a curve defined by a Weierstrass equation
- * y^2 + x*y = x^3 + a*x^2 + b.
- * <=> x^3 + a*x^2 + x*y + b + y^2 = 0
- * <=> ((x + a) * x + y ) * x + b + y^2 = 0
- */
- if (!BN_GF2m_add(lh, &point->X, &group->a)) goto err;
- if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
- if (!BN_GF2m_add(lh, lh, &point->Y)) goto err;
- if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
- if (!BN_GF2m_add(lh, lh, &group->b)) goto err;
- if (!field_sqr(group, y2, &point->Y, ctx)) goto err;
- if (!BN_GF2m_add(lh, lh, y2)) goto err;
- ret = BN_is_zero(lh);
- err:
- if (ctx) BN_CTX_end(ctx);
- if (new_ctx) BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-/* Indicates whether two points are equal.
- * Return values:
- * -1 error
- * 0 equal (in affine coordinates)
- * 1 not equal
- */
-int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
- {
- BIGNUM *aX, *aY, *bX, *bY;
- BN_CTX *new_ctx = NULL;
- int ret = -1;
-
- if (EC_POINT_is_at_infinity(group, a))
- {
- return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
- }
-
- if (EC_POINT_is_at_infinity(group, b))
- return 1;
-
- if (a->Z_is_one && b->Z_is_one)
- {
- return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
- }
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return -1;
- }
-
- BN_CTX_start(ctx);
- aX = BN_CTX_get(ctx);
- aY = BN_CTX_get(ctx);
- bX = BN_CTX_get(ctx);
- bY = BN_CTX_get(ctx);
- if (bY == NULL) goto err;
-
- if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) goto err;
- if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) goto err;
- ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
-
- err:
- if (ctx) BN_CTX_end(ctx);
- if (new_ctx) BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-/* Forces the given EC_POINT to internally use affine coordinates. */
-int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
- {
- BN_CTX *new_ctx = NULL;
- BIGNUM *x, *y;
- int ret = 0;
-
- if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
- return 1;
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- if (y == NULL) goto err;
-
- if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
- if (!BN_copy(&point->X, x)) goto err;
- if (!BN_copy(&point->Y, y)) goto err;
- if (!BN_one(&point->Z)) goto err;
-
- ret = 1;
-
- err:
- if (ctx) BN_CTX_end(ctx);
- if (new_ctx) BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-/* Forces each of the EC_POINTs in the given array to use affine coordinates. */
-int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
- {
- size_t i;
-
- for (i = 0; i < num; i++)
- {
- if (!group->meth->make_affine(group, points[i], ctx)) return 0;
- }
-
- return 1;
- }
-
-
-/* Wrapper to simple binary polynomial field multiplication implementation. */
-int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
- {
- return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
- }
-
-
-/* Wrapper to simple binary polynomial field squaring implementation. */
-int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
- {
- return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
- }
-
-
-/* Wrapper to simple binary polynomial field division implementation. */
-int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
- {
- return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
- }
+/* crypto/ec/ec2_smpl.c */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/err.h>
+
+#include "ec_lcl.h"
+
+
+const EC_METHOD *EC_GF2m_simple_method(void)
+ {
+ static const EC_METHOD ret = {
+ NID_X9_62_characteristic_two_field,
+ ec_GF2m_simple_group_init,
+ ec_GF2m_simple_group_finish,
+ ec_GF2m_simple_group_clear_finish,
+ ec_GF2m_simple_group_copy,
+ ec_GF2m_simple_group_set_curve,
+ ec_GF2m_simple_group_get_curve,
+ ec_GF2m_simple_group_get_degree,
+ ec_GF2m_simple_group_check_discriminant,
+ ec_GF2m_simple_point_init,
+ ec_GF2m_simple_point_finish,
+ ec_GF2m_simple_point_clear_finish,
+ ec_GF2m_simple_point_copy,
+ ec_GF2m_simple_point_set_to_infinity,
+ 0 /* set_Jprojective_coordinates_GFp */,
+ 0 /* get_Jprojective_coordinates_GFp */,
+ ec_GF2m_simple_point_set_affine_coordinates,
+ ec_GF2m_simple_point_get_affine_coordinates,
+ ec_GF2m_simple_set_compressed_coordinates,
+ ec_GF2m_simple_point2oct,
+ ec_GF2m_simple_oct2point,
+ ec_GF2m_simple_add,
+ ec_GF2m_simple_dbl,
+ ec_GF2m_simple_invert,
+ ec_GF2m_simple_is_at_infinity,
+ ec_GF2m_simple_is_on_curve,
+ ec_GF2m_simple_cmp,
+ ec_GF2m_simple_make_affine,
+ ec_GF2m_simple_points_make_affine,
+
+ /* the following three method functions are defined in ec2_mult.c */
+ ec_GF2m_simple_mul,
+ ec_GF2m_precompute_mult,
+ ec_GF2m_have_precompute_mult,
+
+ ec_GF2m_simple_field_mul,
+ ec_GF2m_simple_field_sqr,
+ ec_GF2m_simple_field_div,
+ 0 /* field_encode */,
+ 0 /* field_decode */,
+ 0 /* field_set_to_one */ };
+
+ return &ret;
+ }
+
+
+/* Initialize a GF(2^m)-based EC_GROUP structure.
+ * Note that all other members are handled by EC_GROUP_new.
+ */
+int ec_GF2m_simple_group_init(EC_GROUP *group)
+ {
+ BN_init(&group->field);
+ BN_init(&group->a);
+ BN_init(&group->b);
+ return 1;
+ }
+
+
+/* Free a GF(2^m)-based EC_GROUP structure.
+ * Note that all other members are handled by EC_GROUP_free.
+ */
+void ec_GF2m_simple_group_finish(EC_GROUP *group)
+ {
+ BN_free(&group->field);
+ BN_free(&group->a);
+ BN_free(&group->b);
+ }
+
+
+/* Clear and free a GF(2^m)-based EC_GROUP structure.
+ * Note that all other members are handled by EC_GROUP_clear_free.
+ */
+void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
+ {
+ BN_clear_free(&group->field);
+ BN_clear_free(&group->a);
+ BN_clear_free(&group->b);
+ group->poly[0] = 0;
+ group->poly[1] = 0;
+ group->poly[2] = 0;
+ group->poly[3] = 0;
+ group->poly[4] = 0;
+ group->poly[5] = -1;
+ }
+
+
+/* Copy a GF(2^m)-based EC_GROUP structure.
+ * Note that all other members are handled by EC_GROUP_copy.
+ */
+int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+ {
+ int i;
+ if (!BN_copy(&dest->field, &src->field)) return 0;
+ if (!BN_copy(&dest->a, &src->a)) return 0;
+ if (!BN_copy(&dest->b, &src->b)) return 0;
+ dest->poly[0] = src->poly[0];
+ dest->poly[1] = src->poly[1];
+ dest->poly[2] = src->poly[2];
+ dest->poly[3] = src->poly[3];
+ dest->poly[4] = src->poly[4];
+ dest->poly[5] = src->poly[5];
+ if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
+ if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
+ for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0;
+ for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0;
+ return 1;
+ }
+
+
+/* Set the curve parameters of an EC_GROUP structure. */
+int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
+ const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+ {
+ int ret = 0, i;
+
+ /* group->field */
+ if (!BN_copy(&group->field, p)) goto err;
+ i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1;
+ if ((i != 5) && (i != 3))
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
+ goto err;
+ }
+
+ /* group->a */
+ if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err;
+ if(bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
+ for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0;
+
+ /* group->b */
+ if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err;
+ if(bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err;
+ for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0;
+
+ ret = 1;
+ err:
+ return ret;
+ }
+
+
+/* Get the curve parameters of an EC_GROUP structure.
+ * If p, a, or b are NULL then there values will not be set but the method will return with success.
+ */
+int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+ {
+ int ret = 0;
+
+ if (p != NULL)
+ {
+ if (!BN_copy(p, &group->field)) return 0;
+ }
+
+ if (a != NULL)
+ {
+ if (!BN_copy(a, &group->a)) goto err;
+ }
+
+ if (b != NULL)
+ {
+ if (!BN_copy(b, &group->b)) goto err;
+ }
+
+ ret = 1;
+
+ err:
+ return ret;
+ }
+
+
+/* Gets the degree of the field. For a curve over GF(2^m) this is the value m. */
+int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
+ {
+ return BN_num_bits(&group->field)-1;
+ }
+
+
+/* Checks the discriminant of the curve.
+ * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
+ */
+int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
+ {
+ int ret = 0;
+ BIGNUM *b;
+ BN_CTX *new_ctx = NULL;
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ BN_CTX_start(ctx);
+ b = BN_CTX_get(ctx);
+ if (b == NULL) goto err;
+
+ if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) goto err;
+
+ /* check the discriminant:
+ * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
+ */
+ if (BN_is_zero(b)) goto err;
+
+ ret = 1;
+
+err:
+ if (ctx != NULL)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+/* Initializes an EC_POINT. */
+int ec_GF2m_simple_point_init(EC_POINT *point)
+ {
+ BN_init(&point->X);
+ BN_init(&point->Y);
+ BN_init(&point->Z);
+ return 1;
+ }
+
+
+/* Frees an EC_POINT. */
+void ec_GF2m_simple_point_finish(EC_POINT *point)
+ {
+ BN_free(&point->X);
+ BN_free(&point->Y);
+ BN_free(&point->Z);
+ }
+
+
+/* Clears and frees an EC_POINT. */
+void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
+ {
+ BN_clear_free(&point->X);
+ BN_clear_free(&point->Y);
+ BN_clear_free(&point->Z);
+ point->Z_is_one = 0;
+ }
+
+
+/* Copy the contents of one EC_POINT into another. Assumes dest is initialized. */
+int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
+ {
+ if (!BN_copy(&dest->X, &src->X)) return 0;
+ if (!BN_copy(&dest->Y, &src->Y)) return 0;
+ if (!BN_copy(&dest->Z, &src->Z)) return 0;
+ dest->Z_is_one = src->Z_is_one;
+
+ return 1;
+ }
+
+
+/* Set an EC_POINT to the point at infinity.
+ * A point at infinity is represented by having Z=0.
+ */
+int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
+ {
+ point->Z_is_one = 0;
+ BN_zero(&point->Z);
+ return 1;
+ }
+
+
+/* Set the coordinates of an EC_POINT using affine coordinates.
+ * Note that the simple implementation only uses affine coordinates.
+ */
+int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
+ const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
+ {
+ int ret = 0;
+ if (x == NULL || y == NULL)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (!BN_copy(&point->X, x)) goto err;
+ BN_set_negative(&point->X, 0);
+ if (!BN_copy(&point->Y, y)) goto err;
+ BN_set_negative(&point->Y, 0);
+ if (!BN_copy(&point->Z, BN_value_one())) goto err;
+ BN_set_negative(&point->Z, 0);
+ point->Z_is_one = 1;
+ ret = 1;
+
+ err:
+ return ret;
+ }
+
+
+/* Gets the affine coordinates of an EC_POINT.
+ * Note that the simple implementation only uses affine coordinates.
+ */
+int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
+ {
+ int ret = 0;
+
+ if (EC_POINT_is_at_infinity(group, point))
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ if (BN_cmp(&point->Z, BN_value_one()))
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (x != NULL)
+ {
+ if (!BN_copy(x, &point->X)) goto err;
+ BN_set_negative(x, 0);
+ }
+ if (y != NULL)
+ {
+ if (!BN_copy(y, &point->Y)) goto err;
+ BN_set_negative(y, 0);
+ }
+ ret = 1;
+
+ err:
+ return ret;
+ }
+
+
+/* Calculates and sets the affine coordinates of an EC_POINT from the given
+ * compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
+ * Note that the simple implementation only uses affine coordinates.
+ *
+ * The method is from the following publication:
+ *
+ * Harper, Menezes, Vanstone:
+ * "Public-Key Cryptosystems with Very Small Key Lengths",
+ * EUROCRYPT '92, Springer-Verlag LNCS 658,
+ * published February 1993
+ *
+ * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
+ * the same method, but claim no priority date earlier than July 29, 1994
+ * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
+ */
+int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
+ const BIGNUM *x_, int y_bit, BN_CTX *ctx)
+ {
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp, *x, *y, *z;
+ int ret = 0, z0;
+
+ /* clear error queue */
+ ERR_clear_error();
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ y_bit = (y_bit != 0) ? 1 : 0;
+
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ z = BN_CTX_get(ctx);
+ if (z == NULL) goto err;
+
+ if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
+ if (BN_is_zero(x))
+ {
+ if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
+ }
+ else
+ {
+ if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
+ if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
+ if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
+ if (!BN_GF2m_add(tmp, x, tmp)) goto err;
+ if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
+ {
+ unsigned long err = ERR_peek_last_error();
+
+ if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
+ {
+ ERR_clear_error();
+ ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+ }
+ else
+ ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
+ goto err;
+ }
+ z0 = (BN_is_odd(z)) ? 1 : 0;
+ if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
+ if (z0 != y_bit)
+ {
+ if (!BN_GF2m_add(y, y, x)) goto err;
+ }
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+/* Converts an EC_POINT to an octet string.
+ * If buf is NULL, the encoded length will be returned.
+ * If the length len of buf is smaller than required an error will be returned.
+ */
+size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
+ unsigned char *buf, size_t len, BN_CTX *ctx)
+ {
+ size_t ret;
+ BN_CTX *new_ctx = NULL;
+ int used_ctx = 0;
+ BIGNUM *x, *y, *yxi;
+ size_t field_len, i, skip;
+
+ if ((form != POINT_CONVERSION_COMPRESSED)
+ && (form != POINT_CONVERSION_UNCOMPRESSED)
+ && (form != POINT_CONVERSION_HYBRID))
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
+ goto err;
+ }
+
+ if (EC_POINT_is_at_infinity(group, point))
+ {
+ /* encodes to a single 0 octet */
+ if (buf != NULL)
+ {
+ if (len < 1)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ buf[0] = 0;
+ }
+ return 1;
+ }
+
+
+ /* ret := required output buffer length */
+ field_len = (EC_GROUP_get_degree(group) + 7) / 8;
+ ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
+
+ /* if 'buf' is NULL, just return required length */
+ if (buf != NULL)
+ {
+ if (len < ret)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ goto err;
+ }
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ used_ctx = 1;
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ yxi = BN_CTX_get(ctx);
+ if (yxi == NULL) goto err;
+
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+
+ buf[0] = form;
+ if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
+ {
+ if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
+ if (BN_is_odd(yxi)) buf[0]++;
+ }
+
+ i = 1;
+
+ skip = field_len - BN_num_bytes(x);
+ if (skip > field_len)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ while (skip > 0)
+ {
+ buf[i++] = 0;
+ skip--;
+ }
+ skip = BN_bn2bin(x, buf + i);
+ i += skip;
+ if (i != 1 + field_len)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
+ {
+ skip = field_len - BN_num_bytes(y);
+ if (skip > field_len)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ while (skip > 0)
+ {
+ buf[i++] = 0;
+ skip--;
+ }
+ skip = BN_bn2bin(y, buf + i);
+ i += skip;
+ }
+
+ if (i != ret)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ if (used_ctx)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+
+ err:
+ if (used_ctx)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return 0;
+ }
+
+
+/* Converts an octet string representation to an EC_POINT.
+ * Note that the simple implementation only uses affine coordinates.
+ */
+int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
+ const unsigned char *buf, size_t len, BN_CTX *ctx)
+ {
+ point_conversion_form_t form;
+ int y_bit;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y, *yxi;
+ size_t field_len, enc_len;
+ int ret = 0;
+
+ if (len == 0)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ form = buf[0];
+ y_bit = form & 1;
+ form = form & ~1U;
+ if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
+ && (form != POINT_CONVERSION_UNCOMPRESSED)
+ && (form != POINT_CONVERSION_HYBRID))
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+ if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ if (form == 0)
+ {
+ if (len != 1)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ return EC_POINT_set_to_infinity(group, point);
+ }
+
+ field_len = (EC_GROUP_get_degree(group) + 7) / 8;
+ enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
+
+ if (len != enc_len)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ yxi = BN_CTX_get(ctx);
+ if (yxi == NULL) goto err;
+
+ if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
+ if (BN_ucmp(x, &group->field) >= 0)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+
+ if (form == POINT_CONVERSION_COMPRESSED)
+ {
+ if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
+ if (BN_ucmp(y, &group->field) >= 0)
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+ if (form == POINT_CONVERSION_HYBRID)
+ {
+ if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
+ if (y_bit != BN_is_odd(yxi))
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+ }
+
+ if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
+ {
+ ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
+ goto err;
+ }
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+/* Computes a + b and stores the result in r. r could be a or b, a could be b.
+ * Uses algorithm A.10.2 of IEEE P1363.
+ */
+int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
+ {
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
+ int ret = 0;
+
+ if (EC_POINT_is_at_infinity(group, a))
+ {
+ if (!EC_POINT_copy(r, b)) return 0;
+ return 1;
+ }
+
+ if (EC_POINT_is_at_infinity(group, b))
+ {
+ if (!EC_POINT_copy(r, a)) return 0;
+ return 1;
+ }
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ x0 = BN_CTX_get(ctx);
+ y0 = BN_CTX_get(ctx);
+ x1 = BN_CTX_get(ctx);
+ y1 = BN_CTX_get(ctx);
+ x2 = BN_CTX_get(ctx);
+ y2 = BN_CTX_get(ctx);
+ s = BN_CTX_get(ctx);
+ t = BN_CTX_get(ctx);
+ if (t == NULL) goto err;
+
+ if (a->Z_is_one)
+ {
+ if (!BN_copy(x0, &a->X)) goto err;
+ if (!BN_copy(y0, &a->Y)) goto err;
+ }
+ else
+ {
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err;
+ }
+ if (b->Z_is_one)
+ {
+ if (!BN_copy(x1, &b->X)) goto err;
+ if (!BN_copy(y1, &b->Y)) goto err;
+ }
+ else
+ {
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err;
+ }
+
+
+ if (BN_GF2m_cmp(x0, x1))
+ {
+ if (!BN_GF2m_add(t, x0, x1)) goto err;
+ if (!BN_GF2m_add(s, y0, y1)) goto err;
+ if (!group->meth->field_div(group, s, s, t, ctx)) goto err;
+ if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
+ if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
+ if (!BN_GF2m_add(x2, x2, s)) goto err;
+ if (!BN_GF2m_add(x2, x2, t)) goto err;
+ }
+ else
+ {
+ if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1))
+ {
+ if (!EC_POINT_set_to_infinity(group, r)) goto err;
+ ret = 1;
+ goto err;
+ }
+ if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err;
+ if (!BN_GF2m_add(s, s, x1)) goto err;
+
+ if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
+ if (!BN_GF2m_add(x2, x2, s)) goto err;
+ if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
+ }
+
+ if (!BN_GF2m_add(y2, x1, x2)) goto err;
+ if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err;
+ if (!BN_GF2m_add(y2, y2, x2)) goto err;
+ if (!BN_GF2m_add(y2, y2, y1)) goto err;
+
+ if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err;
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+/* Computes 2 * a and stores the result in r. r could be a.
+ * Uses algorithm A.10.2 of IEEE P1363.
+ */
+int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
+ {
+ return ec_GF2m_simple_add(group, r, a, a, ctx);
+ }
+
+
+int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+ {
+ if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
+ /* point is its own inverse */
+ return 1;
+
+ if (!EC_POINT_make_affine(group, point, ctx)) return 0;
+ return BN_GF2m_add(&point->Y, &point->X, &point->Y);
+ }
+
+
+/* Indicates whether the given point is the point at infinity. */
+int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
+ {
+ return BN_is_zero(&point->Z);
+ }
+
+
+/* Determines whether the given EC_POINT is an actual point on the curve defined
+ * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation:
+ * y^2 + x*y = x^3 + a*x^2 + b.
+ */
+int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
+ {
+ int ret = -1;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *lh, *y2;
+ int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+ int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+
+ if (EC_POINT_is_at_infinity(group, point))
+ return 1;
+
+ field_mul = group->meth->field_mul;
+ field_sqr = group->meth->field_sqr;
+
+ /* only support affine coordinates */
+ if (!point->Z_is_one) goto err;
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return -1;
+ }
+
+ BN_CTX_start(ctx);
+ y2 = BN_CTX_get(ctx);
+ lh = BN_CTX_get(ctx);
+ if (lh == NULL) goto err;
+
+ /* We have a curve defined by a Weierstrass equation
+ * y^2 + x*y = x^3 + a*x^2 + b.
+ * <=> x^3 + a*x^2 + x*y + b + y^2 = 0
+ * <=> ((x + a) * x + y ) * x + b + y^2 = 0
+ */
+ if (!BN_GF2m_add(lh, &point->X, &group->a)) goto err;
+ if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
+ if (!BN_GF2m_add(lh, lh, &point->Y)) goto err;
+ if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
+ if (!BN_GF2m_add(lh, lh, &group->b)) goto err;
+ if (!field_sqr(group, y2, &point->Y, ctx)) goto err;
+ if (!BN_GF2m_add(lh, lh, y2)) goto err;
+ ret = BN_is_zero(lh);
+ err:
+ if (ctx) BN_CTX_end(ctx);
+ if (new_ctx) BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+/* Indicates whether two points are equal.
+ * Return values:
+ * -1 error
+ * 0 equal (in affine coordinates)
+ * 1 not equal
+ */
+int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
+ {
+ BIGNUM *aX, *aY, *bX, *bY;
+ BN_CTX *new_ctx = NULL;
+ int ret = -1;
+
+ if (EC_POINT_is_at_infinity(group, a))
+ {
+ return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
+ }
+
+ if (EC_POINT_is_at_infinity(group, b))
+ return 1;
+
+ if (a->Z_is_one && b->Z_is_one)
+ {
+ return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
+ }
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return -1;
+ }
+
+ BN_CTX_start(ctx);
+ aX = BN_CTX_get(ctx);
+ aY = BN_CTX_get(ctx);
+ bX = BN_CTX_get(ctx);
+ bY = BN_CTX_get(ctx);
+ if (bY == NULL) goto err;
+
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) goto err;
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) goto err;
+ ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
+
+ err:
+ if (ctx) BN_CTX_end(ctx);
+ if (new_ctx) BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+/* Forces the given EC_POINT to internally use affine coordinates. */
+int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+ {
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y;
+ int ret = 0;
+
+ if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
+ return 1;
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (y == NULL) goto err;
+
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+ if (!BN_copy(&point->X, x)) goto err;
+ if (!BN_copy(&point->Y, y)) goto err;
+ if (!BN_one(&point->Z)) goto err;
+
+ ret = 1;
+
+ err:
+ if (ctx) BN_CTX_end(ctx);
+ if (new_ctx) BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+/* Forces each of the EC_POINTs in the given array to use affine coordinates. */
+int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
+ {
+ size_t i;
+
+ for (i = 0; i < num; i++)
+ {
+ if (!group->meth->make_affine(group, points[i], ctx)) return 0;
+ }
+
+ return 1;
+ }
+
+
+/* Wrapper to simple binary polynomial field multiplication implementation. */
+int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+ {
+ return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
+ }
+
+
+/* Wrapper to simple binary polynomial field squaring implementation. */
+int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
+ {
+ return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
+ }
+
+
+/* Wrapper to simple binary polynomial field division implementation. */
+int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+ {
+ return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
+ }
diff --git a/openssl/crypto/ec/ec_key.c b/openssl/crypto/ec/ec_key.c
index 0458d340b..522802c07 100644
--- a/openssl/crypto/ec/ec_key.c
+++ b/openssl/crypto/ec/ec_key.c
@@ -1,463 +1,463 @@
-/* crypto/ec/ec_key.c */
-/*
- * Written by Nils Larsch for the OpenSSL project.
- */
-/* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- * Portions originally developed by SUN MICROSYSTEMS, INC., and
- * contributed to the OpenSSL project.
- */
-
-#include <string.h>
-#include "ec_lcl.h"
-#include <openssl/err.h>
-#include <string.h>
-
-EC_KEY *EC_KEY_new(void)
- {
- EC_KEY *ret;
-
- ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
- if (ret == NULL)
- {
- ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);
- return(NULL);
- }
-
- ret->version = 1;
- ret->group = NULL;
- ret->pub_key = NULL;
- ret->priv_key= NULL;
- ret->enc_flag= 0;
- ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
- ret->references= 1;
- ret->method_data = NULL;
- return(ret);
- }
-
-EC_KEY *EC_KEY_new_by_curve_name(int nid)
- {
- EC_KEY *ret = EC_KEY_new();
- if (ret == NULL)
- return NULL;
- ret->group = EC_GROUP_new_by_curve_name(nid);
- if (ret->group == NULL)
- {
- EC_KEY_free(ret);
- return NULL;
- }
- return ret;
- }
-
-void EC_KEY_free(EC_KEY *r)
- {
- int i;
-
- if (r == NULL) return;
-
- i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC);
-#ifdef REF_PRINT
- REF_PRINT("EC_KEY",r);
-#endif
- if (i > 0) return;
-#ifdef REF_CHECK
- if (i < 0)
- {
- fprintf(stderr,"EC_KEY_free, bad reference count\n");
- abort();
- }
-#endif
-
- if (r->group != NULL)
- EC_GROUP_free(r->group);
- if (r->pub_key != NULL)
- EC_POINT_free(r->pub_key);
- if (r->priv_key != NULL)
- BN_clear_free(r->priv_key);
-
- EC_EX_DATA_free_all_data(&r->method_data);
-
- OPENSSL_cleanse((void *)r, sizeof(EC_KEY));
-
- OPENSSL_free(r);
- }
-
-EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
- {
- EC_EXTRA_DATA *d;
-
- if (dest == NULL || src == NULL)
- {
- ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
- return NULL;
- }
- /* copy the parameters */
- if (src->group)
- {
- const EC_METHOD *meth = EC_GROUP_method_of(src->group);
- /* clear the old group */
- if (dest->group)
- EC_GROUP_free(dest->group);
- dest->group = EC_GROUP_new(meth);
- if (dest->group == NULL)
- return NULL;
- if (!EC_GROUP_copy(dest->group, src->group))
- return NULL;
- }
- /* copy the public key */
- if (src->pub_key && src->group)
- {
- if (dest->pub_key)
- EC_POINT_free(dest->pub_key);
- dest->pub_key = EC_POINT_new(src->group);
- if (dest->pub_key == NULL)
- return NULL;
- if (!EC_POINT_copy(dest->pub_key, src->pub_key))
- return NULL;
- }
- /* copy the private key */
- if (src->priv_key)
- {
- if (dest->priv_key == NULL)
- {
- dest->priv_key = BN_new();
- if (dest->priv_key == NULL)
- return NULL;
- }
- if (!BN_copy(dest->priv_key, src->priv_key))
- return NULL;
- }
- /* copy method/extra data */
- EC_EX_DATA_free_all_data(&dest->method_data);
-
- for (d = src->method_data; d != NULL; d = d->next)
- {
- void *t = d->dup_func(d->data);
-
- if (t == NULL)
- return 0;
- if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, d->free_func, d->clear_free_func))
- return 0;
- }
-
- /* copy the rest */
- dest->enc_flag = src->enc_flag;
- dest->conv_form = src->conv_form;
- dest->version = src->version;
-
- return dest;
- }
-
-EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
- {
- EC_KEY *ret = EC_KEY_new();
- if (ret == NULL)
- return NULL;
- if (EC_KEY_copy(ret, ec_key) == NULL)
- {
- EC_KEY_free(ret);
- return NULL;
- }
- return ret;
- }
-
-int EC_KEY_up_ref(EC_KEY *r)
- {
- int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
-#ifdef REF_PRINT
- REF_PRINT("EC_KEY",r);
-#endif
-#ifdef REF_CHECK
- if (i < 2)
- {
- fprintf(stderr, "EC_KEY_up, bad reference count\n");
- abort();
- }
-#endif
- return ((i > 1) ? 1 : 0);
- }
-
-int EC_KEY_generate_key(EC_KEY *eckey)
- {
- int ok = 0;
- BN_CTX *ctx = NULL;
- BIGNUM *priv_key = NULL, *order = NULL;
- EC_POINT *pub_key = NULL;
-
- if (!eckey || !eckey->group)
- {
- ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
-
- if ((order = BN_new()) == NULL) goto err;
- if ((ctx = BN_CTX_new()) == NULL) goto err;
-
- if (eckey->priv_key == NULL)
- {
- priv_key = BN_new();
- if (priv_key == NULL)
- goto err;
- }
- else
- priv_key = eckey->priv_key;
-
- if (!EC_GROUP_get_order(eckey->group, order, ctx))
- goto err;
-
- do
- if (!BN_rand_range(priv_key, order))
- goto err;
- while (BN_is_zero(priv_key));
-
- if (eckey->pub_key == NULL)
- {
- pub_key = EC_POINT_new(eckey->group);
- if (pub_key == NULL)
- goto err;
- }
- else
- pub_key = eckey->pub_key;
-
- if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
- goto err;
-
- eckey->priv_key = priv_key;
- eckey->pub_key = pub_key;
-
- ok=1;
-
-err:
- if (order)
- BN_free(order);
- if (pub_key != NULL && eckey->pub_key == NULL)
- EC_POINT_free(pub_key);
- if (priv_key != NULL && eckey->priv_key == NULL)
- BN_free(priv_key);
- if (ctx != NULL)
- BN_CTX_free(ctx);
- return(ok);
- }
-
-int EC_KEY_check_key(const EC_KEY *eckey)
- {
- int ok = 0;
- BN_CTX *ctx = NULL;
- const BIGNUM *order = NULL;
- EC_POINT *point = NULL;
-
- if (!eckey || !eckey->group || !eckey->pub_key)
- {
- ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
-
- if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key))
- {
- ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
- goto err;
- }
-
- if ((ctx = BN_CTX_new()) == NULL)
- goto err;
- if ((point = EC_POINT_new(eckey->group)) == NULL)
- goto err;
-
- /* testing whether the pub_key is on the elliptic curve */
- if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx))
- {
- ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
- goto err;
- }
- /* testing whether pub_key * order is the point at infinity */
- order = &eckey->group->order;
- if (BN_is_zero(order))
- {
- ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
- goto err;
- }
- if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx))
- {
- ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
- goto err;
- }
- if (!EC_POINT_is_at_infinity(eckey->group, point))
- {
- ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
- goto err;
- }
- /* in case the priv_key is present :
- * check if generator * priv_key == pub_key
- */
- if (eckey->priv_key)
- {
- if (BN_cmp(eckey->priv_key, order) >= 0)
- {
- ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
- goto err;
- }
- if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
- NULL, NULL, ctx))
- {
- ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
- goto err;
- }
- if (EC_POINT_cmp(eckey->group, point, eckey->pub_key,
- ctx) != 0)
- {
- ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
- goto err;
- }
- }
- ok = 1;
-err:
- if (ctx != NULL)
- BN_CTX_free(ctx);
- if (point != NULL)
- EC_POINT_free(point);
- return(ok);
- }
-
-const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
- {
- return key->group;
- }
-
-int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
- {
- if (key->group != NULL)
- EC_GROUP_free(key->group);
- key->group = EC_GROUP_dup(group);
- return (key->group == NULL) ? 0 : 1;
- }
-
-const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
- {
- return key->priv_key;
- }
-
-int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
- {
- if (key->priv_key)
- BN_clear_free(key->priv_key);
- key->priv_key = BN_dup(priv_key);
- return (key->priv_key == NULL) ? 0 : 1;
- }
-
-const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
- {
- return key->pub_key;
- }
-
-int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
- {
- if (key->pub_key != NULL)
- EC_POINT_free(key->pub_key);
- key->pub_key = EC_POINT_dup(pub_key, key->group);
- return (key->pub_key == NULL) ? 0 : 1;
- }
-
-unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
- {
- return key->enc_flag;
- }
-
-void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
- {
- key->enc_flag = flags;
- }
-
-point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
- {
- return key->conv_form;
- }
-
-void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
- {
- key->conv_form = cform;
- if (key->group != NULL)
- EC_GROUP_set_point_conversion_form(key->group, cform);
- }
-
-void *EC_KEY_get_key_method_data(EC_KEY *key,
- void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
- {
- return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
- }
-
-void EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
- void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
- {
- EC_EXTRA_DATA *ex_data;
- CRYPTO_w_lock(CRYPTO_LOCK_EC);
- ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
- if (ex_data == NULL)
- EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
- CRYPTO_w_unlock(CRYPTO_LOCK_EC);
- }
-
-void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
- {
- if (key->group != NULL)
- EC_GROUP_set_asn1_flag(key->group, flag);
- }
-
-int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
- {
- if (key->group == NULL)
- return 0;
- return EC_GROUP_precompute_mult(key->group, ctx);
- }
+/* crypto/ec/ec_key.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions originally developed by SUN MICROSYSTEMS, INC., and
+ * contributed to the OpenSSL project.
+ */
+
+#include <string.h>
+#include "ec_lcl.h"
+#include <openssl/err.h>
+#include <string.h>
+
+EC_KEY *EC_KEY_new(void)
+ {
+ EC_KEY *ret;
+
+ ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
+ if (ret == NULL)
+ {
+ ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+
+ ret->version = 1;
+ ret->group = NULL;
+ ret->pub_key = NULL;
+ ret->priv_key= NULL;
+ ret->enc_flag= 0;
+ ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
+ ret->references= 1;
+ ret->method_data = NULL;
+ return(ret);
+ }
+
+EC_KEY *EC_KEY_new_by_curve_name(int nid)
+ {
+ EC_KEY *ret = EC_KEY_new();
+ if (ret == NULL)
+ return NULL;
+ ret->group = EC_GROUP_new_by_curve_name(nid);
+ if (ret->group == NULL)
+ {
+ EC_KEY_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void EC_KEY_free(EC_KEY *r)
+ {
+ int i;
+
+ if (r == NULL) return;
+
+ i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC);
+#ifdef REF_PRINT
+ REF_PRINT("EC_KEY",r);
+#endif
+ if (i > 0) return;
+#ifdef REF_CHECK
+ if (i < 0)
+ {
+ fprintf(stderr,"EC_KEY_free, bad reference count\n");
+ abort();
+ }
+#endif
+
+ if (r->group != NULL)
+ EC_GROUP_free(r->group);
+ if (r->pub_key != NULL)
+ EC_POINT_free(r->pub_key);
+ if (r->priv_key != NULL)
+ BN_clear_free(r->priv_key);
+
+ EC_EX_DATA_free_all_data(&r->method_data);
+
+ OPENSSL_cleanse((void *)r, sizeof(EC_KEY));
+
+ OPENSSL_free(r);
+ }
+
+EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
+ {
+ EC_EXTRA_DATA *d;
+
+ if (dest == NULL || src == NULL)
+ {
+ ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ /* copy the parameters */
+ if (src->group)
+ {
+ const EC_METHOD *meth = EC_GROUP_method_of(src->group);
+ /* clear the old group */
+ if (dest->group)
+ EC_GROUP_free(dest->group);
+ dest->group = EC_GROUP_new(meth);
+ if (dest->group == NULL)
+ return NULL;
+ if (!EC_GROUP_copy(dest->group, src->group))
+ return NULL;
+ }
+ /* copy the public key */
+ if (src->pub_key && src->group)
+ {
+ if (dest->pub_key)
+ EC_POINT_free(dest->pub_key);
+ dest->pub_key = EC_POINT_new(src->group);
+ if (dest->pub_key == NULL)
+ return NULL;
+ if (!EC_POINT_copy(dest->pub_key, src->pub_key))
+ return NULL;
+ }
+ /* copy the private key */
+ if (src->priv_key)
+ {
+ if (dest->priv_key == NULL)
+ {
+ dest->priv_key = BN_new();
+ if (dest->priv_key == NULL)
+ return NULL;
+ }
+ if (!BN_copy(dest->priv_key, src->priv_key))
+ return NULL;
+ }
+ /* copy method/extra data */
+ EC_EX_DATA_free_all_data(&dest->method_data);
+
+ for (d = src->method_data; d != NULL; d = d->next)
+ {
+ void *t = d->dup_func(d->data);
+
+ if (t == NULL)
+ return 0;
+ if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, d->free_func, d->clear_free_func))
+ return 0;
+ }
+
+ /* copy the rest */
+ dest->enc_flag = src->enc_flag;
+ dest->conv_form = src->conv_form;
+ dest->version = src->version;
+
+ return dest;
+ }
+
+EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
+ {
+ EC_KEY *ret = EC_KEY_new();
+ if (ret == NULL)
+ return NULL;
+ if (EC_KEY_copy(ret, ec_key) == NULL)
+ {
+ EC_KEY_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+int EC_KEY_up_ref(EC_KEY *r)
+ {
+ int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
+#ifdef REF_PRINT
+ REF_PRINT("EC_KEY",r);
+#endif
+#ifdef REF_CHECK
+ if (i < 2)
+ {
+ fprintf(stderr, "EC_KEY_up, bad reference count\n");
+ abort();
+ }
+#endif
+ return ((i > 1) ? 1 : 0);
+ }
+
+int EC_KEY_generate_key(EC_KEY *eckey)
+ {
+ int ok = 0;
+ BN_CTX *ctx = NULL;
+ BIGNUM *priv_key = NULL, *order = NULL;
+ EC_POINT *pub_key = NULL;
+
+ if (!eckey || !eckey->group)
+ {
+ ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if ((order = BN_new()) == NULL) goto err;
+ if ((ctx = BN_CTX_new()) == NULL) goto err;
+
+ if (eckey->priv_key == NULL)
+ {
+ priv_key = BN_new();
+ if (priv_key == NULL)
+ goto err;
+ }
+ else
+ priv_key = eckey->priv_key;
+
+ if (!EC_GROUP_get_order(eckey->group, order, ctx))
+ goto err;
+
+ do
+ if (!BN_rand_range(priv_key, order))
+ goto err;
+ while (BN_is_zero(priv_key));
+
+ if (eckey->pub_key == NULL)
+ {
+ pub_key = EC_POINT_new(eckey->group);
+ if (pub_key == NULL)
+ goto err;
+ }
+ else
+ pub_key = eckey->pub_key;
+
+ if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
+ goto err;
+
+ eckey->priv_key = priv_key;
+ eckey->pub_key = pub_key;
+
+ ok=1;
+
+err:
+ if (order)
+ BN_free(order);
+ if (pub_key != NULL && eckey->pub_key == NULL)
+ EC_POINT_free(pub_key);
+ if (priv_key != NULL && eckey->priv_key == NULL)
+ BN_free(priv_key);
+ if (ctx != NULL)
+ BN_CTX_free(ctx);
+ return(ok);
+ }
+
+int EC_KEY_check_key(const EC_KEY *eckey)
+ {
+ int ok = 0;
+ BN_CTX *ctx = NULL;
+ const BIGNUM *order = NULL;
+ EC_POINT *point = NULL;
+
+ if (!eckey || !eckey->group || !eckey->pub_key)
+ {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key))
+ {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
+ goto err;
+ }
+
+ if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ if ((point = EC_POINT_new(eckey->group)) == NULL)
+ goto err;
+
+ /* testing whether the pub_key is on the elliptic curve */
+ if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx))
+ {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
+ goto err;
+ }
+ /* testing whether pub_key * order is the point at infinity */
+ order = &eckey->group->order;
+ if (BN_is_zero(order))
+ {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
+ goto err;
+ }
+ if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx))
+ {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (!EC_POINT_is_at_infinity(eckey->group, point))
+ {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
+ goto err;
+ }
+ /* in case the priv_key is present :
+ * check if generator * priv_key == pub_key
+ */
+ if (eckey->priv_key)
+ {
+ if (BN_cmp(eckey->priv_key, order) >= 0)
+ {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
+ goto err;
+ }
+ if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
+ NULL, NULL, ctx))
+ {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (EC_POINT_cmp(eckey->group, point, eckey->pub_key,
+ ctx) != 0)
+ {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
+ goto err;
+ }
+ }
+ ok = 1;
+err:
+ if (ctx != NULL)
+ BN_CTX_free(ctx);
+ if (point != NULL)
+ EC_POINT_free(point);
+ return(ok);
+ }
+
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
+ {
+ return key->group;
+ }
+
+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
+ {
+ if (key->group != NULL)
+ EC_GROUP_free(key->group);
+ key->group = EC_GROUP_dup(group);
+ return (key->group == NULL) ? 0 : 1;
+ }
+
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
+ {
+ return key->priv_key;
+ }
+
+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
+ {
+ if (key->priv_key)
+ BN_clear_free(key->priv_key);
+ key->priv_key = BN_dup(priv_key);
+ return (key->priv_key == NULL) ? 0 : 1;
+ }
+
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
+ {
+ return key->pub_key;
+ }
+
+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
+ {
+ if (key->pub_key != NULL)
+ EC_POINT_free(key->pub_key);
+ key->pub_key = EC_POINT_dup(pub_key, key->group);
+ return (key->pub_key == NULL) ? 0 : 1;
+ }
+
+unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
+ {
+ return key->enc_flag;
+ }
+
+void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
+ {
+ key->enc_flag = flags;
+ }
+
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
+ {
+ return key->conv_form;
+ }
+
+void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
+ {
+ key->conv_form = cform;
+ if (key->group != NULL)
+ EC_GROUP_set_point_conversion_form(key->group, cform);
+ }
+
+void *EC_KEY_get_key_method_data(EC_KEY *key,
+ void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
+ {
+ return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+ }
+
+void EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
+ void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
+ {
+ EC_EXTRA_DATA *ex_data;
+ CRYPTO_w_lock(CRYPTO_LOCK_EC);
+ ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+ if (ex_data == NULL)
+ EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
+ CRYPTO_w_unlock(CRYPTO_LOCK_EC);
+ }
+
+void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
+ {
+ if (key->group != NULL)
+ EC_GROUP_set_asn1_flag(key->group, flag);
+ }
+
+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
+ {
+ if (key->group == NULL)
+ return 0;
+ return EC_GROUP_precompute_mult(key->group, ctx);
+ }
diff --git a/openssl/crypto/ec/ecp_smpl.c b/openssl/crypto/ec/ecp_smpl.c
index 766f5fc51..66a92e2a9 100644
--- a/openssl/crypto/ec/ecp_smpl.c
+++ b/openssl/crypto/ec/ecp_smpl.c
@@ -1,1719 +1,1719 @@
-/* crypto/ec/ecp_smpl.c */
-/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
- * for the OpenSSL project.
- * Includes code written by Bodo Moeller for the OpenSSL project.
-*/
-/* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- * Portions of this software developed by SUN MICROSYSTEMS, INC.,
- * and contributed to the OpenSSL project.
- */
-
-#include <openssl/err.h>
-#include <openssl/symhacks.h>
-
-#include "ec_lcl.h"
-
-const EC_METHOD *EC_GFp_simple_method(void)
- {
- static const EC_METHOD ret = {
- NID_X9_62_prime_field,
- ec_GFp_simple_group_init,
- ec_GFp_simple_group_finish,
- ec_GFp_simple_group_clear_finish,
- ec_GFp_simple_group_copy,
- ec_GFp_simple_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
- ec_GFp_simple_point_get_affine_coordinates,
- ec_GFp_simple_set_compressed_coordinates,
- ec_GFp_simple_point2oct,
- ec_GFp_simple_oct2point,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
- 0 /* mul */,
- 0 /* precompute_mult */,
- 0 /* have_precompute_mult */,
- ec_GFp_simple_field_mul,
- ec_GFp_simple_field_sqr,
- 0 /* field_div */,
- 0 /* field_encode */,
- 0 /* field_decode */,
- 0 /* field_set_to_one */ };
-
- return &ret;
- }
-
-
-/* Most method functions in this file are designed to work with
- * non-trivial representations of field elements if necessary
- * (see ecp_mont.c): while standard modular addition and subtraction
- * are used, the field_mul and field_sqr methods will be used for
- * multiplication, and field_encode and field_decode (if defined)
- * will be used for converting between representations.
-
- * Functions ec_GFp_simple_points_make_affine() and
- * ec_GFp_simple_point_get_affine_coordinates() specifically assume
- * that if a non-trivial representation is used, it is a Montgomery
- * representation (i.e. 'encoding' means multiplying by some factor R).
- */
-
-
-int ec_GFp_simple_group_init(EC_GROUP *group)
- {
- BN_init(&group->field);
- BN_init(&group->a);
- BN_init(&group->b);
- group->a_is_minus3 = 0;
- return 1;
- }
-
-
-void ec_GFp_simple_group_finish(EC_GROUP *group)
- {
- BN_free(&group->field);
- BN_free(&group->a);
- BN_free(&group->b);
- }
-
-
-void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
- {
- BN_clear_free(&group->field);
- BN_clear_free(&group->a);
- BN_clear_free(&group->b);
- }
-
-
-int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
- {
- if (!BN_copy(&dest->field, &src->field)) return 0;
- if (!BN_copy(&dest->a, &src->a)) return 0;
- if (!BN_copy(&dest->b, &src->b)) return 0;
-
- dest->a_is_minus3 = src->a_is_minus3;
-
- return 1;
- }
-
-
-int ec_GFp_simple_group_set_curve(EC_GROUP *group,
- const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
- {
- int ret = 0;
- BN_CTX *new_ctx = NULL;
- BIGNUM *tmp_a;
-
- /* p must be a prime > 3 */
- if (BN_num_bits(p) <= 2 || !BN_is_odd(p))
- {
- ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
- return 0;
- }
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- tmp_a = BN_CTX_get(ctx);
- if (tmp_a == NULL) goto err;
-
- /* group->field */
- if (!BN_copy(&group->field, p)) goto err;
- BN_set_negative(&group->field, 0);
-
- /* group->a */
- if (!BN_nnmod(tmp_a, a, p, ctx)) goto err;
- if (group->meth->field_encode)
- { if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) goto err; }
- else
- if (!BN_copy(&group->a, tmp_a)) goto err;
-
- /* group->b */
- if (!BN_nnmod(&group->b, b, p, ctx)) goto err;
- if (group->meth->field_encode)
- if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) goto err;
-
- /* group->a_is_minus3 */
- if (!BN_add_word(tmp_a, 3)) goto err;
- group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
- {
- int ret = 0;
- BN_CTX *new_ctx = NULL;
-
- if (p != NULL)
- {
- if (!BN_copy(p, &group->field)) return 0;
- }
-
- if (a != NULL || b != NULL)
- {
- if (group->meth->field_decode)
- {
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
- if (a != NULL)
- {
- if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
- }
- if (b != NULL)
- {
- if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
- }
- }
- else
- {
- if (a != NULL)
- {
- if (!BN_copy(a, &group->a)) goto err;
- }
- if (b != NULL)
- {
- if (!BN_copy(b, &group->b)) goto err;
- }
- }
- }
-
- ret = 1;
-
- err:
- if (new_ctx)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
- {
- return BN_num_bits(&group->field);
- }
-
-
-int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
- {
- int ret = 0;
- BIGNUM *a,*b,*order,*tmp_1,*tmp_2;
- const BIGNUM *p = &group->field;
- BN_CTX *new_ctx = NULL;
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- BN_CTX_start(ctx);
- a = BN_CTX_get(ctx);
- b = BN_CTX_get(ctx);
- tmp_1 = BN_CTX_get(ctx);
- tmp_2 = BN_CTX_get(ctx);
- order = BN_CTX_get(ctx);
- if (order == NULL) goto err;
-
- if (group->meth->field_decode)
- {
- if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
- if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
- }
- else
- {
- if (!BN_copy(a, &group->a)) goto err;
- if (!BN_copy(b, &group->b)) goto err;
- }
-
- /* check the discriminant:
- * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
- * 0 =< a, b < p */
- if (BN_is_zero(a))
- {
- if (BN_is_zero(b)) goto err;
- }
- else if (!BN_is_zero(b))
- {
- if (!BN_mod_sqr(tmp_1, a, p, ctx)) goto err;
- if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) goto err;
- if (!BN_lshift(tmp_1, tmp_2, 2)) goto err;
- /* tmp_1 = 4*a^3 */
-
- if (!BN_mod_sqr(tmp_2, b, p, ctx)) goto err;
- if (!BN_mul_word(tmp_2, 27)) goto err;
- /* tmp_2 = 27*b^2 */
-
- if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) goto err;
- if (BN_is_zero(a)) goto err;
- }
- ret = 1;
-
-err:
- if (ctx != NULL)
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-int ec_GFp_simple_point_init(EC_POINT *point)
- {
- BN_init(&point->X);
- BN_init(&point->Y);
- BN_init(&point->Z);
- point->Z_is_one = 0;
-
- return 1;
- }
-
-
-void ec_GFp_simple_point_finish(EC_POINT *point)
- {
- BN_free(&point->X);
- BN_free(&point->Y);
- BN_free(&point->Z);
- }
-
-
-void ec_GFp_simple_point_clear_finish(EC_POINT *point)
- {
- BN_clear_free(&point->X);
- BN_clear_free(&point->Y);
- BN_clear_free(&point->Z);
- point->Z_is_one = 0;
- }
-
-
-int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
- {
- if (!BN_copy(&dest->X, &src->X)) return 0;
- if (!BN_copy(&dest->Y, &src->Y)) return 0;
- if (!BN_copy(&dest->Z, &src->Z)) return 0;
- dest->Z_is_one = src->Z_is_one;
-
- return 1;
- }
-
-
-int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
- {
- point->Z_is_one = 0;
- BN_zero(&point->Z);
- return 1;
- }
-
-
-int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
- const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
- {
- BN_CTX *new_ctx = NULL;
- int ret = 0;
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- if (x != NULL)
- {
- if (!BN_nnmod(&point->X, x, &group->field, ctx)) goto err;
- if (group->meth->field_encode)
- {
- if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) goto err;
- }
- }
-
- if (y != NULL)
- {
- if (!BN_nnmod(&point->Y, y, &group->field, ctx)) goto err;
- if (group->meth->field_encode)
- {
- if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) goto err;
- }
- }
-
- if (z != NULL)
- {
- int Z_is_one;
-
- if (!BN_nnmod(&point->Z, z, &group->field, ctx)) goto err;
- Z_is_one = BN_is_one(&point->Z);
- if (group->meth->field_encode)
- {
- if (Z_is_one && (group->meth->field_set_to_one != 0))
- {
- if (!group->meth->field_set_to_one(group, &point->Z, ctx)) goto err;
- }
- else
- {
- if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx)) goto err;
- }
- }
- point->Z_is_one = Z_is_one;
- }
-
- ret = 1;
-
- err:
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
- BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
- {
- BN_CTX *new_ctx = NULL;
- int ret = 0;
-
- if (group->meth->field_decode != 0)
- {
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- if (x != NULL)
- {
- if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
- }
- if (y != NULL)
- {
- if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
- }
- if (z != NULL)
- {
- if (!group->meth->field_decode(group, z, &point->Z, ctx)) goto err;
- }
- }
- else
- {
- if (x != NULL)
- {
- if (!BN_copy(x, &point->X)) goto err;
- }
- if (y != NULL)
- {
- if (!BN_copy(y, &point->Y)) goto err;
- }
- if (z != NULL)
- {
- if (!BN_copy(z, &point->Z)) goto err;
- }
- }
-
- ret = 1;
-
- err:
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
- const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
- {
- if (x == NULL || y == NULL)
- {
- /* unlike for projective coordinates, we do not tolerate this */
- ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
-
- return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, BN_value_one(), ctx);
- }
-
-
-int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
- BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
- {
- BN_CTX *new_ctx = NULL;
- BIGNUM *Z, *Z_1, *Z_2, *Z_3;
- const BIGNUM *Z_;
- int ret = 0;
-
- if (EC_POINT_is_at_infinity(group, point))
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
- return 0;
- }
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- Z = BN_CTX_get(ctx);
- Z_1 = BN_CTX_get(ctx);
- Z_2 = BN_CTX_get(ctx);
- Z_3 = BN_CTX_get(ctx);
- if (Z_3 == NULL) goto err;
-
- /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
-
- if (group->meth->field_decode)
- {
- if (!group->meth->field_decode(group, Z, &point->Z, ctx)) goto err;
- Z_ = Z;
- }
- else
- {
- Z_ = &point->Z;
- }
-
- if (BN_is_one(Z_))
- {
- if (group->meth->field_decode)
- {
- if (x != NULL)
- {
- if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
- }
- if (y != NULL)
- {
- if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
- }
- }
- else
- {
- if (x != NULL)
- {
- if (!BN_copy(x, &point->X)) goto err;
- }
- if (y != NULL)
- {
- if (!BN_copy(y, &point->Y)) goto err;
- }
- }
- }
- else
- {
- if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx))
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
- goto err;
- }
-
- if (group->meth->field_encode == 0)
- {
- /* field_sqr works on standard representation */
- if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) goto err;
- }
- else
- {
- if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) goto err;
- }
-
- if (x != NULL)
- {
- /* in the Montgomery case, field_mul will cancel out Montgomery factor in X: */
- if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) goto err;
- }
-
- if (y != NULL)
- {
- if (group->meth->field_encode == 0)
- {
- /* field_mul works on standard representation */
- if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) goto err;
- }
- else
- {
- if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err;
- }
-
- /* in the Montgomery case, field_mul will cancel out Montgomery factor in Y: */
- if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) goto err;
- }
- }
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
- const BIGNUM *x_, int y_bit, BN_CTX *ctx)
- {
- BN_CTX *new_ctx = NULL;
- BIGNUM *tmp1, *tmp2, *x, *y;
- int ret = 0;
-
- /* clear error queue*/
- ERR_clear_error();
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- y_bit = (y_bit != 0);
-
- BN_CTX_start(ctx);
- tmp1 = BN_CTX_get(ctx);
- tmp2 = BN_CTX_get(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- if (y == NULL) goto err;
-
- /* Recover y. We have a Weierstrass equation
- * y^2 = x^3 + a*x + b,
- * so y is one of the square roots of x^3 + a*x + b.
- */
-
- /* tmp1 := x^3 */
- if (!BN_nnmod(x, x_, &group->field,ctx)) goto err;
- if (group->meth->field_decode == 0)
- {
- /* field_{sqr,mul} work on standard representation */
- if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err;
- if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err;
- }
- else
- {
- if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err;
- if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err;
- }
-
- /* tmp1 := tmp1 + a*x */
- if (group->a_is_minus3)
- {
- if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err;
- if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err;
- if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
- }
- else
- {
- if (group->meth->field_decode)
- {
- if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err;
- if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err;
- }
- else
- {
- /* field_mul works on standard representation */
- if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err;
- }
-
- if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
- }
-
- /* tmp1 := tmp1 + b */
- if (group->meth->field_decode)
- {
- if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err;
- if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
- }
- else
- {
- if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err;
- }
-
- if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))
- {
- unsigned long err = ERR_peek_last_error();
-
- if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)
- {
- ERR_clear_error();
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
- }
- else
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
- goto err;
- }
-
- if (y_bit != BN_is_odd(y))
- {
- if (BN_is_zero(y))
- {
- int kron;
-
- kron = BN_kronecker(x, &group->field, ctx);
- if (kron == -2) goto err;
-
- if (kron == 1)
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
- else
- /* BN_mod_sqrt() should have cought this error (not a square) */
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
- goto err;
- }
- if (!BN_usub(y, &group->field, y)) goto err;
- }
- if (y_bit != BN_is_odd(y))
- {
- ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
- unsigned char *buf, size_t len, BN_CTX *ctx)
- {
- size_t ret;
- BN_CTX *new_ctx = NULL;
- int used_ctx = 0;
- BIGNUM *x, *y;
- size_t field_len, i, skip;
-
- if ((form != POINT_CONVERSION_COMPRESSED)
- && (form != POINT_CONVERSION_UNCOMPRESSED)
- && (form != POINT_CONVERSION_HYBRID))
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
- goto err;
- }
-
- if (EC_POINT_is_at_infinity(group, point))
- {
- /* encodes to a single 0 octet */
- if (buf != NULL)
- {
- if (len < 1)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
- return 0;
- }
- buf[0] = 0;
- }
- return 1;
- }
-
-
- /* ret := required output buffer length */
- field_len = BN_num_bytes(&group->field);
- ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
-
- /* if 'buf' is NULL, just return required length */
- if (buf != NULL)
- {
- if (len < ret)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
- goto err;
- }
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- used_ctx = 1;
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- if (y == NULL) goto err;
-
- if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
-
- if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
- buf[0] = form + 1;
- else
- buf[0] = form;
-
- i = 1;
-
- skip = field_len - BN_num_bytes(x);
- if (skip > field_len)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- while (skip > 0)
- {
- buf[i++] = 0;
- skip--;
- }
- skip = BN_bn2bin(x, buf + i);
- i += skip;
- if (i != 1 + field_len)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
- {
- skip = field_len - BN_num_bytes(y);
- if (skip > field_len)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- while (skip > 0)
- {
- buf[i++] = 0;
- skip--;
- }
- skip = BN_bn2bin(y, buf + i);
- i += skip;
- }
-
- if (i != ret)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- }
-
- if (used_ctx)
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
-
- err:
- if (used_ctx)
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return 0;
- }
-
-
-int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
- const unsigned char *buf, size_t len, BN_CTX *ctx)
- {
- point_conversion_form_t form;
- int y_bit;
- BN_CTX *new_ctx = NULL;
- BIGNUM *x, *y;
- size_t field_len, enc_len;
- int ret = 0;
-
- if (len == 0)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
- return 0;
- }
- form = buf[0];
- y_bit = form & 1;
- form = form & ~1U;
- if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
- && (form != POINT_CONVERSION_UNCOMPRESSED)
- && (form != POINT_CONVERSION_HYBRID))
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
- if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- if (form == 0)
- {
- if (len != 1)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- return EC_POINT_set_to_infinity(group, point);
- }
-
- field_len = BN_num_bytes(&group->field);
- enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
-
- if (len != enc_len)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- return 0;
- }
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- if (y == NULL) goto err;
-
- if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
- if (BN_ucmp(x, &group->field) >= 0)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- goto err;
- }
-
- if (form == POINT_CONVERSION_COMPRESSED)
- {
- if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) goto err;
- }
- else
- {
- if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
- if (BN_ucmp(y, &group->field) >= 0)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- goto err;
- }
- if (form == POINT_CONVERSION_HYBRID)
- {
- if (y_bit != BN_is_odd(y))
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
- goto err;
- }
- }
-
- if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
- }
-
- if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
- {
- ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
- goto err;
- }
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
- {
- int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
- int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
- const BIGNUM *p;
- BN_CTX *new_ctx = NULL;
- BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
- int ret = 0;
-
- if (a == b)
- return EC_POINT_dbl(group, r, a, ctx);
- if (EC_POINT_is_at_infinity(group, a))
- return EC_POINT_copy(r, b);
- if (EC_POINT_is_at_infinity(group, b))
- return EC_POINT_copy(r, a);
-
- field_mul = group->meth->field_mul;
- field_sqr = group->meth->field_sqr;
- p = &group->field;
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- n0 = BN_CTX_get(ctx);
- n1 = BN_CTX_get(ctx);
- n2 = BN_CTX_get(ctx);
- n3 = BN_CTX_get(ctx);
- n4 = BN_CTX_get(ctx);
- n5 = BN_CTX_get(ctx);
- n6 = BN_CTX_get(ctx);
- if (n6 == NULL) goto end;
-
- /* Note that in this function we must not read components of 'a' or 'b'
- * once we have written the corresponding components of 'r'.
- * ('r' might be one of 'a' or 'b'.)
- */
-
- /* n1, n2 */
- if (b->Z_is_one)
- {
- if (!BN_copy(n1, &a->X)) goto end;
- if (!BN_copy(n2, &a->Y)) goto end;
- /* n1 = X_a */
- /* n2 = Y_a */
- }
- else
- {
- if (!field_sqr(group, n0, &b->Z, ctx)) goto end;
- if (!field_mul(group, n1, &a->X, n0, ctx)) goto end;
- /* n1 = X_a * Z_b^2 */
-
- if (!field_mul(group, n0, n0, &b->Z, ctx)) goto end;
- if (!field_mul(group, n2, &a->Y, n0, ctx)) goto end;
- /* n2 = Y_a * Z_b^3 */
- }
-
- /* n3, n4 */
- if (a->Z_is_one)
- {
- if (!BN_copy(n3, &b->X)) goto end;
- if (!BN_copy(n4, &b->Y)) goto end;
- /* n3 = X_b */
- /* n4 = Y_b */
- }
- else
- {
- if (!field_sqr(group, n0, &a->Z, ctx)) goto end;
- if (!field_mul(group, n3, &b->X, n0, ctx)) goto end;
- /* n3 = X_b * Z_a^2 */
-
- if (!field_mul(group, n0, n0, &a->Z, ctx)) goto end;
- if (!field_mul(group, n4, &b->Y, n0, ctx)) goto end;
- /* n4 = Y_b * Z_a^3 */
- }
-
- /* n5, n6 */
- if (!BN_mod_sub_quick(n5, n1, n3, p)) goto end;
- if (!BN_mod_sub_quick(n6, n2, n4, p)) goto end;
- /* n5 = n1 - n3 */
- /* n6 = n2 - n4 */
-
- if (BN_is_zero(n5))
- {
- if (BN_is_zero(n6))
- {
- /* a is the same point as b */
- BN_CTX_end(ctx);
- ret = EC_POINT_dbl(group, r, a, ctx);
- ctx = NULL;
- goto end;
- }
- else
- {
- /* a is the inverse of b */
- BN_zero(&r->Z);
- r->Z_is_one = 0;
- ret = 1;
- goto end;
- }
- }
-
- /* 'n7', 'n8' */
- if (!BN_mod_add_quick(n1, n1, n3, p)) goto end;
- if (!BN_mod_add_quick(n2, n2, n4, p)) goto end;
- /* 'n7' = n1 + n3 */
- /* 'n8' = n2 + n4 */
-
- /* Z_r */
- if (a->Z_is_one && b->Z_is_one)
- {
- if (!BN_copy(&r->Z, n5)) goto end;
- }
- else
- {
- if (a->Z_is_one)
- { if (!BN_copy(n0, &b->Z)) goto end; }
- else if (b->Z_is_one)
- { if (!BN_copy(n0, &a->Z)) goto end; }
- else
- { if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) goto end; }
- if (!field_mul(group, &r->Z, n0, n5, ctx)) goto end;
- }
- r->Z_is_one = 0;
- /* Z_r = Z_a * Z_b * n5 */
-
- /* X_r */
- if (!field_sqr(group, n0, n6, ctx)) goto end;
- if (!field_sqr(group, n4, n5, ctx)) goto end;
- if (!field_mul(group, n3, n1, n4, ctx)) goto end;
- if (!BN_mod_sub_quick(&r->X, n0, n3, p)) goto end;
- /* X_r = n6^2 - n5^2 * 'n7' */
-
- /* 'n9' */
- if (!BN_mod_lshift1_quick(n0, &r->X, p)) goto end;
- if (!BN_mod_sub_quick(n0, n3, n0, p)) goto end;
- /* n9 = n5^2 * 'n7' - 2 * X_r */
-
- /* Y_r */
- if (!field_mul(group, n0, n0, n6, ctx)) goto end;
- if (!field_mul(group, n5, n4, n5, ctx)) goto end; /* now n5 is n5^3 */
- if (!field_mul(group, n1, n2, n5, ctx)) goto end;
- if (!BN_mod_sub_quick(n0, n0, n1, p)) goto end;
- if (BN_is_odd(n0))
- if (!BN_add(n0, n0, p)) goto end;
- /* now 0 <= n0 < 2*p, and n0 is even */
- if (!BN_rshift1(&r->Y, n0)) goto end;
- /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
-
- ret = 1;
-
- end:
- if (ctx) /* otherwise we already called BN_CTX_end */
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
- {
- int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
- int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
- const BIGNUM *p;
- BN_CTX *new_ctx = NULL;
- BIGNUM *n0, *n1, *n2, *n3;
- int ret = 0;
-
- if (EC_POINT_is_at_infinity(group, a))
- {
- BN_zero(&r->Z);
- r->Z_is_one = 0;
- return 1;
- }
-
- field_mul = group->meth->field_mul;
- field_sqr = group->meth->field_sqr;
- p = &group->field;
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- n0 = BN_CTX_get(ctx);
- n1 = BN_CTX_get(ctx);
- n2 = BN_CTX_get(ctx);
- n3 = BN_CTX_get(ctx);
- if (n3 == NULL) goto err;
-
- /* Note that in this function we must not read components of 'a'
- * once we have written the corresponding components of 'r'.
- * ('r' might the same as 'a'.)
- */
-
- /* n1 */
- if (a->Z_is_one)
- {
- if (!field_sqr(group, n0, &a->X, ctx)) goto err;
- if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
- if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
- if (!BN_mod_add_quick(n1, n0, &group->a, p)) goto err;
- /* n1 = 3 * X_a^2 + a_curve */
- }
- else if (group->a_is_minus3)
- {
- if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
- if (!BN_mod_add_quick(n0, &a->X, n1, p)) goto err;
- if (!BN_mod_sub_quick(n2, &a->X, n1, p)) goto err;
- if (!field_mul(group, n1, n0, n2, ctx)) goto err;
- if (!BN_mod_lshift1_quick(n0, n1, p)) goto err;
- if (!BN_mod_add_quick(n1, n0, n1, p)) goto err;
- /* n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
- * = 3 * X_a^2 - 3 * Z_a^4 */
- }
- else
- {
- if (!field_sqr(group, n0, &a->X, ctx)) goto err;
- if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
- if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
- if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
- if (!field_sqr(group, n1, n1, ctx)) goto err;
- if (!field_mul(group, n1, n1, &group->a, ctx)) goto err;
- if (!BN_mod_add_quick(n1, n1, n0, p)) goto err;
- /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
- }
-
- /* Z_r */
- if (a->Z_is_one)
- {
- if (!BN_copy(n0, &a->Y)) goto err;
- }
- else
- {
- if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) goto err;
- }
- if (!BN_mod_lshift1_quick(&r->Z, n0, p)) goto err;
- r->Z_is_one = 0;
- /* Z_r = 2 * Y_a * Z_a */
-
- /* n2 */
- if (!field_sqr(group, n3, &a->Y, ctx)) goto err;
- if (!field_mul(group, n2, &a->X, n3, ctx)) goto err;
- if (!BN_mod_lshift_quick(n2, n2, 2, p)) goto err;
- /* n2 = 4 * X_a * Y_a^2 */
-
- /* X_r */
- if (!BN_mod_lshift1_quick(n0, n2, p)) goto err;
- if (!field_sqr(group, &r->X, n1, ctx)) goto err;
- if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) goto err;
- /* X_r = n1^2 - 2 * n2 */
-
- /* n3 */
- if (!field_sqr(group, n0, n3, ctx)) goto err;
- if (!BN_mod_lshift_quick(n3, n0, 3, p)) goto err;
- /* n3 = 8 * Y_a^4 */
-
- /* Y_r */
- if (!BN_mod_sub_quick(n0, n2, &r->X, p)) goto err;
- if (!field_mul(group, n0, n1, n0, ctx)) goto err;
- if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) goto err;
- /* Y_r = n1 * (n2 - X_r) - n3 */
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
- {
- if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
- /* point is its own inverse */
- return 1;
-
- return BN_usub(&point->Y, &group->field, &point->Y);
- }
-
-
-int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
- {
- return BN_is_zero(&point->Z);
- }
-
-
-int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
- {
- int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
- int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
- const BIGNUM *p;
- BN_CTX *new_ctx = NULL;
- BIGNUM *rh, *tmp, *Z4, *Z6;
- int ret = -1;
-
- if (EC_POINT_is_at_infinity(group, point))
- return 1;
-
- field_mul = group->meth->field_mul;
- field_sqr = group->meth->field_sqr;
- p = &group->field;
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return -1;
- }
-
- BN_CTX_start(ctx);
- rh = BN_CTX_get(ctx);
- tmp = BN_CTX_get(ctx);
- Z4 = BN_CTX_get(ctx);
- Z6 = BN_CTX_get(ctx);
- if (Z6 == NULL) goto err;
-
- /* We have a curve defined by a Weierstrass equation
- * y^2 = x^3 + a*x + b.
- * The point to consider is given in Jacobian projective coordinates
- * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
- * Substituting this and multiplying by Z^6 transforms the above equation into
- * Y^2 = X^3 + a*X*Z^4 + b*Z^6.
- * To test this, we add up the right-hand side in 'rh'.
- */
-
- /* rh := X^2 */
- if (!field_sqr(group, rh, &point->X, ctx)) goto err;
-
- if (!point->Z_is_one)
- {
- if (!field_sqr(group, tmp, &point->Z, ctx)) goto err;
- if (!field_sqr(group, Z4, tmp, ctx)) goto err;
- if (!field_mul(group, Z6, Z4, tmp, ctx)) goto err;
-
- /* rh := (rh + a*Z^4)*X */
- if (group->a_is_minus3)
- {
- if (!BN_mod_lshift1_quick(tmp, Z4, p)) goto err;
- if (!BN_mod_add_quick(tmp, tmp, Z4, p)) goto err;
- if (!BN_mod_sub_quick(rh, rh, tmp, p)) goto err;
- if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
- }
- else
- {
- if (!field_mul(group, tmp, Z4, &group->a, ctx)) goto err;
- if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
- if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
- }
-
- /* rh := rh + b*Z^6 */
- if (!field_mul(group, tmp, &group->b, Z6, ctx)) goto err;
- if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
- }
- else
- {
- /* point->Z_is_one */
-
- /* rh := (rh + a)*X */
- if (!BN_mod_add_quick(rh, rh, &group->a, p)) goto err;
- if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
- /* rh := rh + b */
- if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err;
- }
-
- /* 'lh' := Y^2 */
- if (!field_sqr(group, tmp, &point->Y, ctx)) goto err;
-
- ret = (0 == BN_ucmp(tmp, rh));
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
- {
- /* return values:
- * -1 error
- * 0 equal (in affine coordinates)
- * 1 not equal
- */
-
- int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
- int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
- BN_CTX *new_ctx = NULL;
- BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
- const BIGNUM *tmp1_, *tmp2_;
- int ret = -1;
-
- if (EC_POINT_is_at_infinity(group, a))
- {
- return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
- }
-
- if (EC_POINT_is_at_infinity(group, b))
- return 1;
-
- if (a->Z_is_one && b->Z_is_one)
- {
- return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
- }
-
- field_mul = group->meth->field_mul;
- field_sqr = group->meth->field_sqr;
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return -1;
- }
-
- BN_CTX_start(ctx);
- tmp1 = BN_CTX_get(ctx);
- tmp2 = BN_CTX_get(ctx);
- Za23 = BN_CTX_get(ctx);
- Zb23 = BN_CTX_get(ctx);
- if (Zb23 == NULL) goto end;
-
- /* We have to decide whether
- * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
- * or equivalently, whether
- * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
- */
-
- if (!b->Z_is_one)
- {
- if (!field_sqr(group, Zb23, &b->Z, ctx)) goto end;
- if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) goto end;
- tmp1_ = tmp1;
- }
- else
- tmp1_ = &a->X;
- if (!a->Z_is_one)
- {
- if (!field_sqr(group, Za23, &a->Z, ctx)) goto end;
- if (!field_mul(group, tmp2, &b->X, Za23, ctx)) goto end;
- tmp2_ = tmp2;
- }
- else
- tmp2_ = &b->X;
-
- /* compare X_a*Z_b^2 with X_b*Z_a^2 */
- if (BN_cmp(tmp1_, tmp2_) != 0)
- {
- ret = 1; /* points differ */
- goto end;
- }
-
-
- if (!b->Z_is_one)
- {
- if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) goto end;
- if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) goto end;
- /* tmp1_ = tmp1 */
- }
- else
- tmp1_ = &a->Y;
- if (!a->Z_is_one)
- {
- if (!field_mul(group, Za23, Za23, &a->Z, ctx)) goto end;
- if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) goto end;
- /* tmp2_ = tmp2 */
- }
- else
- tmp2_ = &b->Y;
-
- /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
- if (BN_cmp(tmp1_, tmp2_) != 0)
- {
- ret = 1; /* points differ */
- goto end;
- }
-
- /* points are equal */
- ret = 0;
-
- end:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
- {
- BN_CTX *new_ctx = NULL;
- BIGNUM *x, *y;
- int ret = 0;
-
- if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
- return 1;
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- if (y == NULL) goto err;
-
- if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
- if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
- if (!point->Z_is_one)
- {
- ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- return ret;
- }
-
-
-int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
- {
- BN_CTX *new_ctx = NULL;
- BIGNUM *tmp0, *tmp1;
- size_t pow2 = 0;
- BIGNUM **heap = NULL;
- size_t i;
- int ret = 0;
-
- if (num == 0)
- return 1;
-
- if (ctx == NULL)
- {
- ctx = new_ctx = BN_CTX_new();
- if (ctx == NULL)
- return 0;
- }
-
- BN_CTX_start(ctx);
- tmp0 = BN_CTX_get(ctx);
- tmp1 = BN_CTX_get(ctx);
- if (tmp0 == NULL || tmp1 == NULL) goto err;
-
- /* Before converting the individual points, compute inverses of all Z values.
- * Modular inversion is rather slow, but luckily we can do with a single
- * explicit inversion, plus about 3 multiplications per input value.
- */
-
- pow2 = 1;
- while (num > pow2)
- pow2 <<= 1;
- /* Now pow2 is the smallest power of 2 satifsying pow2 >= num.
- * We need twice that. */
- pow2 <<= 1;
-
- heap = OPENSSL_malloc(pow2 * sizeof heap[0]);
- if (heap == NULL) goto err;
-
- /* The array is used as a binary tree, exactly as in heapsort:
- *
- * heap[1]
- * heap[2] heap[3]
- * heap[4] heap[5] heap[6] heap[7]
- * heap[8]heap[9] heap[10]heap[11] heap[12]heap[13] heap[14] heap[15]
- *
- * We put the Z's in the last line;
- * then we set each other node to the product of its two child-nodes (where
- * empty or 0 entries are treated as ones);
- * then we invert heap[1];
- * then we invert each other node by replacing it by the product of its
- * parent (after inversion) and its sibling (before inversion).
- */
- heap[0] = NULL;
- for (i = pow2/2 - 1; i > 0; i--)
- heap[i] = NULL;
- for (i = 0; i < num; i++)
- heap[pow2/2 + i] = &points[i]->Z;
- for (i = pow2/2 + num; i < pow2; i++)
- heap[i] = NULL;
-
- /* set each node to the product of its children */
- for (i = pow2/2 - 1; i > 0; i--)
- {
- heap[i] = BN_new();
- if (heap[i] == NULL) goto err;
-
- if (heap[2*i] != NULL)
- {
- if ((heap[2*i + 1] == NULL) || BN_is_zero(heap[2*i + 1]))
- {
- if (!BN_copy(heap[i], heap[2*i])) goto err;
- }
- else
- {
- if (BN_is_zero(heap[2*i]))
- {
- if (!BN_copy(heap[i], heap[2*i + 1])) goto err;
- }
- else
- {
- if (!group->meth->field_mul(group, heap[i],
- heap[2*i], heap[2*i + 1], ctx)) goto err;
- }
- }
- }
- }
-
- /* invert heap[1] */
- if (!BN_is_zero(heap[1]))
- {
- if (!BN_mod_inverse(heap[1], heap[1], &group->field, ctx))
- {
- ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
- goto err;
- }
- }
- if (group->meth->field_encode != 0)
- {
- /* in the Montgomery case, we just turned R*H (representing H)
- * into 1/(R*H), but we need R*(1/H) (representing 1/H);
- * i.e. we have need to multiply by the Montgomery factor twice */
- if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
- if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
- }
-
- /* set other heap[i]'s to their inverses */
- for (i = 2; i < pow2/2 + num; i += 2)
- {
- /* i is even */
- if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1]))
- {
- if (!group->meth->field_mul(group, tmp0, heap[i/2], heap[i + 1], ctx)) goto err;
- if (!group->meth->field_mul(group, tmp1, heap[i/2], heap[i], ctx)) goto err;
- if (!BN_copy(heap[i], tmp0)) goto err;
- if (!BN_copy(heap[i + 1], tmp1)) goto err;
- }
- else
- {
- if (!BN_copy(heap[i], heap[i/2])) goto err;
- }
- }
-
- /* we have replaced all non-zero Z's by their inverses, now fix up all the points */
- for (i = 0; i < num; i++)
- {
- EC_POINT *p = points[i];
-
- if (!BN_is_zero(&p->Z))
- {
- /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
-
- if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx)) goto err;
- if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx)) goto err;
-
- if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx)) goto err;
- if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx)) goto err;
-
- if (group->meth->field_set_to_one != 0)
- {
- if (!group->meth->field_set_to_one(group, &p->Z, ctx)) goto err;
- }
- else
- {
- if (!BN_one(&p->Z)) goto err;
- }
- p->Z_is_one = 1;
- }
- }
-
- ret = 1;
-
- err:
- BN_CTX_end(ctx);
- if (new_ctx != NULL)
- BN_CTX_free(new_ctx);
- if (heap != NULL)
- {
- /* heap[pow2/2] .. heap[pow2-1] have not been allocated locally! */
- for (i = pow2/2 - 1; i > 0; i--)
- {
- if (heap[i] != NULL)
- BN_clear_free(heap[i]);
- }
- OPENSSL_free(heap);
- }
- return ret;
- }
-
-
-int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
- {
- return BN_mod_mul(r, a, b, &group->field, ctx);
- }
-
-
-int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
- {
- return BN_mod_sqr(r, a, &group->field, ctx);
- }
+/* crypto/ec/ecp_smpl.c */
+/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
+ * for the OpenSSL project.
+ * Includes code written by Bodo Moeller for the OpenSSL project.
+*/
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <openssl/err.h>
+#include <openssl/symhacks.h>
+
+#include "ec_lcl.h"
+
+const EC_METHOD *EC_GFp_simple_method(void)
+ {
+ static const EC_METHOD ret = {
+ NID_X9_62_prime_field,
+ ec_GFp_simple_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_clear_finish,
+ ec_GFp_simple_group_copy,
+ ec_GFp_simple_group_set_curve,
+ ec_GFp_simple_group_get_curve,
+ ec_GFp_simple_group_get_degree,
+ ec_GFp_simple_group_check_discriminant,
+ ec_GFp_simple_point_init,
+ ec_GFp_simple_point_finish,
+ ec_GFp_simple_point_clear_finish,
+ ec_GFp_simple_point_copy,
+ ec_GFp_simple_point_set_to_infinity,
+ ec_GFp_simple_set_Jprojective_coordinates_GFp,
+ ec_GFp_simple_get_Jprojective_coordinates_GFp,
+ ec_GFp_simple_point_set_affine_coordinates,
+ ec_GFp_simple_point_get_affine_coordinates,
+ ec_GFp_simple_set_compressed_coordinates,
+ ec_GFp_simple_point2oct,
+ ec_GFp_simple_oct2point,
+ ec_GFp_simple_add,
+ ec_GFp_simple_dbl,
+ ec_GFp_simple_invert,
+ ec_GFp_simple_is_at_infinity,
+ ec_GFp_simple_is_on_curve,
+ ec_GFp_simple_cmp,
+ ec_GFp_simple_make_affine,
+ ec_GFp_simple_points_make_affine,
+ 0 /* mul */,
+ 0 /* precompute_mult */,
+ 0 /* have_precompute_mult */,
+ ec_GFp_simple_field_mul,
+ ec_GFp_simple_field_sqr,
+ 0 /* field_div */,
+ 0 /* field_encode */,
+ 0 /* field_decode */,
+ 0 /* field_set_to_one */ };
+
+ return &ret;
+ }
+
+
+/* Most method functions in this file are designed to work with
+ * non-trivial representations of field elements if necessary
+ * (see ecp_mont.c): while standard modular addition and subtraction
+ * are used, the field_mul and field_sqr methods will be used for
+ * multiplication, and field_encode and field_decode (if defined)
+ * will be used for converting between representations.
+
+ * Functions ec_GFp_simple_points_make_affine() and
+ * ec_GFp_simple_point_get_affine_coordinates() specifically assume
+ * that if a non-trivial representation is used, it is a Montgomery
+ * representation (i.e. 'encoding' means multiplying by some factor R).
+ */
+
+
+int ec_GFp_simple_group_init(EC_GROUP *group)
+ {
+ BN_init(&group->field);
+ BN_init(&group->a);
+ BN_init(&group->b);
+ group->a_is_minus3 = 0;
+ return 1;
+ }
+
+
+void ec_GFp_simple_group_finish(EC_GROUP *group)
+ {
+ BN_free(&group->field);
+ BN_free(&group->a);
+ BN_free(&group->b);
+ }
+
+
+void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
+ {
+ BN_clear_free(&group->field);
+ BN_clear_free(&group->a);
+ BN_clear_free(&group->b);
+ }
+
+
+int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+ {
+ if (!BN_copy(&dest->field, &src->field)) return 0;
+ if (!BN_copy(&dest->a, &src->a)) return 0;
+ if (!BN_copy(&dest->b, &src->b)) return 0;
+
+ dest->a_is_minus3 = src->a_is_minus3;
+
+ return 1;
+ }
+
+
+int ec_GFp_simple_group_set_curve(EC_GROUP *group,
+ const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+ {
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp_a;
+
+ /* p must be a prime > 3 */
+ if (BN_num_bits(p) <= 2 || !BN_is_odd(p))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
+ return 0;
+ }
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ tmp_a = BN_CTX_get(ctx);
+ if (tmp_a == NULL) goto err;
+
+ /* group->field */
+ if (!BN_copy(&group->field, p)) goto err;
+ BN_set_negative(&group->field, 0);
+
+ /* group->a */
+ if (!BN_nnmod(tmp_a, a, p, ctx)) goto err;
+ if (group->meth->field_encode)
+ { if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) goto err; }
+ else
+ if (!BN_copy(&group->a, tmp_a)) goto err;
+
+ /* group->b */
+ if (!BN_nnmod(&group->b, b, p, ctx)) goto err;
+ if (group->meth->field_encode)
+ if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) goto err;
+
+ /* group->a_is_minus3 */
+ if (!BN_add_word(tmp_a, 3)) goto err;
+ group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+ {
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+
+ if (p != NULL)
+ {
+ if (!BN_copy(p, &group->field)) return 0;
+ }
+
+ if (a != NULL || b != NULL)
+ {
+ if (group->meth->field_decode)
+ {
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+ if (a != NULL)
+ {
+ if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
+ }
+ if (b != NULL)
+ {
+ if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
+ }
+ }
+ else
+ {
+ if (a != NULL)
+ {
+ if (!BN_copy(a, &group->a)) goto err;
+ }
+ if (b != NULL)
+ {
+ if (!BN_copy(b, &group->b)) goto err;
+ }
+ }
+ }
+
+ ret = 1;
+
+ err:
+ if (new_ctx)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
+ {
+ return BN_num_bits(&group->field);
+ }
+
+
+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
+ {
+ int ret = 0;
+ BIGNUM *a,*b,*order,*tmp_1,*tmp_2;
+ const BIGNUM *p = &group->field;
+ BN_CTX *new_ctx = NULL;
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ BN_CTX_start(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ tmp_1 = BN_CTX_get(ctx);
+ tmp_2 = BN_CTX_get(ctx);
+ order = BN_CTX_get(ctx);
+ if (order == NULL) goto err;
+
+ if (group->meth->field_decode)
+ {
+ if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
+ if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_copy(a, &group->a)) goto err;
+ if (!BN_copy(b, &group->b)) goto err;
+ }
+
+ /* check the discriminant:
+ * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
+ * 0 =< a, b < p */
+ if (BN_is_zero(a))
+ {
+ if (BN_is_zero(b)) goto err;
+ }
+ else if (!BN_is_zero(b))
+ {
+ if (!BN_mod_sqr(tmp_1, a, p, ctx)) goto err;
+ if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) goto err;
+ if (!BN_lshift(tmp_1, tmp_2, 2)) goto err;
+ /* tmp_1 = 4*a^3 */
+
+ if (!BN_mod_sqr(tmp_2, b, p, ctx)) goto err;
+ if (!BN_mul_word(tmp_2, 27)) goto err;
+ /* tmp_2 = 27*b^2 */
+
+ if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) goto err;
+ if (BN_is_zero(a)) goto err;
+ }
+ ret = 1;
+
+err:
+ if (ctx != NULL)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+int ec_GFp_simple_point_init(EC_POINT *point)
+ {
+ BN_init(&point->X);
+ BN_init(&point->Y);
+ BN_init(&point->Z);
+ point->Z_is_one = 0;
+
+ return 1;
+ }
+
+
+void ec_GFp_simple_point_finish(EC_POINT *point)
+ {
+ BN_free(&point->X);
+ BN_free(&point->Y);
+ BN_free(&point->Z);
+ }
+
+
+void ec_GFp_simple_point_clear_finish(EC_POINT *point)
+ {
+ BN_clear_free(&point->X);
+ BN_clear_free(&point->Y);
+ BN_clear_free(&point->Z);
+ point->Z_is_one = 0;
+ }
+
+
+int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
+ {
+ if (!BN_copy(&dest->X, &src->X)) return 0;
+ if (!BN_copy(&dest->Y, &src->Y)) return 0;
+ if (!BN_copy(&dest->Z, &src->Z)) return 0;
+ dest->Z_is_one = src->Z_is_one;
+
+ return 1;
+ }
+
+
+int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
+ {
+ point->Z_is_one = 0;
+ BN_zero(&point->Z);
+ return 1;
+ }
+
+
+int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
+ const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
+ {
+ BN_CTX *new_ctx = NULL;
+ int ret = 0;
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ if (x != NULL)
+ {
+ if (!BN_nnmod(&point->X, x, &group->field, ctx)) goto err;
+ if (group->meth->field_encode)
+ {
+ if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) goto err;
+ }
+ }
+
+ if (y != NULL)
+ {
+ if (!BN_nnmod(&point->Y, y, &group->field, ctx)) goto err;
+ if (group->meth->field_encode)
+ {
+ if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) goto err;
+ }
+ }
+
+ if (z != NULL)
+ {
+ int Z_is_one;
+
+ if (!BN_nnmod(&point->Z, z, &group->field, ctx)) goto err;
+ Z_is_one = BN_is_one(&point->Z);
+ if (group->meth->field_encode)
+ {
+ if (Z_is_one && (group->meth->field_set_to_one != 0))
+ {
+ if (!group->meth->field_set_to_one(group, &point->Z, ctx)) goto err;
+ }
+ else
+ {
+ if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx)) goto err;
+ }
+ }
+ point->Z_is_one = Z_is_one;
+ }
+
+ ret = 1;
+
+ err:
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
+ {
+ BN_CTX *new_ctx = NULL;
+ int ret = 0;
+
+ if (group->meth->field_decode != 0)
+ {
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ if (x != NULL)
+ {
+ if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
+ }
+ if (y != NULL)
+ {
+ if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
+ }
+ if (z != NULL)
+ {
+ if (!group->meth->field_decode(group, z, &point->Z, ctx)) goto err;
+ }
+ }
+ else
+ {
+ if (x != NULL)
+ {
+ if (!BN_copy(x, &point->X)) goto err;
+ }
+ if (y != NULL)
+ {
+ if (!BN_copy(y, &point->Y)) goto err;
+ }
+ if (z != NULL)
+ {
+ if (!BN_copy(z, &point->Z)) goto err;
+ }
+ }
+
+ ret = 1;
+
+ err:
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
+ const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
+ {
+ if (x == NULL || y == NULL)
+ {
+ /* unlike for projective coordinates, we do not tolerate this */
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, BN_value_one(), ctx);
+ }
+
+
+int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
+ {
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *Z, *Z_1, *Z_2, *Z_3;
+ const BIGNUM *Z_;
+ int ret = 0;
+
+ if (EC_POINT_is_at_infinity(group, point))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ Z = BN_CTX_get(ctx);
+ Z_1 = BN_CTX_get(ctx);
+ Z_2 = BN_CTX_get(ctx);
+ Z_3 = BN_CTX_get(ctx);
+ if (Z_3 == NULL) goto err;
+
+ /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
+
+ if (group->meth->field_decode)
+ {
+ if (!group->meth->field_decode(group, Z, &point->Z, ctx)) goto err;
+ Z_ = Z;
+ }
+ else
+ {
+ Z_ = &point->Z;
+ }
+
+ if (BN_is_one(Z_))
+ {
+ if (group->meth->field_decode)
+ {
+ if (x != NULL)
+ {
+ if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
+ }
+ if (y != NULL)
+ {
+ if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
+ }
+ }
+ else
+ {
+ if (x != NULL)
+ {
+ if (!BN_copy(x, &point->X)) goto err;
+ }
+ if (y != NULL)
+ {
+ if (!BN_copy(y, &point->Y)) goto err;
+ }
+ }
+ }
+ else
+ {
+ if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ if (group->meth->field_encode == 0)
+ {
+ /* field_sqr works on standard representation */
+ if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) goto err;
+ }
+
+ if (x != NULL)
+ {
+ /* in the Montgomery case, field_mul will cancel out Montgomery factor in X: */
+ if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) goto err;
+ }
+
+ if (y != NULL)
+ {
+ if (group->meth->field_encode == 0)
+ {
+ /* field_mul works on standard representation */
+ if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err;
+ }
+
+ /* in the Montgomery case, field_mul will cancel out Montgomery factor in Y: */
+ if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) goto err;
+ }
+ }
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
+ const BIGNUM *x_, int y_bit, BN_CTX *ctx)
+ {
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp1, *tmp2, *x, *y;
+ int ret = 0;
+
+ /* clear error queue*/
+ ERR_clear_error();
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ y_bit = (y_bit != 0);
+
+ BN_CTX_start(ctx);
+ tmp1 = BN_CTX_get(ctx);
+ tmp2 = BN_CTX_get(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (y == NULL) goto err;
+
+ /* Recover y. We have a Weierstrass equation
+ * y^2 = x^3 + a*x + b,
+ * so y is one of the square roots of x^3 + a*x + b.
+ */
+
+ /* tmp1 := x^3 */
+ if (!BN_nnmod(x, x_, &group->field,ctx)) goto err;
+ if (group->meth->field_decode == 0)
+ {
+ /* field_{sqr,mul} work on standard representation */
+ if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err;
+ if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err;
+ if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err;
+ }
+
+ /* tmp1 := tmp1 + a*x */
+ if (group->a_is_minus3)
+ {
+ if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err;
+ if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err;
+ if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
+ }
+ else
+ {
+ if (group->meth->field_decode)
+ {
+ if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err;
+ if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err;
+ }
+ else
+ {
+ /* field_mul works on standard representation */
+ if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err;
+ }
+
+ if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
+ }
+
+ /* tmp1 := tmp1 + b */
+ if (group->meth->field_decode)
+ {
+ if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err;
+ if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
+ }
+ else
+ {
+ if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err;
+ }
+
+ if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))
+ {
+ unsigned long err = ERR_peek_last_error();
+
+ if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)
+ {
+ ERR_clear_error();
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+ }
+ else
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ if (y_bit != BN_is_odd(y))
+ {
+ if (BN_is_zero(y))
+ {
+ int kron;
+
+ kron = BN_kronecker(x, &group->field, ctx);
+ if (kron == -2) goto err;
+
+ if (kron == 1)
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
+ else
+ /* BN_mod_sqrt() should have cought this error (not a square) */
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+ goto err;
+ }
+ if (!BN_usub(y, &group->field, y)) goto err;
+ }
+ if (y_bit != BN_is_odd(y))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
+ unsigned char *buf, size_t len, BN_CTX *ctx)
+ {
+ size_t ret;
+ BN_CTX *new_ctx = NULL;
+ int used_ctx = 0;
+ BIGNUM *x, *y;
+ size_t field_len, i, skip;
+
+ if ((form != POINT_CONVERSION_COMPRESSED)
+ && (form != POINT_CONVERSION_UNCOMPRESSED)
+ && (form != POINT_CONVERSION_HYBRID))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
+ goto err;
+ }
+
+ if (EC_POINT_is_at_infinity(group, point))
+ {
+ /* encodes to a single 0 octet */
+ if (buf != NULL)
+ {
+ if (len < 1)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ buf[0] = 0;
+ }
+ return 1;
+ }
+
+
+ /* ret := required output buffer length */
+ field_len = BN_num_bytes(&group->field);
+ ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
+
+ /* if 'buf' is NULL, just return required length */
+ if (buf != NULL)
+ {
+ if (len < ret)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ goto err;
+ }
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ used_ctx = 1;
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (y == NULL) goto err;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+
+ if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
+ buf[0] = form + 1;
+ else
+ buf[0] = form;
+
+ i = 1;
+
+ skip = field_len - BN_num_bytes(x);
+ if (skip > field_len)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ while (skip > 0)
+ {
+ buf[i++] = 0;
+ skip--;
+ }
+ skip = BN_bn2bin(x, buf + i);
+ i += skip;
+ if (i != 1 + field_len)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
+ {
+ skip = field_len - BN_num_bytes(y);
+ if (skip > field_len)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ while (skip > 0)
+ {
+ buf[i++] = 0;
+ skip--;
+ }
+ skip = BN_bn2bin(y, buf + i);
+ i += skip;
+ }
+
+ if (i != ret)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ if (used_ctx)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+
+ err:
+ if (used_ctx)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return 0;
+ }
+
+
+int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
+ const unsigned char *buf, size_t len, BN_CTX *ctx)
+ {
+ point_conversion_form_t form;
+ int y_bit;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y;
+ size_t field_len, enc_len;
+ int ret = 0;
+
+ if (len == 0)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ form = buf[0];
+ y_bit = form & 1;
+ form = form & ~1U;
+ if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
+ && (form != POINT_CONVERSION_UNCOMPRESSED)
+ && (form != POINT_CONVERSION_HYBRID))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+ if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ if (form == 0)
+ {
+ if (len != 1)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ return EC_POINT_set_to_infinity(group, point);
+ }
+
+ field_len = BN_num_bytes(&group->field);
+ enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
+
+ if (len != enc_len)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (y == NULL) goto err;
+
+ if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
+ if (BN_ucmp(x, &group->field) >= 0)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+
+ if (form == POINT_CONVERSION_COMPRESSED)
+ {
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
+ if (BN_ucmp(y, &group->field) >= 0)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+ if (form == POINT_CONVERSION_HYBRID)
+ {
+ if (y_bit != BN_is_odd(y))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+ }
+
+ if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
+ goto err;
+ }
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
+ {
+ int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+ int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+ const BIGNUM *p;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
+ int ret = 0;
+
+ if (a == b)
+ return EC_POINT_dbl(group, r, a, ctx);
+ if (EC_POINT_is_at_infinity(group, a))
+ return EC_POINT_copy(r, b);
+ if (EC_POINT_is_at_infinity(group, b))
+ return EC_POINT_copy(r, a);
+
+ field_mul = group->meth->field_mul;
+ field_sqr = group->meth->field_sqr;
+ p = &group->field;
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ n0 = BN_CTX_get(ctx);
+ n1 = BN_CTX_get(ctx);
+ n2 = BN_CTX_get(ctx);
+ n3 = BN_CTX_get(ctx);
+ n4 = BN_CTX_get(ctx);
+ n5 = BN_CTX_get(ctx);
+ n6 = BN_CTX_get(ctx);
+ if (n6 == NULL) goto end;
+
+ /* Note that in this function we must not read components of 'a' or 'b'
+ * once we have written the corresponding components of 'r'.
+ * ('r' might be one of 'a' or 'b'.)
+ */
+
+ /* n1, n2 */
+ if (b->Z_is_one)
+ {
+ if (!BN_copy(n1, &a->X)) goto end;
+ if (!BN_copy(n2, &a->Y)) goto end;
+ /* n1 = X_a */
+ /* n2 = Y_a */
+ }
+ else
+ {
+ if (!field_sqr(group, n0, &b->Z, ctx)) goto end;
+ if (!field_mul(group, n1, &a->X, n0, ctx)) goto end;
+ /* n1 = X_a * Z_b^2 */
+
+ if (!field_mul(group, n0, n0, &b->Z, ctx)) goto end;
+ if (!field_mul(group, n2, &a->Y, n0, ctx)) goto end;
+ /* n2 = Y_a * Z_b^3 */
+ }
+
+ /* n3, n4 */
+ if (a->Z_is_one)
+ {
+ if (!BN_copy(n3, &b->X)) goto end;
+ if (!BN_copy(n4, &b->Y)) goto end;
+ /* n3 = X_b */
+ /* n4 = Y_b */
+ }
+ else
+ {
+ if (!field_sqr(group, n0, &a->Z, ctx)) goto end;
+ if (!field_mul(group, n3, &b->X, n0, ctx)) goto end;
+ /* n3 = X_b * Z_a^2 */
+
+ if (!field_mul(group, n0, n0, &a->Z, ctx)) goto end;
+ if (!field_mul(group, n4, &b->Y, n0, ctx)) goto end;
+ /* n4 = Y_b * Z_a^3 */
+ }
+
+ /* n5, n6 */
+ if (!BN_mod_sub_quick(n5, n1, n3, p)) goto end;
+ if (!BN_mod_sub_quick(n6, n2, n4, p)) goto end;
+ /* n5 = n1 - n3 */
+ /* n6 = n2 - n4 */
+
+ if (BN_is_zero(n5))
+ {
+ if (BN_is_zero(n6))
+ {
+ /* a is the same point as b */
+ BN_CTX_end(ctx);
+ ret = EC_POINT_dbl(group, r, a, ctx);
+ ctx = NULL;
+ goto end;
+ }
+ else
+ {
+ /* a is the inverse of b */
+ BN_zero(&r->Z);
+ r->Z_is_one = 0;
+ ret = 1;
+ goto end;
+ }
+ }
+
+ /* 'n7', 'n8' */
+ if (!BN_mod_add_quick(n1, n1, n3, p)) goto end;
+ if (!BN_mod_add_quick(n2, n2, n4, p)) goto end;
+ /* 'n7' = n1 + n3 */
+ /* 'n8' = n2 + n4 */
+
+ /* Z_r */
+ if (a->Z_is_one && b->Z_is_one)
+ {
+ if (!BN_copy(&r->Z, n5)) goto end;
+ }
+ else
+ {
+ if (a->Z_is_one)
+ { if (!BN_copy(n0, &b->Z)) goto end; }
+ else if (b->Z_is_one)
+ { if (!BN_copy(n0, &a->Z)) goto end; }
+ else
+ { if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) goto end; }
+ if (!field_mul(group, &r->Z, n0, n5, ctx)) goto end;
+ }
+ r->Z_is_one = 0;
+ /* Z_r = Z_a * Z_b * n5 */
+
+ /* X_r */
+ if (!field_sqr(group, n0, n6, ctx)) goto end;
+ if (!field_sqr(group, n4, n5, ctx)) goto end;
+ if (!field_mul(group, n3, n1, n4, ctx)) goto end;
+ if (!BN_mod_sub_quick(&r->X, n0, n3, p)) goto end;
+ /* X_r = n6^2 - n5^2 * 'n7' */
+
+ /* 'n9' */
+ if (!BN_mod_lshift1_quick(n0, &r->X, p)) goto end;
+ if (!BN_mod_sub_quick(n0, n3, n0, p)) goto end;
+ /* n9 = n5^2 * 'n7' - 2 * X_r */
+
+ /* Y_r */
+ if (!field_mul(group, n0, n0, n6, ctx)) goto end;
+ if (!field_mul(group, n5, n4, n5, ctx)) goto end; /* now n5 is n5^3 */
+ if (!field_mul(group, n1, n2, n5, ctx)) goto end;
+ if (!BN_mod_sub_quick(n0, n0, n1, p)) goto end;
+ if (BN_is_odd(n0))
+ if (!BN_add(n0, n0, p)) goto end;
+ /* now 0 <= n0 < 2*p, and n0 is even */
+ if (!BN_rshift1(&r->Y, n0)) goto end;
+ /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
+
+ ret = 1;
+
+ end:
+ if (ctx) /* otherwise we already called BN_CTX_end */
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
+ {
+ int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+ int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+ const BIGNUM *p;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *n0, *n1, *n2, *n3;
+ int ret = 0;
+
+ if (EC_POINT_is_at_infinity(group, a))
+ {
+ BN_zero(&r->Z);
+ r->Z_is_one = 0;
+ return 1;
+ }
+
+ field_mul = group->meth->field_mul;
+ field_sqr = group->meth->field_sqr;
+ p = &group->field;
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ n0 = BN_CTX_get(ctx);
+ n1 = BN_CTX_get(ctx);
+ n2 = BN_CTX_get(ctx);
+ n3 = BN_CTX_get(ctx);
+ if (n3 == NULL) goto err;
+
+ /* Note that in this function we must not read components of 'a'
+ * once we have written the corresponding components of 'r'.
+ * ('r' might the same as 'a'.)
+ */
+
+ /* n1 */
+ if (a->Z_is_one)
+ {
+ if (!field_sqr(group, n0, &a->X, ctx)) goto err;
+ if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
+ if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
+ if (!BN_mod_add_quick(n1, n0, &group->a, p)) goto err;
+ /* n1 = 3 * X_a^2 + a_curve */
+ }
+ else if (group->a_is_minus3)
+ {
+ if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
+ if (!BN_mod_add_quick(n0, &a->X, n1, p)) goto err;
+ if (!BN_mod_sub_quick(n2, &a->X, n1, p)) goto err;
+ if (!field_mul(group, n1, n0, n2, ctx)) goto err;
+ if (!BN_mod_lshift1_quick(n0, n1, p)) goto err;
+ if (!BN_mod_add_quick(n1, n0, n1, p)) goto err;
+ /* n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
+ * = 3 * X_a^2 - 3 * Z_a^4 */
+ }
+ else
+ {
+ if (!field_sqr(group, n0, &a->X, ctx)) goto err;
+ if (!BN_mod_lshift1_quick(n1, n0, p)) goto err;
+ if (!BN_mod_add_quick(n0, n0, n1, p)) goto err;
+ if (!field_sqr(group, n1, &a->Z, ctx)) goto err;
+ if (!field_sqr(group, n1, n1, ctx)) goto err;
+ if (!field_mul(group, n1, n1, &group->a, ctx)) goto err;
+ if (!BN_mod_add_quick(n1, n1, n0, p)) goto err;
+ /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
+ }
+
+ /* Z_r */
+ if (a->Z_is_one)
+ {
+ if (!BN_copy(n0, &a->Y)) goto err;
+ }
+ else
+ {
+ if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) goto err;
+ }
+ if (!BN_mod_lshift1_quick(&r->Z, n0, p)) goto err;
+ r->Z_is_one = 0;
+ /* Z_r = 2 * Y_a * Z_a */
+
+ /* n2 */
+ if (!field_sqr(group, n3, &a->Y, ctx)) goto err;
+ if (!field_mul(group, n2, &a->X, n3, ctx)) goto err;
+ if (!BN_mod_lshift_quick(n2, n2, 2, p)) goto err;
+ /* n2 = 4 * X_a * Y_a^2 */
+
+ /* X_r */
+ if (!BN_mod_lshift1_quick(n0, n2, p)) goto err;
+ if (!field_sqr(group, &r->X, n1, ctx)) goto err;
+ if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) goto err;
+ /* X_r = n1^2 - 2 * n2 */
+
+ /* n3 */
+ if (!field_sqr(group, n0, n3, ctx)) goto err;
+ if (!BN_mod_lshift_quick(n3, n0, 3, p)) goto err;
+ /* n3 = 8 * Y_a^4 */
+
+ /* Y_r */
+ if (!BN_mod_sub_quick(n0, n2, &r->X, p)) goto err;
+ if (!field_mul(group, n0, n1, n0, ctx)) goto err;
+ if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) goto err;
+ /* Y_r = n1 * (n2 - X_r) - n3 */
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+ {
+ if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
+ /* point is its own inverse */
+ return 1;
+
+ return BN_usub(&point->Y, &group->field, &point->Y);
+ }
+
+
+int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
+ {
+ return BN_is_zero(&point->Z);
+ }
+
+
+int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
+ {
+ int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+ int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+ const BIGNUM *p;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *rh, *tmp, *Z4, *Z6;
+ int ret = -1;
+
+ if (EC_POINT_is_at_infinity(group, point))
+ return 1;
+
+ field_mul = group->meth->field_mul;
+ field_sqr = group->meth->field_sqr;
+ p = &group->field;
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return -1;
+ }
+
+ BN_CTX_start(ctx);
+ rh = BN_CTX_get(ctx);
+ tmp = BN_CTX_get(ctx);
+ Z4 = BN_CTX_get(ctx);
+ Z6 = BN_CTX_get(ctx);
+ if (Z6 == NULL) goto err;
+
+ /* We have a curve defined by a Weierstrass equation
+ * y^2 = x^3 + a*x + b.
+ * The point to consider is given in Jacobian projective coordinates
+ * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
+ * Substituting this and multiplying by Z^6 transforms the above equation into
+ * Y^2 = X^3 + a*X*Z^4 + b*Z^6.
+ * To test this, we add up the right-hand side in 'rh'.
+ */
+
+ /* rh := X^2 */
+ if (!field_sqr(group, rh, &point->X, ctx)) goto err;
+
+ if (!point->Z_is_one)
+ {
+ if (!field_sqr(group, tmp, &point->Z, ctx)) goto err;
+ if (!field_sqr(group, Z4, tmp, ctx)) goto err;
+ if (!field_mul(group, Z6, Z4, tmp, ctx)) goto err;
+
+ /* rh := (rh + a*Z^4)*X */
+ if (group->a_is_minus3)
+ {
+ if (!BN_mod_lshift1_quick(tmp, Z4, p)) goto err;
+ if (!BN_mod_add_quick(tmp, tmp, Z4, p)) goto err;
+ if (!BN_mod_sub_quick(rh, rh, tmp, p)) goto err;
+ if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
+ }
+ else
+ {
+ if (!field_mul(group, tmp, Z4, &group->a, ctx)) goto err;
+ if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
+ if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
+ }
+
+ /* rh := rh + b*Z^6 */
+ if (!field_mul(group, tmp, &group->b, Z6, ctx)) goto err;
+ if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
+ }
+ else
+ {
+ /* point->Z_is_one */
+
+ /* rh := (rh + a)*X */
+ if (!BN_mod_add_quick(rh, rh, &group->a, p)) goto err;
+ if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
+ /* rh := rh + b */
+ if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err;
+ }
+
+ /* 'lh' := Y^2 */
+ if (!field_sqr(group, tmp, &point->Y, ctx)) goto err;
+
+ ret = (0 == BN_ucmp(tmp, rh));
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
+ {
+ /* return values:
+ * -1 error
+ * 0 equal (in affine coordinates)
+ * 1 not equal
+ */
+
+ int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+ int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
+ const BIGNUM *tmp1_, *tmp2_;
+ int ret = -1;
+
+ if (EC_POINT_is_at_infinity(group, a))
+ {
+ return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
+ }
+
+ if (EC_POINT_is_at_infinity(group, b))
+ return 1;
+
+ if (a->Z_is_one && b->Z_is_one)
+ {
+ return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
+ }
+
+ field_mul = group->meth->field_mul;
+ field_sqr = group->meth->field_sqr;
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return -1;
+ }
+
+ BN_CTX_start(ctx);
+ tmp1 = BN_CTX_get(ctx);
+ tmp2 = BN_CTX_get(ctx);
+ Za23 = BN_CTX_get(ctx);
+ Zb23 = BN_CTX_get(ctx);
+ if (Zb23 == NULL) goto end;
+
+ /* We have to decide whether
+ * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
+ * or equivalently, whether
+ * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
+ */
+
+ if (!b->Z_is_one)
+ {
+ if (!field_sqr(group, Zb23, &b->Z, ctx)) goto end;
+ if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) goto end;
+ tmp1_ = tmp1;
+ }
+ else
+ tmp1_ = &a->X;
+ if (!a->Z_is_one)
+ {
+ if (!field_sqr(group, Za23, &a->Z, ctx)) goto end;
+ if (!field_mul(group, tmp2, &b->X, Za23, ctx)) goto end;
+ tmp2_ = tmp2;
+ }
+ else
+ tmp2_ = &b->X;
+
+ /* compare X_a*Z_b^2 with X_b*Z_a^2 */
+ if (BN_cmp(tmp1_, tmp2_) != 0)
+ {
+ ret = 1; /* points differ */
+ goto end;
+ }
+
+
+ if (!b->Z_is_one)
+ {
+ if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) goto end;
+ if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) goto end;
+ /* tmp1_ = tmp1 */
+ }
+ else
+ tmp1_ = &a->Y;
+ if (!a->Z_is_one)
+ {
+ if (!field_mul(group, Za23, Za23, &a->Z, ctx)) goto end;
+ if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) goto end;
+ /* tmp2_ = tmp2 */
+ }
+ else
+ tmp2_ = &b->Y;
+
+ /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
+ if (BN_cmp(tmp1_, tmp2_) != 0)
+ {
+ ret = 1; /* points differ */
+ goto end;
+ }
+
+ /* points are equal */
+ ret = 0;
+
+ end:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+ {
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y;
+ int ret = 0;
+
+ if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
+ return 1;
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (y == NULL) goto err;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
+ if (!point->Z_is_one)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+ }
+
+
+int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
+ {
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp0, *tmp1;
+ size_t pow2 = 0;
+ BIGNUM **heap = NULL;
+ size_t i;
+ int ret = 0;
+
+ if (num == 0)
+ return 1;
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ tmp0 = BN_CTX_get(ctx);
+ tmp1 = BN_CTX_get(ctx);
+ if (tmp0 == NULL || tmp1 == NULL) goto err;
+
+ /* Before converting the individual points, compute inverses of all Z values.
+ * Modular inversion is rather slow, but luckily we can do with a single
+ * explicit inversion, plus about 3 multiplications per input value.
+ */
+
+ pow2 = 1;
+ while (num > pow2)
+ pow2 <<= 1;
+ /* Now pow2 is the smallest power of 2 satifsying pow2 >= num.
+ * We need twice that. */
+ pow2 <<= 1;
+
+ heap = OPENSSL_malloc(pow2 * sizeof heap[0]);
+ if (heap == NULL) goto err;
+
+ /* The array is used as a binary tree, exactly as in heapsort:
+ *
+ * heap[1]
+ * heap[2] heap[3]
+ * heap[4] heap[5] heap[6] heap[7]
+ * heap[8]heap[9] heap[10]heap[11] heap[12]heap[13] heap[14] heap[15]
+ *
+ * We put the Z's in the last line;
+ * then we set each other node to the product of its two child-nodes (where
+ * empty or 0 entries are treated as ones);
+ * then we invert heap[1];
+ * then we invert each other node by replacing it by the product of its
+ * parent (after inversion) and its sibling (before inversion).
+ */
+ heap[0] = NULL;
+ for (i = pow2/2 - 1; i > 0; i--)
+ heap[i] = NULL;
+ for (i = 0; i < num; i++)
+ heap[pow2/2 + i] = &points[i]->Z;
+ for (i = pow2/2 + num; i < pow2; i++)
+ heap[i] = NULL;
+
+ /* set each node to the product of its children */
+ for (i = pow2/2 - 1; i > 0; i--)
+ {
+ heap[i] = BN_new();
+ if (heap[i] == NULL) goto err;
+
+ if (heap[2*i] != NULL)
+ {
+ if ((heap[2*i + 1] == NULL) || BN_is_zero(heap[2*i + 1]))
+ {
+ if (!BN_copy(heap[i], heap[2*i])) goto err;
+ }
+ else
+ {
+ if (BN_is_zero(heap[2*i]))
+ {
+ if (!BN_copy(heap[i], heap[2*i + 1])) goto err;
+ }
+ else
+ {
+ if (!group->meth->field_mul(group, heap[i],
+ heap[2*i], heap[2*i + 1], ctx)) goto err;
+ }
+ }
+ }
+ }
+
+ /* invert heap[1] */
+ if (!BN_is_zero(heap[1]))
+ {
+ if (!BN_mod_inverse(heap[1], heap[1], &group->field, ctx))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
+ goto err;
+ }
+ }
+ if (group->meth->field_encode != 0)
+ {
+ /* in the Montgomery case, we just turned R*H (representing H)
+ * into 1/(R*H), but we need R*(1/H) (representing 1/H);
+ * i.e. we have need to multiply by the Montgomery factor twice */
+ if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
+ if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err;
+ }
+
+ /* set other heap[i]'s to their inverses */
+ for (i = 2; i < pow2/2 + num; i += 2)
+ {
+ /* i is even */
+ if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1]))
+ {
+ if (!group->meth->field_mul(group, tmp0, heap[i/2], heap[i + 1], ctx)) goto err;
+ if (!group->meth->field_mul(group, tmp1, heap[i/2], heap[i], ctx)) goto err;
+ if (!BN_copy(heap[i], tmp0)) goto err;
+ if (!BN_copy(heap[i + 1], tmp1)) goto err;
+ }
+ else
+ {
+ if (!BN_copy(heap[i], heap[i/2])) goto err;
+ }
+ }
+
+ /* we have replaced all non-zero Z's by their inverses, now fix up all the points */
+ for (i = 0; i < num; i++)
+ {
+ EC_POINT *p = points[i];
+
+ if (!BN_is_zero(&p->Z))
+ {
+ /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
+
+ if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx)) goto err;
+ if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx)) goto err;
+
+ if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx)) goto err;
+ if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx)) goto err;
+
+ if (group->meth->field_set_to_one != 0)
+ {
+ if (!group->meth->field_set_to_one(group, &p->Z, ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_one(&p->Z)) goto err;
+ }
+ p->Z_is_one = 1;
+ }
+ }
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (heap != NULL)
+ {
+ /* heap[pow2/2] .. heap[pow2-1] have not been allocated locally! */
+ for (i = pow2/2 - 1; i > 0; i--)
+ {
+ if (heap[i] != NULL)
+ BN_clear_free(heap[i]);
+ }
+ OPENSSL_free(heap);
+ }
+ return ret;
+ }
+
+
+int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+ {
+ return BN_mod_mul(r, a, b, &group->field, ctx);
+ }
+
+
+int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
+ {
+ return BN_mod_sqr(r, a, &group->field, ctx);
+ }
diff --git a/openssl/crypto/engine/engine.h b/openssl/crypto/engine/engine.h
index c24e26d4c..943aeae21 100644
--- a/openssl/crypto/engine/engine.h
+++ b/openssl/crypto/engine/engine.h
@@ -1,833 +1,833 @@
-/* openssl/engine.h */
-/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
- * project 2000.
- */
-/* ====================================================================
- * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- * ECDH support in OpenSSL originally developed by
- * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
- */
-
-#ifndef HEADER_ENGINE_H
-#define HEADER_ENGINE_H
-
-#include <openssl/opensslconf.h>
-
-#ifdef OPENSSL_NO_ENGINE
-#error ENGINE is disabled.
-#endif
-
-#ifndef OPENSSL_NO_DEPRECATED
-#include <openssl/bn.h>
-#ifndef OPENSSL_NO_RSA
-#include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DSA
-#include <openssl/dsa.h>
-#endif
-#ifndef OPENSSL_NO_DH
-#include <openssl/dh.h>
-#endif
-#ifndef OPENSSL_NO_ECDH
-#include <openssl/ecdh.h>
-#endif
-#ifndef OPENSSL_NO_ECDSA
-#include <openssl/ecdsa.h>
-#endif
-#include <openssl/rand.h>
-#include <openssl/ui.h>
-#include <openssl/err.h>
-#endif
-
-#include <openssl/ossl_typ.h>
-#include <openssl/symhacks.h>
-
-#include <openssl/x509.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* These flags are used to control combinations of algorithm (methods)
- * by bitwise "OR"ing. */
-#define ENGINE_METHOD_RSA (unsigned int)0x0001
-#define ENGINE_METHOD_DSA (unsigned int)0x0002
-#define ENGINE_METHOD_DH (unsigned int)0x0004
-#define ENGINE_METHOD_RAND (unsigned int)0x0008
-#define ENGINE_METHOD_ECDH (unsigned int)0x0010
-#define ENGINE_METHOD_ECDSA (unsigned int)0x0020
-#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040
-#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
-#define ENGINE_METHOD_STORE (unsigned int)0x0100
-#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200
-#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400
-/* Obvious all-or-nothing cases. */
-#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
-#define ENGINE_METHOD_NONE (unsigned int)0x0000
-
-/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
- * internally to control registration of ENGINE implementations, and can be set
- * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
- * initialise registered ENGINEs if they are not already initialised. */
-#define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001
-
-/* ENGINE flags that can be set by ENGINE_set_flags(). */
-/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ /* Not used */
-
-/* This flag is for ENGINEs that wish to handle the various 'CMD'-related
- * control commands on their own. Without this flag, ENGINE_ctrl() handles these
- * control commands on behalf of the ENGINE using their "cmd_defns" data. */
-#define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002
-
-/* This flag is for ENGINEs who return new duplicate structures when found via
- * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl()
- * commands are called in sequence as part of some stateful process like
- * key-generation setup and execution), it can set this flag - then each attempt
- * to obtain the ENGINE will result in it being copied into a new structure.
- * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments
- * the existing ENGINE's structural reference count. */
-#define ENGINE_FLAGS_BY_ID_COPY (int)0x0004
-
-/* ENGINEs can support their own command types, and these flags are used in
- * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
- * command expects. Currently only numeric and string input is supported. If a
- * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options,
- * then it is regarded as an "internal" control command - and not for use in
- * config setting situations. As such, they're not available to the
- * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to
- * this list of 'command types' should be reflected carefully in
- * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */
-
-/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
-#define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001
-/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to
- * ENGINE_ctrl) */
-#define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002
-/* Indicates that the control command takes *no* input. Ie. the control command
- * is unparameterised. */
-#define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004
-/* Indicates that the control command is internal. This control command won't
- * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
- * function. */
-#define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008
-
-/* NB: These 3 control commands are deprecated and should not be used. ENGINEs
- * relying on these commands should compile conditional support for
- * compatibility (eg. if these symbols are defined) but should also migrate the
- * same functionality to their own ENGINE-specific control functions that can be
- * "discovered" by calling applications. The fact these control commands
- * wouldn't be "executable" (ie. usable by text-based config) doesn't change the
- * fact that application code can find and use them without requiring per-ENGINE
- * hacking. */
-
-/* These flags are used to tell the ctrl function what should be done.
- * All command numbers are shared between all engines, even if some don't
- * make sense to some engines. In such a case, they do nothing but return
- * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
-#define ENGINE_CTRL_SET_LOGSTREAM 1
-#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2
-#define ENGINE_CTRL_HUP 3 /* Close and reinitialise any
- handles/connections etc. */
-#define ENGINE_CTRL_SET_USER_INTERFACE 4 /* Alternative to callback */
-#define ENGINE_CTRL_SET_CALLBACK_DATA 5 /* User-specific data, used
- when calling the password
- callback and the user
- interface */
-#define ENGINE_CTRL_LOAD_CONFIGURATION 6 /* Load a configuration, given
- a string that represents a
- file name or so */
-#define ENGINE_CTRL_LOAD_SECTION 7 /* Load data from a given
- section in the already loaded
- configuration */
-
-/* These control commands allow an application to deal with an arbitrary engine
- * in a dynamic way. Warn: Negative return values indicate errors FOR THESE
- * COMMANDS because zero is used to indicate 'end-of-list'. Other commands,
- * including ENGINE-specific command types, return zero for an error.
- *
- * An ENGINE can choose to implement these ctrl functions, and can internally
- * manage things however it chooses - it does so by setting the
- * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the
- * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns
- * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl()
- * handler need only implement its own commands - the above "meta" commands will
- * be taken care of. */
-
-/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then
- * all the remaining control commands will return failure, so it is worth
- * checking this first if the caller is trying to "discover" the engine's
- * capabilities and doesn't want errors generated unnecessarily. */
-#define ENGINE_CTRL_HAS_CTRL_FUNCTION 10
-/* Returns a positive command number for the first command supported by the
- * engine. Returns zero if no ctrl commands are supported. */
-#define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11
-/* The 'long' argument specifies a command implemented by the engine, and the
- * return value is the next command supported, or zero if there are no more. */
-#define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12
-/* The 'void*' argument is a command name (cast from 'const char *'), and the
- * return value is the command that corresponds to it. */
-#define ENGINE_CTRL_GET_CMD_FROM_NAME 13
-/* The next two allow a command to be converted into its corresponding string
- * form. In each case, the 'long' argument supplies the command. In the NAME_LEN
- * case, the return value is the length of the command name (not counting a
- * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer
- * large enough, and it will be populated with the name of the command (WITH a
- * trailing EOL). */
-#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14
-#define ENGINE_CTRL_GET_NAME_FROM_CMD 15
-/* The next two are similar but give a "short description" of a command. */
-#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16
-#define ENGINE_CTRL_GET_DESC_FROM_CMD 17
-/* With this command, the return value is the OR'd combination of
- * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
- * engine-specific ctrl command expects. */
-#define ENGINE_CTRL_GET_CMD_FLAGS 18
-
-/* ENGINE implementations should start the numbering of their own control
- * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */
-#define ENGINE_CMD_BASE 200
-
-/* NB: These 2 nCipher "chil" control commands are deprecated, and their
- * functionality is now available through ENGINE-specific control commands
- * (exposed through the above-mentioned 'CMD'-handling). Code using these 2
- * commands should be migrated to the more general command handling before these
- * are removed. */
-
-/* Flags specific to the nCipher "chil" engine */
-#define ENGINE_CTRL_CHIL_SET_FORKCHECK 100
- /* Depending on the value of the (long)i argument, this sets or
- * unsets the SimpleForkCheck flag in the CHIL API to enable or
- * disable checking and workarounds for applications that fork().
- */
-#define ENGINE_CTRL_CHIL_NO_LOCKING 101
- /* This prevents the initialisation function from providing mutex
- * callbacks to the nCipher library. */
-
-/* If an ENGINE supports its own specific control commands and wishes the
- * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its
- * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries
- * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that
- * supports the stated commands (ie. the "cmd_num" entries as described by the
- * array). NB: The array must be ordered in increasing order of cmd_num.
- * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set
- * to zero and/or cmd_name set to NULL. */
-typedef struct ENGINE_CMD_DEFN_st
- {
- unsigned int cmd_num; /* The command number */
- const char *cmd_name; /* The command name itself */
- const char *cmd_desc; /* A short description of the command */
- unsigned int cmd_flags; /* The input the command expects */
- } ENGINE_CMD_DEFN;
-
-/* Generic function pointer */
-typedef int (*ENGINE_GEN_FUNC_PTR)(void);
-/* Generic function pointer taking no arguments */
-typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
-/* Specific control function pointer */
-typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void));
-/* Generic load_key function pointer */
-typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
- UI_METHOD *ui_method, void *callback_data);
-typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,
- STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
- STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
-/* These callback types are for an ENGINE's handler for cipher and digest logic.
- * These handlers have these prototypes;
- * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
- * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
- * Looking at how to implement these handlers in the case of cipher support, if
- * the framework wants the EVP_CIPHER for 'nid', it will call;
- * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure)
- * If the framework wants a list of supported 'nid's, it will call;
- * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
- */
-/* Returns to a pointer to the array of supported cipher 'nid's. If the second
- * parameter is non-NULL it is set to the size of the returned array. */
-typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
-typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
-typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
-typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
-/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
- * structures where the pointers have a "structural reference". This means that
- * their reference is to allowed access to the structure but it does not imply
- * that the structure is functional. To simply increment or decrement the
- * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not
- * required when iterating using ENGINE_get_next as it will automatically
- * decrement the structural reference count of the "current" ENGINE and
- * increment the structural reference count of the ENGINE it returns (unless it
- * is NULL). */
-
-/* Get the first/last "ENGINE" type available. */
-ENGINE *ENGINE_get_first(void);
-ENGINE *ENGINE_get_last(void);
-/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
-ENGINE *ENGINE_get_next(ENGINE *e);
-ENGINE *ENGINE_get_prev(ENGINE *e);
-/* Add another "ENGINE" type into the array. */
-int ENGINE_add(ENGINE *e);
-/* Remove an existing "ENGINE" type from the array. */
-int ENGINE_remove(ENGINE *e);
-/* Retrieve an engine from the list by its unique "id" value. */
-ENGINE *ENGINE_by_id(const char *id);
-/* Add all the built-in engines. */
-void ENGINE_load_openssl(void);
-void ENGINE_load_dynamic(void);
-#ifndef OPENSSL_NO_STATIC_ENGINE
-void ENGINE_load_4758cca(void);
-void ENGINE_load_aep(void);
-void ENGINE_load_atalla(void);
-void ENGINE_load_chil(void);
-void ENGINE_load_cswift(void);
-void ENGINE_load_nuron(void);
-void ENGINE_load_sureware(void);
-void ENGINE_load_ubsec(void);
-void ENGINE_load_padlock(void);
-void ENGINE_load_capi(void);
-#ifndef OPENSSL_NO_GMP
-void ENGINE_load_gmp(void);
-#endif
-#ifndef OPENSSL_NO_GOST
-void ENGINE_load_gost(void);
-#endif
-#endif
-void ENGINE_load_cryptodev(void);
-void ENGINE_load_builtin_engines(void);
-
-/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
- * "registry" handling. */
-unsigned int ENGINE_get_table_flags(void);
-void ENGINE_set_table_flags(unsigned int flags);
-
-/* Manage registration of ENGINEs per "table". For each type, there are 3
- * functions;
- * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
- * ENGINE_unregister_***(e) - unregister the implementation from 'e'
- * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
- * Cleanup is automatically registered from each table when required, so
- * ENGINE_cleanup() will reverse any "register" operations. */
-
-int ENGINE_register_RSA(ENGINE *e);
-void ENGINE_unregister_RSA(ENGINE *e);
-void ENGINE_register_all_RSA(void);
-
-int ENGINE_register_DSA(ENGINE *e);
-void ENGINE_unregister_DSA(ENGINE *e);
-void ENGINE_register_all_DSA(void);
-
-int ENGINE_register_ECDH(ENGINE *e);
-void ENGINE_unregister_ECDH(ENGINE *e);
-void ENGINE_register_all_ECDH(void);
-
-int ENGINE_register_ECDSA(ENGINE *e);
-void ENGINE_unregister_ECDSA(ENGINE *e);
-void ENGINE_register_all_ECDSA(void);
-
-int ENGINE_register_DH(ENGINE *e);
-void ENGINE_unregister_DH(ENGINE *e);
-void ENGINE_register_all_DH(void);
-
-int ENGINE_register_RAND(ENGINE *e);
-void ENGINE_unregister_RAND(ENGINE *e);
-void ENGINE_register_all_RAND(void);
-
-int ENGINE_register_STORE(ENGINE *e);
-void ENGINE_unregister_STORE(ENGINE *e);
-void ENGINE_register_all_STORE(void);
-
-int ENGINE_register_ciphers(ENGINE *e);
-void ENGINE_unregister_ciphers(ENGINE *e);
-void ENGINE_register_all_ciphers(void);
-
-int ENGINE_register_digests(ENGINE *e);
-void ENGINE_unregister_digests(ENGINE *e);
-void ENGINE_register_all_digests(void);
-
-int ENGINE_register_pkey_meths(ENGINE *e);
-void ENGINE_unregister_pkey_meths(ENGINE *e);
-void ENGINE_register_all_pkey_meths(void);
-
-int ENGINE_register_pkey_asn1_meths(ENGINE *e);
-void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
-void ENGINE_register_all_pkey_asn1_meths(void);
-
-/* These functions register all support from the above categories. Note, use of
- * these functions can result in static linkage of code your application may not
- * need. If you only need a subset of functionality, consider using more
- * selective initialisation. */
-int ENGINE_register_complete(ENGINE *e);
-int ENGINE_register_all_complete(void);
-
-/* Send parametrised control commands to the engine. The possibilities to send
- * down an integer, a pointer to data or a function pointer are provided. Any of
- * the parameters may or may not be NULL, depending on the command number. In
- * actuality, this function only requires a structural (rather than functional)
- * reference to an engine, but many control commands may require the engine be
- * functional. The caller should be aware of trying commands that require an
- * operational ENGINE, and only use functional references in such situations. */
-int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
-
-/* This function tests if an ENGINE-specific command is usable as a "setting".
- * Eg. in an application's config file that gets processed through
- * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
- * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */
-int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
-
-/* This function works like ENGINE_ctrl() with the exception of taking a
- * command name instead of a command number, and can handle optional commands.
- * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to
- * use the cmd_name and cmd_optional. */
-int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
- long i, void *p, void (*f)(void), int cmd_optional);
-
-/* This function passes a command-name and argument to an ENGINE. The cmd_name
- * is converted to a command number and the control command is called using
- * 'arg' as an argument (unless the ENGINE doesn't support such a command, in
- * which case no control command is called). The command is checked for input
- * flags, and if necessary the argument will be converted to a numeric value. If
- * cmd_optional is non-zero, then if the ENGINE doesn't support the given
- * cmd_name the return value will be success anyway. This function is intended
- * for applications to use so that users (or config files) can supply
- * engine-specific config data to the ENGINE at run-time to control behaviour of
- * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl()
- * functions that return data, deal with binary data, or that are otherwise
- * supposed to be used directly through ENGINE_ctrl() in application code. Any
- * "return" data from an ENGINE_ctrl() operation in this function will be lost -
- * the return value is interpreted as failure if the return value is zero,
- * success otherwise, and this function returns a boolean value as a result. In
- * other words, vendors of 'ENGINE'-enabled devices should write ENGINE
- * implementations with parameterisations that work in this scheme, so that
- * compliant ENGINE-based applications can work consistently with the same
- * configuration for the same ENGINE-enabled devices, across applications. */
-int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
- int cmd_optional);
-
-/* These functions are useful for manufacturing new ENGINE structures. They
- * don't address reference counting at all - one uses them to populate an ENGINE
- * structure with personalised implementations of things prior to using it
- * directly or adding it to the builtin ENGINE list in OpenSSL. These are also
- * here so that the ENGINE structure doesn't have to be exposed and break binary
- * compatibility! */
-ENGINE *ENGINE_new(void);
-int ENGINE_free(ENGINE *e);
-int ENGINE_up_ref(ENGINE *e);
-int ENGINE_set_id(ENGINE *e, const char *id);
-int ENGINE_set_name(ENGINE *e, const char *name);
-int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
-int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
-int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
-int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
-int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
-int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
-int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
-int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
-int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
-int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
-int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
-int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
-int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
-int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
- ENGINE_SSL_CLIENT_CERT_PTR loadssl_f);
-int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
-int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
-int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
-int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
-int ENGINE_set_flags(ENGINE *e, int flags);
-int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
-/* These functions allow control over any per-structure ENGINE data. */
-int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
- CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
-int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
-void *ENGINE_get_ex_data(const ENGINE *e, int idx);
-
-/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
- * automatically ensures the list cleanup function is registered to be called
- * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure
- * ENGINE_cleanup() will clean up after them. */
-void ENGINE_cleanup(void);
-
-/* These return values from within the ENGINE structure. These can be useful
- * with functional references as well as structural references - it depends
- * which you obtained. Using the result for functional purposes if you only
- * obtained a structural reference may be problematic! */
-const char *ENGINE_get_id(const ENGINE *e);
-const char *ENGINE_get_name(const ENGINE *e);
-const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
-const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
-const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
-const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
-const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
-const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
-const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
-ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
-ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
-ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
-ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
-ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
-ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
-ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e);
-ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
-ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
-ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
-ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
-const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
-const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
-const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
-const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
-const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
- const char *str, int len);
-const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
- const char *str, int len);
-const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
-int ENGINE_get_flags(const ENGINE *e);
-
-/* FUNCTIONAL functions. These functions deal with ENGINE structures
- * that have (or will) be initialised for use. Broadly speaking, the
- * structural functions are useful for iterating the list of available
- * engine types, creating new engine types, and other "list" operations.
- * These functions actually deal with ENGINEs that are to be used. As
- * such these functions can fail (if applicable) when particular
- * engines are unavailable - eg. if a hardware accelerator is not
- * attached or not functioning correctly. Each ENGINE has 2 reference
- * counts; structural and functional. Every time a functional reference
- * is obtained or released, a corresponding structural reference is
- * automatically obtained or released too. */
-
-/* Initialise a engine type for use (or up its reference count if it's
- * already in use). This will fail if the engine is not currently
- * operational and cannot initialise. */
-int ENGINE_init(ENGINE *e);
-/* Free a functional reference to a engine type. This does not require
- * a corresponding call to ENGINE_free as it also releases a structural
- * reference. */
-int ENGINE_finish(ENGINE *e);
-
-/* The following functions handle keys that are stored in some secondary
- * location, handled by the engine. The storage may be on a card or
- * whatever. */
-EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
- UI_METHOD *ui_method, void *callback_data);
-EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
- UI_METHOD *ui_method, void *callback_data);
-int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
- STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
- STACK_OF(X509) **pother,
- UI_METHOD *ui_method, void *callback_data);
-
-/* This returns a pointer for the current ENGINE structure that
- * is (by default) performing any RSA operations. The value returned
- * is an incremented reference, so it should be free'd (ENGINE_finish)
- * before it is discarded. */
-ENGINE *ENGINE_get_default_RSA(void);
-/* Same for the other "methods" */
-ENGINE *ENGINE_get_default_DSA(void);
-ENGINE *ENGINE_get_default_ECDH(void);
-ENGINE *ENGINE_get_default_ECDSA(void);
-ENGINE *ENGINE_get_default_DH(void);
-ENGINE *ENGINE_get_default_RAND(void);
-/* These functions can be used to get a functional reference to perform
- * ciphering or digesting corresponding to "nid". */
-ENGINE *ENGINE_get_cipher_engine(int nid);
-ENGINE *ENGINE_get_digest_engine(int nid);
-ENGINE *ENGINE_get_pkey_meth_engine(int nid);
-ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
-
-/* This sets a new default ENGINE structure for performing RSA
- * operations. If the result is non-zero (success) then the ENGINE
- * structure will have had its reference count up'd so the caller
- * should still free their own reference 'e'. */
-int ENGINE_set_default_RSA(ENGINE *e);
-int ENGINE_set_default_string(ENGINE *e, const char *def_list);
-/* Same for the other "methods" */
-int ENGINE_set_default_DSA(ENGINE *e);
-int ENGINE_set_default_ECDH(ENGINE *e);
-int ENGINE_set_default_ECDSA(ENGINE *e);
-int ENGINE_set_default_DH(ENGINE *e);
-int ENGINE_set_default_RAND(ENGINE *e);
-int ENGINE_set_default_ciphers(ENGINE *e);
-int ENGINE_set_default_digests(ENGINE *e);
-int ENGINE_set_default_pkey_meths(ENGINE *e);
-int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
-
-/* The combination "set" - the flags are bitwise "OR"d from the
- * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
- * function, this function can result in unnecessary static linkage. If your
- * application requires only specific functionality, consider using more
- * selective functions. */
-int ENGINE_set_default(ENGINE *e, unsigned int flags);
-
-void ENGINE_add_conf_module(void);
-
-/* Deprecated functions ... */
-/* int ENGINE_clear_defaults(void); */
-
-/**************************/
-/* DYNAMIC ENGINE SUPPORT */
-/**************************/
-
-/* Binary/behaviour compatibility levels */
-#define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000
-/* Binary versions older than this are too old for us (whether we're a loader or
- * a loadee) */
-#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000
-
-/* When compiling an ENGINE entirely as an external shared library, loadable by
- * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
- * type provides the calling application's (or library's) error functionality
- * and memory management function pointers to the loaded library. These should
- * be used/set in the loaded library code so that the loading application's
- * 'state' will be used/changed in all operations. The 'static_state' pointer
- * allows the loaded library to know if it shares the same static data as the
- * calling application (or library), and thus whether these callbacks need to be
- * set or not. */
-typedef void *(*dyn_MEM_malloc_cb)(size_t);
-typedef void *(*dyn_MEM_realloc_cb)(void *, size_t);
-typedef void (*dyn_MEM_free_cb)(void *);
-typedef struct st_dynamic_MEM_fns {
- dyn_MEM_malloc_cb malloc_cb;
- dyn_MEM_realloc_cb realloc_cb;
- dyn_MEM_free_cb free_cb;
- } dynamic_MEM_fns;
-/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use
- * these types so we (and any other dependant code) can simplify a bit?? */
-typedef void (*dyn_lock_locking_cb)(int,int,const char *,int);
-typedef int (*dyn_lock_add_lock_cb)(int*,int,int,const char *,int);
-typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)(
- const char *,int);
-typedef void (*dyn_dynlock_lock_cb)(int,struct CRYPTO_dynlock_value *,
- const char *,int);
-typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *,
- const char *,int);
-typedef struct st_dynamic_LOCK_fns {
- dyn_lock_locking_cb lock_locking_cb;
- dyn_lock_add_lock_cb lock_add_lock_cb;
- dyn_dynlock_create_cb dynlock_create_cb;
- dyn_dynlock_lock_cb dynlock_lock_cb;
- dyn_dynlock_destroy_cb dynlock_destroy_cb;
- } dynamic_LOCK_fns;
-/* The top-level structure */
-typedef struct st_dynamic_fns {
- void *static_state;
- const ERR_FNS *err_fns;
- const CRYPTO_EX_DATA_IMPL *ex_data_fns;
- dynamic_MEM_fns mem_fns;
- dynamic_LOCK_fns lock_fns;
- } dynamic_fns;
-
-/* The version checking function should be of this prototype. NB: The
- * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code.
- * If this function returns zero, it indicates a (potential) version
- * incompatibility and the loaded library doesn't believe it can proceed.
- * Otherwise, the returned value is the (latest) version supported by the
- * loading library. The loader may still decide that the loaded code's version
- * is unsatisfactory and could veto the load. The function is expected to
- * be implemented with the symbol name "v_check", and a default implementation
- * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
-typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
-#define IMPLEMENT_DYNAMIC_CHECK_FN() \
- OPENSSL_EXPORT unsigned long v_check(unsigned long v); \
- OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
- if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
- return 0; }
-
-/* This function is passed the ENGINE structure to initialise with its own
- * function and command settings. It should not adjust the structural or
- * functional reference counts. If this function returns zero, (a) the load will
- * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the
- * structure, and (c) the shared library will be unloaded. So implementations
- * should do their own internal cleanup in failure circumstances otherwise they
- * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that
- * the loader is looking for. If this is NULL, the shared library can choose to
- * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared
- * library must initialise only an ENGINE matching the passed 'id'. The function
- * is expected to be implemented with the symbol name "bind_engine". A standard
- * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where
- * the parameter 'fn' is a callback function that populates the ENGINE structure
- * and returns an int value (zero for failure). 'fn' should have prototype;
- * [static] int fn(ENGINE *e, const char *id); */
-typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
- const dynamic_fns *fns);
-#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
- OPENSSL_EXPORT \
- int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \
- OPENSSL_EXPORT \
- int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
- if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
- if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
- fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
- return 0; \
- CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
- CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
- CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
- CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
- CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
- if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
- return 0; \
- if(!ERR_set_implementation(fns->err_fns)) return 0; \
- skip_cbs: \
- if(!fn(e,id)) return 0; \
- return 1; }
-
-/* If the loading application (or library) and the loaded ENGINE library share
- * the same static data (eg. they're both dynamically linked to the same
- * libcrypto.so) we need a way to avoid trying to set system callbacks - this
- * would fail, and for the same reason that it's unnecessary to try. If the
- * loaded ENGINE has (or gets from through the loader) its own copy of the
- * libcrypto static data, we will need to set the callbacks. The easiest way to
- * detect this is to have a function that returns a pointer to some static data
- * and let the loading application and loaded ENGINE compare their respective
- * values. */
-void *ENGINE_get_static_state(void);
-
-#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
-void ENGINE_setup_bsd_cryptodev(void);
-#endif
-
-/* BEGIN ERROR CODES */
-/* The following lines are auto generated by the script mkerr.pl. Any changes
- * made after this point may be overwritten when the script is next run.
- */
-void ERR_load_ENGINE_strings(void);
-
-/* Error codes for the ENGINE functions. */
-
-/* Function codes. */
-#define ENGINE_F_DYNAMIC_CTRL 180
-#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181
-#define ENGINE_F_DYNAMIC_LOAD 182
-#define ENGINE_F_DYNAMIC_SET_DATA_CTX 183
-#define ENGINE_F_ENGINE_ADD 105
-#define ENGINE_F_ENGINE_BY_ID 106
-#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170
-#define ENGINE_F_ENGINE_CTRL 142
-#define ENGINE_F_ENGINE_CTRL_CMD 178
-#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171
-#define ENGINE_F_ENGINE_FINISH 107
-#define ENGINE_F_ENGINE_FREE_UTIL 108
-#define ENGINE_F_ENGINE_GET_CIPHER 185
-#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177
-#define ENGINE_F_ENGINE_GET_DIGEST 186
-#define ENGINE_F_ENGINE_GET_NEXT 115
-#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193
-#define ENGINE_F_ENGINE_GET_PKEY_METH 192
-#define ENGINE_F_ENGINE_GET_PREV 116
-#define ENGINE_F_ENGINE_INIT 119
-#define ENGINE_F_ENGINE_LIST_ADD 120
-#define ENGINE_F_ENGINE_LIST_REMOVE 121
-#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
-#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
-#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194
-#define ENGINE_F_ENGINE_NEW 122
-#define ENGINE_F_ENGINE_REMOVE 123
-#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189
-#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126
-#define ENGINE_F_ENGINE_SET_ID 129
-#define ENGINE_F_ENGINE_SET_NAME 130
-#define ENGINE_F_ENGINE_TABLE_REGISTER 184
-#define ENGINE_F_ENGINE_UNLOAD_KEY 152
-#define ENGINE_F_ENGINE_UNLOCKED_FINISH 191
-#define ENGINE_F_ENGINE_UP_REF 190
-#define ENGINE_F_INT_CTRL_HELPER 172
-#define ENGINE_F_INT_ENGINE_CONFIGURE 188
-#define ENGINE_F_INT_ENGINE_MODULE_INIT 187
-#define ENGINE_F_LOG_MESSAGE 141
-
-/* Reason codes. */
-#define ENGINE_R_ALREADY_LOADED 100
-#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133
-#define ENGINE_R_CMD_NOT_EXECUTABLE 134
-#define ENGINE_R_COMMAND_TAKES_INPUT 135
-#define ENGINE_R_COMMAND_TAKES_NO_INPUT 136
-#define ENGINE_R_CONFLICTING_ENGINE_ID 103
-#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119
-#define ENGINE_R_DH_NOT_IMPLEMENTED 139
-#define ENGINE_R_DSA_NOT_IMPLEMENTED 140
-#define ENGINE_R_DSO_FAILURE 104
-#define ENGINE_R_DSO_NOT_FOUND 132
-#define ENGINE_R_ENGINES_SECTION_ERROR 148
-#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102
-#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
-#define ENGINE_R_ENGINE_SECTION_ERROR 149
-#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
-#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129
-#define ENGINE_R_FINISH_FAILED 106
-#define ENGINE_R_GET_HANDLE_FAILED 107
-#define ENGINE_R_ID_OR_NAME_MISSING 108
-#define ENGINE_R_INIT_FAILED 109
-#define ENGINE_R_INTERNAL_LIST_ERROR 110
-#define ENGINE_R_INVALID_ARGUMENT 143
-#define ENGINE_R_INVALID_CMD_NAME 137
-#define ENGINE_R_INVALID_CMD_NUMBER 138
-#define ENGINE_R_INVALID_INIT_VALUE 151
-#define ENGINE_R_INVALID_STRING 150
-#define ENGINE_R_NOT_INITIALISED 117
-#define ENGINE_R_NOT_LOADED 112
-#define ENGINE_R_NO_CONTROL_FUNCTION 120
-#define ENGINE_R_NO_INDEX 144
-#define ENGINE_R_NO_LOAD_FUNCTION 125
-#define ENGINE_R_NO_REFERENCE 130
-#define ENGINE_R_NO_SUCH_ENGINE 116
-#define ENGINE_R_NO_UNLOAD_FUNCTION 126
-#define ENGINE_R_PROVIDE_PARAMETERS 113
-#define ENGINE_R_RSA_NOT_IMPLEMENTED 141
-#define ENGINE_R_UNIMPLEMENTED_CIPHER 146
-#define ENGINE_R_UNIMPLEMENTED_DIGEST 147
-#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101
-#define ENGINE_R_VERSION_INCOMPATIBILITY 145
-
-#ifdef __cplusplus
-}
-#endif
-#endif
+/* openssl/engine.h */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_ENGINE_H
+#define HEADER_ENGINE_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_ENGINE
+#error ENGINE is disabled.
+#endif
+
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#ifndef OPENSSL_NO_ECDH
+#include <openssl/ecdh.h>
+#endif
+#ifndef OPENSSL_NO_ECDSA
+#include <openssl/ecdsa.h>
+#endif
+#include <openssl/rand.h>
+#include <openssl/ui.h>
+#include <openssl/err.h>
+#endif
+
+#include <openssl/ossl_typ.h>
+#include <openssl/symhacks.h>
+
+#include <openssl/x509.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* These flags are used to control combinations of algorithm (methods)
+ * by bitwise "OR"ing. */
+#define ENGINE_METHOD_RSA (unsigned int)0x0001
+#define ENGINE_METHOD_DSA (unsigned int)0x0002
+#define ENGINE_METHOD_DH (unsigned int)0x0004
+#define ENGINE_METHOD_RAND (unsigned int)0x0008
+#define ENGINE_METHOD_ECDH (unsigned int)0x0010
+#define ENGINE_METHOD_ECDSA (unsigned int)0x0020
+#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040
+#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
+#define ENGINE_METHOD_STORE (unsigned int)0x0100
+#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200
+#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400
+/* Obvious all-or-nothing cases. */
+#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
+#define ENGINE_METHOD_NONE (unsigned int)0x0000
+
+/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
+ * internally to control registration of ENGINE implementations, and can be set
+ * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
+ * initialise registered ENGINEs if they are not already initialised. */
+#define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001
+
+/* ENGINE flags that can be set by ENGINE_set_flags(). */
+/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ /* Not used */
+
+/* This flag is for ENGINEs that wish to handle the various 'CMD'-related
+ * control commands on their own. Without this flag, ENGINE_ctrl() handles these
+ * control commands on behalf of the ENGINE using their "cmd_defns" data. */
+#define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002
+
+/* This flag is for ENGINEs who return new duplicate structures when found via
+ * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl()
+ * commands are called in sequence as part of some stateful process like
+ * key-generation setup and execution), it can set this flag - then each attempt
+ * to obtain the ENGINE will result in it being copied into a new structure.
+ * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments
+ * the existing ENGINE's structural reference count. */
+#define ENGINE_FLAGS_BY_ID_COPY (int)0x0004
+
+/* ENGINEs can support their own command types, and these flags are used in
+ * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
+ * command expects. Currently only numeric and string input is supported. If a
+ * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options,
+ * then it is regarded as an "internal" control command - and not for use in
+ * config setting situations. As such, they're not available to the
+ * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to
+ * this list of 'command types' should be reflected carefully in
+ * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */
+
+/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
+#define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001
+/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to
+ * ENGINE_ctrl) */
+#define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002
+/* Indicates that the control command takes *no* input. Ie. the control command
+ * is unparameterised. */
+#define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004
+/* Indicates that the control command is internal. This control command won't
+ * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
+ * function. */
+#define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008
+
+/* NB: These 3 control commands are deprecated and should not be used. ENGINEs
+ * relying on these commands should compile conditional support for
+ * compatibility (eg. if these symbols are defined) but should also migrate the
+ * same functionality to their own ENGINE-specific control functions that can be
+ * "discovered" by calling applications. The fact these control commands
+ * wouldn't be "executable" (ie. usable by text-based config) doesn't change the
+ * fact that application code can find and use them without requiring per-ENGINE
+ * hacking. */
+
+/* These flags are used to tell the ctrl function what should be done.
+ * All command numbers are shared between all engines, even if some don't
+ * make sense to some engines. In such a case, they do nothing but return
+ * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
+#define ENGINE_CTRL_SET_LOGSTREAM 1
+#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2
+#define ENGINE_CTRL_HUP 3 /* Close and reinitialise any
+ handles/connections etc. */
+#define ENGINE_CTRL_SET_USER_INTERFACE 4 /* Alternative to callback */
+#define ENGINE_CTRL_SET_CALLBACK_DATA 5 /* User-specific data, used
+ when calling the password
+ callback and the user
+ interface */
+#define ENGINE_CTRL_LOAD_CONFIGURATION 6 /* Load a configuration, given
+ a string that represents a
+ file name or so */
+#define ENGINE_CTRL_LOAD_SECTION 7 /* Load data from a given
+ section in the already loaded
+ configuration */
+
+/* These control commands allow an application to deal with an arbitrary engine
+ * in a dynamic way. Warn: Negative return values indicate errors FOR THESE
+ * COMMANDS because zero is used to indicate 'end-of-list'. Other commands,
+ * including ENGINE-specific command types, return zero for an error.
+ *
+ * An ENGINE can choose to implement these ctrl functions, and can internally
+ * manage things however it chooses - it does so by setting the
+ * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the
+ * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns
+ * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl()
+ * handler need only implement its own commands - the above "meta" commands will
+ * be taken care of. */
+
+/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then
+ * all the remaining control commands will return failure, so it is worth
+ * checking this first if the caller is trying to "discover" the engine's
+ * capabilities and doesn't want errors generated unnecessarily. */
+#define ENGINE_CTRL_HAS_CTRL_FUNCTION 10
+/* Returns a positive command number for the first command supported by the
+ * engine. Returns zero if no ctrl commands are supported. */
+#define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11
+/* The 'long' argument specifies a command implemented by the engine, and the
+ * return value is the next command supported, or zero if there are no more. */
+#define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12
+/* The 'void*' argument is a command name (cast from 'const char *'), and the
+ * return value is the command that corresponds to it. */
+#define ENGINE_CTRL_GET_CMD_FROM_NAME 13
+/* The next two allow a command to be converted into its corresponding string
+ * form. In each case, the 'long' argument supplies the command. In the NAME_LEN
+ * case, the return value is the length of the command name (not counting a
+ * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer
+ * large enough, and it will be populated with the name of the command (WITH a
+ * trailing EOL). */
+#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14
+#define ENGINE_CTRL_GET_NAME_FROM_CMD 15
+/* The next two are similar but give a "short description" of a command. */
+#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16
+#define ENGINE_CTRL_GET_DESC_FROM_CMD 17
+/* With this command, the return value is the OR'd combination of
+ * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
+ * engine-specific ctrl command expects. */
+#define ENGINE_CTRL_GET_CMD_FLAGS 18
+
+/* ENGINE implementations should start the numbering of their own control
+ * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */
+#define ENGINE_CMD_BASE 200
+
+/* NB: These 2 nCipher "chil" control commands are deprecated, and their
+ * functionality is now available through ENGINE-specific control commands
+ * (exposed through the above-mentioned 'CMD'-handling). Code using these 2
+ * commands should be migrated to the more general command handling before these
+ * are removed. */
+
+/* Flags specific to the nCipher "chil" engine */
+#define ENGINE_CTRL_CHIL_SET_FORKCHECK 100
+ /* Depending on the value of the (long)i argument, this sets or
+ * unsets the SimpleForkCheck flag in the CHIL API to enable or
+ * disable checking and workarounds for applications that fork().
+ */
+#define ENGINE_CTRL_CHIL_NO_LOCKING 101
+ /* This prevents the initialisation function from providing mutex
+ * callbacks to the nCipher library. */
+
+/* If an ENGINE supports its own specific control commands and wishes the
+ * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its
+ * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries
+ * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that
+ * supports the stated commands (ie. the "cmd_num" entries as described by the
+ * array). NB: The array must be ordered in increasing order of cmd_num.
+ * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set
+ * to zero and/or cmd_name set to NULL. */
+typedef struct ENGINE_CMD_DEFN_st
+ {
+ unsigned int cmd_num; /* The command number */
+ const char *cmd_name; /* The command name itself */
+ const char *cmd_desc; /* A short description of the command */
+ unsigned int cmd_flags; /* The input the command expects */
+ } ENGINE_CMD_DEFN;
+
+/* Generic function pointer */
+typedef int (*ENGINE_GEN_FUNC_PTR)(void);
+/* Generic function pointer taking no arguments */
+typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
+/* Specific control function pointer */
+typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void));
+/* Generic load_key function pointer */
+typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
+ UI_METHOD *ui_method, void *callback_data);
+typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,
+ STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
+ STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
+/* These callback types are for an ENGINE's handler for cipher and digest logic.
+ * These handlers have these prototypes;
+ * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
+ * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
+ * Looking at how to implement these handlers in the case of cipher support, if
+ * the framework wants the EVP_CIPHER for 'nid', it will call;
+ * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure)
+ * If the framework wants a list of supported 'nid's, it will call;
+ * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
+ */
+/* Returns to a pointer to the array of supported cipher 'nid's. If the second
+ * parameter is non-NULL it is set to the size of the returned array. */
+typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
+typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
+typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
+typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
+/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
+ * structures where the pointers have a "structural reference". This means that
+ * their reference is to allowed access to the structure but it does not imply
+ * that the structure is functional. To simply increment or decrement the
+ * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not
+ * required when iterating using ENGINE_get_next as it will automatically
+ * decrement the structural reference count of the "current" ENGINE and
+ * increment the structural reference count of the ENGINE it returns (unless it
+ * is NULL). */
+
+/* Get the first/last "ENGINE" type available. */
+ENGINE *ENGINE_get_first(void);
+ENGINE *ENGINE_get_last(void);
+/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
+ENGINE *ENGINE_get_next(ENGINE *e);
+ENGINE *ENGINE_get_prev(ENGINE *e);
+/* Add another "ENGINE" type into the array. */
+int ENGINE_add(ENGINE *e);
+/* Remove an existing "ENGINE" type from the array. */
+int ENGINE_remove(ENGINE *e);
+/* Retrieve an engine from the list by its unique "id" value. */
+ENGINE *ENGINE_by_id(const char *id);
+/* Add all the built-in engines. */
+void ENGINE_load_openssl(void);
+void ENGINE_load_dynamic(void);
+#ifndef OPENSSL_NO_STATIC_ENGINE
+void ENGINE_load_4758cca(void);
+void ENGINE_load_aep(void);
+void ENGINE_load_atalla(void);
+void ENGINE_load_chil(void);
+void ENGINE_load_cswift(void);
+void ENGINE_load_nuron(void);
+void ENGINE_load_sureware(void);
+void ENGINE_load_ubsec(void);
+void ENGINE_load_padlock(void);
+void ENGINE_load_capi(void);
+#ifndef OPENSSL_NO_GMP
+void ENGINE_load_gmp(void);
+#endif
+#ifndef OPENSSL_NO_GOST
+void ENGINE_load_gost(void);
+#endif
+#endif
+void ENGINE_load_cryptodev(void);
+void ENGINE_load_builtin_engines(void);
+
+/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
+ * "registry" handling. */
+unsigned int ENGINE_get_table_flags(void);
+void ENGINE_set_table_flags(unsigned int flags);
+
+/* Manage registration of ENGINEs per "table". For each type, there are 3
+ * functions;
+ * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
+ * ENGINE_unregister_***(e) - unregister the implementation from 'e'
+ * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
+ * Cleanup is automatically registered from each table when required, so
+ * ENGINE_cleanup() will reverse any "register" operations. */
+
+int ENGINE_register_RSA(ENGINE *e);
+void ENGINE_unregister_RSA(ENGINE *e);
+void ENGINE_register_all_RSA(void);
+
+int ENGINE_register_DSA(ENGINE *e);
+void ENGINE_unregister_DSA(ENGINE *e);
+void ENGINE_register_all_DSA(void);
+
+int ENGINE_register_ECDH(ENGINE *e);
+void ENGINE_unregister_ECDH(ENGINE *e);
+void ENGINE_register_all_ECDH(void);
+
+int ENGINE_register_ECDSA(ENGINE *e);
+void ENGINE_unregister_ECDSA(ENGINE *e);
+void ENGINE_register_all_ECDSA(void);
+
+int ENGINE_register_DH(ENGINE *e);
+void ENGINE_unregister_DH(ENGINE *e);
+void ENGINE_register_all_DH(void);
+
+int ENGINE_register_RAND(ENGINE *e);
+void ENGINE_unregister_RAND(ENGINE *e);
+void ENGINE_register_all_RAND(void);
+
+int ENGINE_register_STORE(ENGINE *e);
+void ENGINE_unregister_STORE(ENGINE *e);
+void ENGINE_register_all_STORE(void);
+
+int ENGINE_register_ciphers(ENGINE *e);
+void ENGINE_unregister_ciphers(ENGINE *e);
+void ENGINE_register_all_ciphers(void);
+
+int ENGINE_register_digests(ENGINE *e);
+void ENGINE_unregister_digests(ENGINE *e);
+void ENGINE_register_all_digests(void);
+
+int ENGINE_register_pkey_meths(ENGINE *e);
+void ENGINE_unregister_pkey_meths(ENGINE *e);
+void ENGINE_register_all_pkey_meths(void);
+
+int ENGINE_register_pkey_asn1_meths(ENGINE *e);
+void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
+void ENGINE_register_all_pkey_asn1_meths(void);
+
+/* These functions register all support from the above categories. Note, use of
+ * these functions can result in static linkage of code your application may not
+ * need. If you only need a subset of functionality, consider using more
+ * selective initialisation. */
+int ENGINE_register_complete(ENGINE *e);
+int ENGINE_register_all_complete(void);
+
+/* Send parametrised control commands to the engine. The possibilities to send
+ * down an integer, a pointer to data or a function pointer are provided. Any of
+ * the parameters may or may not be NULL, depending on the command number. In
+ * actuality, this function only requires a structural (rather than functional)
+ * reference to an engine, but many control commands may require the engine be
+ * functional. The caller should be aware of trying commands that require an
+ * operational ENGINE, and only use functional references in such situations. */
+int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+
+/* This function tests if an ENGINE-specific command is usable as a "setting".
+ * Eg. in an application's config file that gets processed through
+ * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
+ * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */
+int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
+
+/* This function works like ENGINE_ctrl() with the exception of taking a
+ * command name instead of a command number, and can handle optional commands.
+ * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to
+ * use the cmd_name and cmd_optional. */
+int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
+ long i, void *p, void (*f)(void), int cmd_optional);
+
+/* This function passes a command-name and argument to an ENGINE. The cmd_name
+ * is converted to a command number and the control command is called using
+ * 'arg' as an argument (unless the ENGINE doesn't support such a command, in
+ * which case no control command is called). The command is checked for input
+ * flags, and if necessary the argument will be converted to a numeric value. If
+ * cmd_optional is non-zero, then if the ENGINE doesn't support the given
+ * cmd_name the return value will be success anyway. This function is intended
+ * for applications to use so that users (or config files) can supply
+ * engine-specific config data to the ENGINE at run-time to control behaviour of
+ * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl()
+ * functions that return data, deal with binary data, or that are otherwise
+ * supposed to be used directly through ENGINE_ctrl() in application code. Any
+ * "return" data from an ENGINE_ctrl() operation in this function will be lost -
+ * the return value is interpreted as failure if the return value is zero,
+ * success otherwise, and this function returns a boolean value as a result. In
+ * other words, vendors of 'ENGINE'-enabled devices should write ENGINE
+ * implementations with parameterisations that work in this scheme, so that
+ * compliant ENGINE-based applications can work consistently with the same
+ * configuration for the same ENGINE-enabled devices, across applications. */
+int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
+ int cmd_optional);
+
+/* These functions are useful for manufacturing new ENGINE structures. They
+ * don't address reference counting at all - one uses them to populate an ENGINE
+ * structure with personalised implementations of things prior to using it
+ * directly or adding it to the builtin ENGINE list in OpenSSL. These are also
+ * here so that the ENGINE structure doesn't have to be exposed and break binary
+ * compatibility! */
+ENGINE *ENGINE_new(void);
+int ENGINE_free(ENGINE *e);
+int ENGINE_up_ref(ENGINE *e);
+int ENGINE_set_id(ENGINE *e, const char *id);
+int ENGINE_set_name(ENGINE *e, const char *name);
+int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
+int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
+int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
+int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
+int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
+int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
+int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
+int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
+int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
+int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
+int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
+int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
+int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
+int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
+ ENGINE_SSL_CLIENT_CERT_PTR loadssl_f);
+int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
+int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
+int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
+int ENGINE_set_flags(ENGINE *e, int flags);
+int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
+/* These functions allow control over any per-structure ENGINE data. */
+int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
+void *ENGINE_get_ex_data(const ENGINE *e, int idx);
+
+/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
+ * automatically ensures the list cleanup function is registered to be called
+ * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure
+ * ENGINE_cleanup() will clean up after them. */
+void ENGINE_cleanup(void);
+
+/* These return values from within the ENGINE structure. These can be useful
+ * with functional references as well as structural references - it depends
+ * which you obtained. Using the result for functional purposes if you only
+ * obtained a structural reference may be problematic! */
+const char *ENGINE_get_id(const ENGINE *e);
+const char *ENGINE_get_name(const ENGINE *e);
+const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
+const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
+const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
+const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
+const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
+const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
+const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
+ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
+ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e);
+ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
+ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
+ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
+const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
+const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
+const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
+ const char *str, int len);
+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
+ const char *str, int len);
+const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
+int ENGINE_get_flags(const ENGINE *e);
+
+/* FUNCTIONAL functions. These functions deal with ENGINE structures
+ * that have (or will) be initialised for use. Broadly speaking, the
+ * structural functions are useful for iterating the list of available
+ * engine types, creating new engine types, and other "list" operations.
+ * These functions actually deal with ENGINEs that are to be used. As
+ * such these functions can fail (if applicable) when particular
+ * engines are unavailable - eg. if a hardware accelerator is not
+ * attached or not functioning correctly. Each ENGINE has 2 reference
+ * counts; structural and functional. Every time a functional reference
+ * is obtained or released, a corresponding structural reference is
+ * automatically obtained or released too. */
+
+/* Initialise a engine type for use (or up its reference count if it's
+ * already in use). This will fail if the engine is not currently
+ * operational and cannot initialise. */
+int ENGINE_init(ENGINE *e);
+/* Free a functional reference to a engine type. This does not require
+ * a corresponding call to ENGINE_free as it also releases a structural
+ * reference. */
+int ENGINE_finish(ENGINE *e);
+
+/* The following functions handle keys that are stored in some secondary
+ * location, handled by the engine. The storage may be on a card or
+ * whatever. */
+EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data);
+EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data);
+int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
+ STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
+ STACK_OF(X509) **pother,
+ UI_METHOD *ui_method, void *callback_data);
+
+/* This returns a pointer for the current ENGINE structure that
+ * is (by default) performing any RSA operations. The value returned
+ * is an incremented reference, so it should be free'd (ENGINE_finish)
+ * before it is discarded. */
+ENGINE *ENGINE_get_default_RSA(void);
+/* Same for the other "methods" */
+ENGINE *ENGINE_get_default_DSA(void);
+ENGINE *ENGINE_get_default_ECDH(void);
+ENGINE *ENGINE_get_default_ECDSA(void);
+ENGINE *ENGINE_get_default_DH(void);
+ENGINE *ENGINE_get_default_RAND(void);
+/* These functions can be used to get a functional reference to perform
+ * ciphering or digesting corresponding to "nid". */
+ENGINE *ENGINE_get_cipher_engine(int nid);
+ENGINE *ENGINE_get_digest_engine(int nid);
+ENGINE *ENGINE_get_pkey_meth_engine(int nid);
+ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
+
+/* This sets a new default ENGINE structure for performing RSA
+ * operations. If the result is non-zero (success) then the ENGINE
+ * structure will have had its reference count up'd so the caller
+ * should still free their own reference 'e'. */
+int ENGINE_set_default_RSA(ENGINE *e);
+int ENGINE_set_default_string(ENGINE *e, const char *def_list);
+/* Same for the other "methods" */
+int ENGINE_set_default_DSA(ENGINE *e);
+int ENGINE_set_default_ECDH(ENGINE *e);
+int ENGINE_set_default_ECDSA(ENGINE *e);
+int ENGINE_set_default_DH(ENGINE *e);
+int ENGINE_set_default_RAND(ENGINE *e);
+int ENGINE_set_default_ciphers(ENGINE *e);
+int ENGINE_set_default_digests(ENGINE *e);
+int ENGINE_set_default_pkey_meths(ENGINE *e);
+int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
+
+/* The combination "set" - the flags are bitwise "OR"d from the
+ * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
+ * function, this function can result in unnecessary static linkage. If your
+ * application requires only specific functionality, consider using more
+ * selective functions. */
+int ENGINE_set_default(ENGINE *e, unsigned int flags);
+
+void ENGINE_add_conf_module(void);
+
+/* Deprecated functions ... */
+/* int ENGINE_clear_defaults(void); */
+
+/**************************/
+/* DYNAMIC ENGINE SUPPORT */
+/**************************/
+
+/* Binary/behaviour compatibility levels */
+#define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000
+/* Binary versions older than this are too old for us (whether we're a loader or
+ * a loadee) */
+#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000
+
+/* When compiling an ENGINE entirely as an external shared library, loadable by
+ * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
+ * type provides the calling application's (or library's) error functionality
+ * and memory management function pointers to the loaded library. These should
+ * be used/set in the loaded library code so that the loading application's
+ * 'state' will be used/changed in all operations. The 'static_state' pointer
+ * allows the loaded library to know if it shares the same static data as the
+ * calling application (or library), and thus whether these callbacks need to be
+ * set or not. */
+typedef void *(*dyn_MEM_malloc_cb)(size_t);
+typedef void *(*dyn_MEM_realloc_cb)(void *, size_t);
+typedef void (*dyn_MEM_free_cb)(void *);
+typedef struct st_dynamic_MEM_fns {
+ dyn_MEM_malloc_cb malloc_cb;
+ dyn_MEM_realloc_cb realloc_cb;
+ dyn_MEM_free_cb free_cb;
+ } dynamic_MEM_fns;
+/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use
+ * these types so we (and any other dependant code) can simplify a bit?? */
+typedef void (*dyn_lock_locking_cb)(int,int,const char *,int);
+typedef int (*dyn_lock_add_lock_cb)(int*,int,int,const char *,int);
+typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)(
+ const char *,int);
+typedef void (*dyn_dynlock_lock_cb)(int,struct CRYPTO_dynlock_value *,
+ const char *,int);
+typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *,
+ const char *,int);
+typedef struct st_dynamic_LOCK_fns {
+ dyn_lock_locking_cb lock_locking_cb;
+ dyn_lock_add_lock_cb lock_add_lock_cb;
+ dyn_dynlock_create_cb dynlock_create_cb;
+ dyn_dynlock_lock_cb dynlock_lock_cb;
+ dyn_dynlock_destroy_cb dynlock_destroy_cb;
+ } dynamic_LOCK_fns;
+/* The top-level structure */
+typedef struct st_dynamic_fns {
+ void *static_state;
+ const ERR_FNS *err_fns;
+ const CRYPTO_EX_DATA_IMPL *ex_data_fns;
+ dynamic_MEM_fns mem_fns;
+ dynamic_LOCK_fns lock_fns;
+ } dynamic_fns;
+
+/* The version checking function should be of this prototype. NB: The
+ * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code.
+ * If this function returns zero, it indicates a (potential) version
+ * incompatibility and the loaded library doesn't believe it can proceed.
+ * Otherwise, the returned value is the (latest) version supported by the
+ * loading library. The loader may still decide that the loaded code's version
+ * is unsatisfactory and could veto the load. The function is expected to
+ * be implemented with the symbol name "v_check", and a default implementation
+ * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
+typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
+#define IMPLEMENT_DYNAMIC_CHECK_FN() \
+ OPENSSL_EXPORT unsigned long v_check(unsigned long v); \
+ OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
+ if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
+ return 0; }
+
+/* This function is passed the ENGINE structure to initialise with its own
+ * function and command settings. It should not adjust the structural or
+ * functional reference counts. If this function returns zero, (a) the load will
+ * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the
+ * structure, and (c) the shared library will be unloaded. So implementations
+ * should do their own internal cleanup in failure circumstances otherwise they
+ * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that
+ * the loader is looking for. If this is NULL, the shared library can choose to
+ * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared
+ * library must initialise only an ENGINE matching the passed 'id'. The function
+ * is expected to be implemented with the symbol name "bind_engine". A standard
+ * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where
+ * the parameter 'fn' is a callback function that populates the ENGINE structure
+ * and returns an int value (zero for failure). 'fn' should have prototype;
+ * [static] int fn(ENGINE *e, const char *id); */
+typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
+ const dynamic_fns *fns);
+#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
+ OPENSSL_EXPORT \
+ int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \
+ OPENSSL_EXPORT \
+ int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
+ if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
+ if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
+ fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
+ return 0; \
+ CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
+ CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
+ CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
+ CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
+ CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
+ if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
+ return 0; \
+ if(!ERR_set_implementation(fns->err_fns)) return 0; \
+ skip_cbs: \
+ if(!fn(e,id)) return 0; \
+ return 1; }
+
+/* If the loading application (or library) and the loaded ENGINE library share
+ * the same static data (eg. they're both dynamically linked to the same
+ * libcrypto.so) we need a way to avoid trying to set system callbacks - this
+ * would fail, and for the same reason that it's unnecessary to try. If the
+ * loaded ENGINE has (or gets from through the loader) its own copy of the
+ * libcrypto static data, we will need to set the callbacks. The easiest way to
+ * detect this is to have a function that returns a pointer to some static data
+ * and let the loading application and loaded ENGINE compare their respective
+ * values. */
+void *ENGINE_get_static_state(void);
+
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
+void ENGINE_setup_bsd_cryptodev(void);
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ENGINE_strings(void);
+
+/* Error codes for the ENGINE functions. */
+
+/* Function codes. */
+#define ENGINE_F_DYNAMIC_CTRL 180
+#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181
+#define ENGINE_F_DYNAMIC_LOAD 182
+#define ENGINE_F_DYNAMIC_SET_DATA_CTX 183
+#define ENGINE_F_ENGINE_ADD 105
+#define ENGINE_F_ENGINE_BY_ID 106
+#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170
+#define ENGINE_F_ENGINE_CTRL 142
+#define ENGINE_F_ENGINE_CTRL_CMD 178
+#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171
+#define ENGINE_F_ENGINE_FINISH 107
+#define ENGINE_F_ENGINE_FREE_UTIL 108
+#define ENGINE_F_ENGINE_GET_CIPHER 185
+#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177
+#define ENGINE_F_ENGINE_GET_DIGEST 186
+#define ENGINE_F_ENGINE_GET_NEXT 115
+#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193
+#define ENGINE_F_ENGINE_GET_PKEY_METH 192
+#define ENGINE_F_ENGINE_GET_PREV 116
+#define ENGINE_F_ENGINE_INIT 119
+#define ENGINE_F_ENGINE_LIST_ADD 120
+#define ENGINE_F_ENGINE_LIST_REMOVE 121
+#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
+#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
+#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194
+#define ENGINE_F_ENGINE_NEW 122
+#define ENGINE_F_ENGINE_REMOVE 123
+#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189
+#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126
+#define ENGINE_F_ENGINE_SET_ID 129
+#define ENGINE_F_ENGINE_SET_NAME 130
+#define ENGINE_F_ENGINE_TABLE_REGISTER 184
+#define ENGINE_F_ENGINE_UNLOAD_KEY 152
+#define ENGINE_F_ENGINE_UNLOCKED_FINISH 191
+#define ENGINE_F_ENGINE_UP_REF 190
+#define ENGINE_F_INT_CTRL_HELPER 172
+#define ENGINE_F_INT_ENGINE_CONFIGURE 188
+#define ENGINE_F_INT_ENGINE_MODULE_INIT 187
+#define ENGINE_F_LOG_MESSAGE 141
+
+/* Reason codes. */
+#define ENGINE_R_ALREADY_LOADED 100
+#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133
+#define ENGINE_R_CMD_NOT_EXECUTABLE 134
+#define ENGINE_R_COMMAND_TAKES_INPUT 135
+#define ENGINE_R_COMMAND_TAKES_NO_INPUT 136
+#define ENGINE_R_CONFLICTING_ENGINE_ID 103
+#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119
+#define ENGINE_R_DH_NOT_IMPLEMENTED 139
+#define ENGINE_R_DSA_NOT_IMPLEMENTED 140
+#define ENGINE_R_DSO_FAILURE 104
+#define ENGINE_R_DSO_NOT_FOUND 132
+#define ENGINE_R_ENGINES_SECTION_ERROR 148
+#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102
+#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
+#define ENGINE_R_ENGINE_SECTION_ERROR 149
+#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
+#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129
+#define ENGINE_R_FINISH_FAILED 106
+#define ENGINE_R_GET_HANDLE_FAILED 107
+#define ENGINE_R_ID_OR_NAME_MISSING 108
+#define ENGINE_R_INIT_FAILED 109
+#define ENGINE_R_INTERNAL_LIST_ERROR 110
+#define ENGINE_R_INVALID_ARGUMENT 143
+#define ENGINE_R_INVALID_CMD_NAME 137
+#define ENGINE_R_INVALID_CMD_NUMBER 138
+#define ENGINE_R_INVALID_INIT_VALUE 151
+#define ENGINE_R_INVALID_STRING 150
+#define ENGINE_R_NOT_INITIALISED 117
+#define ENGINE_R_NOT_LOADED 112
+#define ENGINE_R_NO_CONTROL_FUNCTION 120
+#define ENGINE_R_NO_INDEX 144
+#define ENGINE_R_NO_LOAD_FUNCTION 125
+#define ENGINE_R_NO_REFERENCE 130
+#define ENGINE_R_NO_SUCH_ENGINE 116
+#define ENGINE_R_NO_UNLOAD_FUNCTION 126
+#define ENGINE_R_PROVIDE_PARAMETERS 113
+#define ENGINE_R_RSA_NOT_IMPLEMENTED 141
+#define ENGINE_R_UNIMPLEMENTED_CIPHER 146
+#define ENGINE_R_UNIMPLEMENTED_DIGEST 147
+#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101
+#define ENGINE_R_VERSION_INCOMPATIBILITY 145
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto/install.com b/openssl/crypto/install.com
index 5ddd4d794..8bc1e180e 100644
--- a/openssl/crypto/install.com
+++ b/openssl/crypto/install.com
@@ -1,150 +1,150 @@
-$! INSTALL.COM -- Installs the files in a given directory tree
-$!
-$! Author: Richard Levitte <richard@levitte.org>
-$! Time of creation: 22-MAY-1998 10:13
-$!
-$! Changes by Zoltan Arpadffy <zoli@polarhome.com>
-$!
-$! P1 root of the directory tree
-$!
-$ IF P1 .EQS. ""
-$ THEN
-$ WRITE SYS$OUTPUT "First argument missing."
-$ WRITE SYS$OUTPUT -
- "It should be the directory where you want things installed."
-$ EXIT
-$ ENDIF
-$
-$ IF (F$GETSYI("CPU").LT.128)
-$ THEN
-$ ARCH := VAX
-$ ELSE
-$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
-$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
-$ ENDIF
-$
-$ ROOT = F$PARSE(P1,"[]A.;0",,,"SYNTAX_ONLY,NO_CONCEAL") - "A.;0"
-$ ROOT_DEV = F$PARSE(ROOT,,,"DEVICE","SYNTAX_ONLY")
-$ ROOT_DIR = F$PARSE(ROOT,,,"DIRECTORY","SYNTAX_ONLY") -
- - "[000000." - "][" - "[" - "]"
-$ ROOT = ROOT_DEV + "[" + ROOT_DIR
-$
-$ DEFINE/NOLOG WRK_SSLROOT 'ROOT'.] /TRANS=CONC
-$ DEFINE/NOLOG WRK_SSLLIB WRK_SSLROOT:['ARCH'_LIB]
-$ DEFINE/NOLOG WRK_SSLINCLUDE WRK_SSLROOT:[INCLUDE]
-$
-$ IF F$PARSE("WRK_SSLROOT:[000000]") .EQS. "" THEN -
- CREATE/DIR/LOG WRK_SSLROOT:[000000]
-$ IF F$PARSE("WRK_SSLLIB:") .EQS. "" THEN -
- CREATE/DIR/LOG WRK_SSLLIB:
-$ IF F$PARSE("WRK_SSLINCLUDE:") .EQS. "" THEN -
- CREATE/DIR/LOG WRK_SSLINCLUDE:
-$
-$ SDIRS := ,-
- _'ARCH',-
- OBJECTS,-
- MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,WHRLPOOL,-
- DES,AES,RC2,RC4,RC5,IDEA,BF,CAST,CAMELLIA,SEED,-
- BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,-
- BUFFER,BIO,STACK,LHASH,RAND,ERR,-
- EVP,ASN1,PEM,X509,X509V3,CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,-
- UI,KRB5,-
- STORE,CMS,PQUEUE,TS,JPAKE
-$ EXHEADER_ := crypto.h,opensslv.h,ebcdic.h,symhacks.h,ossl_typ.h
-$ EXHEADER__'ARCH' := opensslconf.h
-$ EXHEADER_OBJECTS := objects.h,obj_mac.h
-$ EXHEADER_MD2 := md2.h
-$ EXHEADER_MD4 := md4.h
-$ EXHEADER_MD5 := md5.h
-$ EXHEADER_SHA := sha.h
-$ EXHEADER_MDC2 := mdc2.h
-$ EXHEADER_HMAC := hmac.h
-$ EXHEADER_RIPEMD := ripemd.h
-$ EXHEADER_WHRLPOOL := whrlpool.h
-$ EXHEADER_DES := des.h,des_old.h
-$ EXHEADER_AES := aes.h
-$ EXHEADER_RC2 := rc2.h
-$ EXHEADER_RC4 := rc4.h
-$ EXHEADER_RC5 := rc5.h
-$ EXHEADER_IDEA := idea.h
-$ EXHEADER_BF := blowfish.h
-$ EXHEADER_CAST := cast.h
-$ EXHEADER_CAMELLIA := camellia.h
-$ EXHEADER_SEED := seed.h
-$ EXHEADER_MODES := modes.h
-$ EXHEADER_BN := bn.h
-$ EXHEADER_EC := ec.h
-$ EXHEADER_RSA := rsa.h
-$ EXHEADER_DSA := dsa.h
-$ EXHEADER_ECDSA := ecdsa.h
-$ EXHEADER_DH := dh.h
-$ EXHEADER_ECDH := ecdh.h
-$ EXHEADER_DSO := dso.h
-$ EXHEADER_ENGINE := engine.h
-$ EXHEADER_BUFFER := buffer.h
-$ EXHEADER_BIO := bio.h
-$ EXHEADER_STACK := stack.h,safestack.h
-$ EXHEADER_LHASH := lhash.h
-$ EXHEADER_RAND := rand.h
-$ EXHEADER_ERR := err.h
-$ EXHEADER_EVP := evp.h
-$ EXHEADER_ASN1 := asn1.h,asn1_mac.h,asn1t.h
-$ EXHEADER_PEM := pem.h,pem2.h
-$ EXHEADER_X509 := x509.h,x509_vfy.h
-$ EXHEADER_X509V3 := x509v3.h
-$ EXHEADER_CONF := conf.h,conf_api.h
-$ EXHEADER_TXT_DB := txt_db.h
-$ EXHEADER_PKCS7 := pkcs7.h
-$ EXHEADER_PKCS12 := pkcs12.h
-$ EXHEADER_COMP := comp.h
-$ EXHEADER_OCSP := ocsp.h
-$ EXHEADER_UI := ui.h,ui_compat.h
-$ EXHEADER_KRB5 := krb5_asn.h
-$! EXHEADER_STORE := store.h,str_compat.h
-$ EXHEADER_STORE := store.h
-$ EXHEADER_CMS := cms.h
-$ EXHEADER_PQUEUE := pqueue.h
-$ EXHEADER_TS := ts.h
-$ EXHEADER_JPAKE := jpake.h
-$ LIBS := LIBCRYPTO,LIBCRYPTO32
-$
-$ EXE_DIR := [-.'ARCH'.EXE.CRYPTO]
-$
-$ I = 0
-$ LOOP_SDIRS:
-$ D = F$EDIT(F$ELEMENT(I, ",", SDIRS),"TRIM")
-$ I = I + 1
-$ IF D .EQS. "," THEN GOTO LOOP_SDIRS_END
-$ tmp = EXHEADER_'D'
-$ IF D .EQS. ""
-$ THEN
-$ COPY 'tmp' WRK_SSLINCLUDE: /LOG
-$ ELSE
-$ COPY [.'D']'tmp' WRK_SSLINCLUDE: /LOG
-$ ENDIF
-$ SET FILE/PROT=WORLD:RE WRK_SSLINCLUDE:'tmp'
-$ GOTO LOOP_SDIRS
-$ LOOP_SDIRS_END:
-$
-$ I = 0
-$ LOOP_LIB:
-$ E = F$EDIT(F$ELEMENT(I, ",", LIBS),"TRIM")
-$ I = I + 1
-$ IF E .EQS. "," THEN GOTO LOOP_LIB_END
-$ SET NOON
-$ IF F$SEARCH(EXE_DIR+E+".OLB") .NES. ""
-$ THEN
-$ COPY 'EXE_DIR''E'.OLB WRK_SSLLIB:'E'.OLB/log
-$ SET FILE/PROT=W:RE WRK_SSLLIB:'E'.OLB
-$ ENDIF
-$ ! Preparing for the time when we have shareable images
-$ IF F$SEARCH(EXE_DIR+E+".EXE") .NES. ""
-$ THEN
-$ COPY 'EXE_DIR''E'.EXE WRK_SSLLIB:'E'.EXE/log
-$ SET FILE/PROT=W:RE WRK_SSLLIB:'E'.EXE
-$ ENDIF
-$ SET ON
-$ GOTO LOOP_LIB
-$ LOOP_LIB_END:
-$
-$ EXIT
+$! INSTALL.COM -- Installs the files in a given directory tree
+$!
+$! Author: Richard Levitte <richard@levitte.org>
+$! Time of creation: 22-MAY-1998 10:13
+$!
+$! Changes by Zoltan Arpadffy <zoli@polarhome.com>
+$!
+$! P1 root of the directory tree
+$!
+$ IF P1 .EQS. ""
+$ THEN
+$ WRITE SYS$OUTPUT "First argument missing."
+$ WRITE SYS$OUTPUT -
+ "It should be the directory where you want things installed."
+$ EXIT
+$ ENDIF
+$
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$ ARCH := VAX
+$ ELSE
+$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$ ENDIF
+$
+$ ROOT = F$PARSE(P1,"[]A.;0",,,"SYNTAX_ONLY,NO_CONCEAL") - "A.;0"
+$ ROOT_DEV = F$PARSE(ROOT,,,"DEVICE","SYNTAX_ONLY")
+$ ROOT_DIR = F$PARSE(ROOT,,,"DIRECTORY","SYNTAX_ONLY") -
+ - "[000000." - "][" - "[" - "]"
+$ ROOT = ROOT_DEV + "[" + ROOT_DIR
+$
+$ DEFINE/NOLOG WRK_SSLROOT 'ROOT'.] /TRANS=CONC
+$ DEFINE/NOLOG WRK_SSLLIB WRK_SSLROOT:['ARCH'_LIB]
+$ DEFINE/NOLOG WRK_SSLINCLUDE WRK_SSLROOT:[INCLUDE]
+$
+$ IF F$PARSE("WRK_SSLROOT:[000000]") .EQS. "" THEN -
+ CREATE/DIR/LOG WRK_SSLROOT:[000000]
+$ IF F$PARSE("WRK_SSLLIB:") .EQS. "" THEN -
+ CREATE/DIR/LOG WRK_SSLLIB:
+$ IF F$PARSE("WRK_SSLINCLUDE:") .EQS. "" THEN -
+ CREATE/DIR/LOG WRK_SSLINCLUDE:
+$
+$ SDIRS := ,-
+ _'ARCH',-
+ OBJECTS,-
+ MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,WHRLPOOL,-
+ DES,AES,RC2,RC4,RC5,IDEA,BF,CAST,CAMELLIA,SEED,-
+ BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,-
+ BUFFER,BIO,STACK,LHASH,RAND,ERR,-
+ EVP,ASN1,PEM,X509,X509V3,CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,-
+ UI,KRB5,-
+ STORE,CMS,PQUEUE,TS,JPAKE
+$ EXHEADER_ := crypto.h,opensslv.h,ebcdic.h,symhacks.h,ossl_typ.h
+$ EXHEADER__'ARCH' := opensslconf.h
+$ EXHEADER_OBJECTS := objects.h,obj_mac.h
+$ EXHEADER_MD2 := md2.h
+$ EXHEADER_MD4 := md4.h
+$ EXHEADER_MD5 := md5.h
+$ EXHEADER_SHA := sha.h
+$ EXHEADER_MDC2 := mdc2.h
+$ EXHEADER_HMAC := hmac.h
+$ EXHEADER_RIPEMD := ripemd.h
+$ EXHEADER_WHRLPOOL := whrlpool.h
+$ EXHEADER_DES := des.h,des_old.h
+$ EXHEADER_AES := aes.h
+$ EXHEADER_RC2 := rc2.h
+$ EXHEADER_RC4 := rc4.h
+$ EXHEADER_RC5 := rc5.h
+$ EXHEADER_IDEA := idea.h
+$ EXHEADER_BF := blowfish.h
+$ EXHEADER_CAST := cast.h
+$ EXHEADER_CAMELLIA := camellia.h
+$ EXHEADER_SEED := seed.h
+$ EXHEADER_MODES := modes.h
+$ EXHEADER_BN := bn.h
+$ EXHEADER_EC := ec.h
+$ EXHEADER_RSA := rsa.h
+$ EXHEADER_DSA := dsa.h
+$ EXHEADER_ECDSA := ecdsa.h
+$ EXHEADER_DH := dh.h
+$ EXHEADER_ECDH := ecdh.h
+$ EXHEADER_DSO := dso.h
+$ EXHEADER_ENGINE := engine.h
+$ EXHEADER_BUFFER := buffer.h
+$ EXHEADER_BIO := bio.h
+$ EXHEADER_STACK := stack.h,safestack.h
+$ EXHEADER_LHASH := lhash.h
+$ EXHEADER_RAND := rand.h
+$ EXHEADER_ERR := err.h
+$ EXHEADER_EVP := evp.h
+$ EXHEADER_ASN1 := asn1.h,asn1_mac.h,asn1t.h
+$ EXHEADER_PEM := pem.h,pem2.h
+$ EXHEADER_X509 := x509.h,x509_vfy.h
+$ EXHEADER_X509V3 := x509v3.h
+$ EXHEADER_CONF := conf.h,conf_api.h
+$ EXHEADER_TXT_DB := txt_db.h
+$ EXHEADER_PKCS7 := pkcs7.h
+$ EXHEADER_PKCS12 := pkcs12.h
+$ EXHEADER_COMP := comp.h
+$ EXHEADER_OCSP := ocsp.h
+$ EXHEADER_UI := ui.h,ui_compat.h
+$ EXHEADER_KRB5 := krb5_asn.h
+$! EXHEADER_STORE := store.h,str_compat.h
+$ EXHEADER_STORE := store.h
+$ EXHEADER_CMS := cms.h
+$ EXHEADER_PQUEUE := pqueue.h
+$ EXHEADER_TS := ts.h
+$ EXHEADER_JPAKE := jpake.h
+$ LIBS := LIBCRYPTO,LIBCRYPTO32
+$
+$ EXE_DIR := [-.'ARCH'.EXE.CRYPTO]
+$
+$ I = 0
+$ LOOP_SDIRS:
+$ D = F$EDIT(F$ELEMENT(I, ",", SDIRS),"TRIM")
+$ I = I + 1
+$ IF D .EQS. "," THEN GOTO LOOP_SDIRS_END
+$ tmp = EXHEADER_'D'
+$ IF D .EQS. ""
+$ THEN
+$ COPY 'tmp' WRK_SSLINCLUDE: /LOG
+$ ELSE
+$ COPY [.'D']'tmp' WRK_SSLINCLUDE: /LOG
+$ ENDIF
+$ SET FILE/PROT=WORLD:RE WRK_SSLINCLUDE:'tmp'
+$ GOTO LOOP_SDIRS
+$ LOOP_SDIRS_END:
+$
+$ I = 0
+$ LOOP_LIB:
+$ E = F$EDIT(F$ELEMENT(I, ",", LIBS),"TRIM")
+$ I = I + 1
+$ IF E .EQS. "," THEN GOTO LOOP_LIB_END
+$ SET NOON
+$ IF F$SEARCH(EXE_DIR+E+".OLB") .NES. ""
+$ THEN
+$ COPY 'EXE_DIR''E'.OLB WRK_SSLLIB:'E'.OLB/log
+$ SET FILE/PROT=W:RE WRK_SSLLIB:'E'.OLB
+$ ENDIF
+$ ! Preparing for the time when we have shareable images
+$ IF F$SEARCH(EXE_DIR+E+".EXE") .NES. ""
+$ THEN
+$ COPY 'EXE_DIR''E'.EXE WRK_SSLLIB:'E'.EXE/log
+$ SET FILE/PROT=W:RE WRK_SSLLIB:'E'.EXE
+$ ENDIF
+$ SET ON
+$ GOTO LOOP_LIB
+$ LOOP_LIB_END:
+$
+$ EXIT
diff --git a/openssl/crypto/opensslv.h b/openssl/crypto/opensslv.h
index ecffe494f..e7fca8345 100644
--- a/openssl/crypto/opensslv.h
+++ b/openssl/crypto/opensslv.h
@@ -1,89 +1,89 @@
-#ifndef HEADER_OPENSSLV_H
-#define HEADER_OPENSSLV_H
-
-/* Numeric release version identifier:
- * MNNFFPPS: major minor fix patch status
- * The status nibble has one of the values 0 for development, 1 to e for betas
- * 1 to 14, and f for release. The patch level is exactly that.
- * For example:
- * 0.9.3-dev 0x00903000
- * 0.9.3-beta1 0x00903001
- * 0.9.3-beta2-dev 0x00903002
- * 0.9.3-beta2 0x00903002 (same as ...beta2-dev)
- * 0.9.3 0x0090300f
- * 0.9.3a 0x0090301f
- * 0.9.4 0x0090400f
- * 1.2.3z 0x102031af
- *
- * For continuity reasons (because 0.9.5 is already out, and is coded
- * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
- * part is slightly different, by setting the highest bit. This means
- * that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start
- * with 0x0090600S...
- *
- * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
- * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
- * major minor fix final patch/beta)
- */
-#define OPENSSL_VERSION_NUMBER 0x1000004fL
-#ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0d-fips 8 Feb 2011"
-#else
-#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0d 8 Feb 2011"
-#endif
-#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
-
-
-/* The macros below are to be used for shared library (.so, .dll, ...)
- * versioning. That kind of versioning works a bit differently between
- * operating systems. The most usual scheme is to set a major and a minor
- * number, and have the runtime loader check that the major number is equal
- * to what it was at application link time, while the minor number has to
- * be greater or equal to what it was at application link time. With this
- * scheme, the version number is usually part of the file name, like this:
- *
- * libcrypto.so.0.9
- *
- * Some unixen also make a softlink with the major verson number only:
- *
- * libcrypto.so.0
- *
- * On Tru64 and IRIX 6.x it works a little bit differently. There, the
- * shared library version is stored in the file, and is actually a series
- * of versions, separated by colons. The rightmost version present in the
- * library when linking an application is stored in the application to be
- * matched at run time. When the application is run, a check is done to
- * see if the library version stored in the application matches any of the
- * versions in the version string of the library itself.
- * This version string can be constructed in any way, depending on what
- * kind of matching is desired. However, to implement the same scheme as
- * the one used in the other unixen, all compatible versions, from lowest
- * to highest, should be part of the string. Consecutive builds would
- * give the following versions strings:
- *
- * 3.0
- * 3.0:3.1
- * 3.0:3.1:3.2
- * 4.0
- * 4.0:4.1
- *
- * Notice how version 4 is completely incompatible with version, and
- * therefore give the breach you can see.
- *
- * There may be other schemes as well that I haven't yet discovered.
- *
- * So, here's the way it works here: first of all, the library version
- * number doesn't need at all to match the overall OpenSSL version.
- * However, it's nice and more understandable if it actually does.
- * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
- * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
- * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways,
- * we need to keep a history of version numbers, which is done in the
- * macro SHLIB_VERSION_HISTORY. The numbers are separated by colons and
- * should only keep the versions that are binary compatible with the current.
- */
-#define SHLIB_VERSION_HISTORY ""
-#define SHLIB_VERSION_NUMBER "1.0.0"
-
-
-#endif /* HEADER_OPENSSLV_H */
+#ifndef HEADER_OPENSSLV_H
+#define HEADER_OPENSSLV_H
+
+/* Numeric release version identifier:
+ * MNNFFPPS: major minor fix patch status
+ * The status nibble has one of the values 0 for development, 1 to e for betas
+ * 1 to 14, and f for release. The patch level is exactly that.
+ * For example:
+ * 0.9.3-dev 0x00903000
+ * 0.9.3-beta1 0x00903001
+ * 0.9.3-beta2-dev 0x00903002
+ * 0.9.3-beta2 0x00903002 (same as ...beta2-dev)
+ * 0.9.3 0x0090300f
+ * 0.9.3a 0x0090301f
+ * 0.9.4 0x0090400f
+ * 1.2.3z 0x102031af
+ *
+ * For continuity reasons (because 0.9.5 is already out, and is coded
+ * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
+ * part is slightly different, by setting the highest bit. This means
+ * that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start
+ * with 0x0090600S...
+ *
+ * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
+ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
+ * major minor fix final patch/beta)
+ */
+#define OPENSSL_VERSION_NUMBER 0x1000004fL
+#ifdef OPENSSL_FIPS
+#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0d-fips 8 Feb 2011"
+#else
+#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0d 8 Feb 2011"
+#endif
+#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
+
+
+/* The macros below are to be used for shared library (.so, .dll, ...)
+ * versioning. That kind of versioning works a bit differently between
+ * operating systems. The most usual scheme is to set a major and a minor
+ * number, and have the runtime loader check that the major number is equal
+ * to what it was at application link time, while the minor number has to
+ * be greater or equal to what it was at application link time. With this
+ * scheme, the version number is usually part of the file name, like this:
+ *
+ * libcrypto.so.0.9
+ *
+ * Some unixen also make a softlink with the major verson number only:
+ *
+ * libcrypto.so.0
+ *
+ * On Tru64 and IRIX 6.x it works a little bit differently. There, the
+ * shared library version is stored in the file, and is actually a series
+ * of versions, separated by colons. The rightmost version present in the
+ * library when linking an application is stored in the application to be
+ * matched at run time. When the application is run, a check is done to
+ * see if the library version stored in the application matches any of the
+ * versions in the version string of the library itself.
+ * This version string can be constructed in any way, depending on what
+ * kind of matching is desired. However, to implement the same scheme as
+ * the one used in the other unixen, all compatible versions, from lowest
+ * to highest, should be part of the string. Consecutive builds would
+ * give the following versions strings:
+ *
+ * 3.0
+ * 3.0:3.1
+ * 3.0:3.1:3.2
+ * 4.0
+ * 4.0:4.1
+ *
+ * Notice how version 4 is completely incompatible with version, and
+ * therefore give the breach you can see.
+ *
+ * There may be other schemes as well that I haven't yet discovered.
+ *
+ * So, here's the way it works here: first of all, the library version
+ * number doesn't need at all to match the overall OpenSSL version.
+ * However, it's nice and more understandable if it actually does.
+ * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
+ * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
+ * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways,
+ * we need to keep a history of version numbers, which is done in the
+ * macro SHLIB_VERSION_HISTORY. The numbers are separated by colons and
+ * should only keep the versions that are binary compatible with the current.
+ */
+#define SHLIB_VERSION_HISTORY ""
+#define SHLIB_VERSION_NUMBER "1.0.0"
+
+
+#endif /* HEADER_OPENSSLV_H */
diff --git a/openssl/crypto/stack/safestack.h b/openssl/crypto/stack/safestack.h
index d416f2c9b..39914bdde 100644
--- a/openssl/crypto/stack/safestack.h
+++ b/openssl/crypto/stack/safestack.h
@@ -1,2575 +1,2575 @@
-/* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#ifndef HEADER_SAFESTACK_H
-#define HEADER_SAFESTACK_H
-
-#include <openssl/stack.h>
-
-#ifndef CHECKED_PTR_OF
-#define CHECKED_PTR_OF(type, p) \
- ((void*) (1 ? p : (type*)0))
-#endif
-
-/* In C++ we get problems because an explicit cast is needed from (void *)
- * we use CHECKED_STACK_OF to ensure the correct type is passed in the macros
- * below.
- */
-
-#define CHECKED_STACK_OF(type, p) \
- ((_STACK*) (1 ? p : (STACK_OF(type)*)0))
-
-#define CHECKED_SK_FREE_FUNC(type, p) \
- ((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))
-
-#define CHECKED_SK_FREE_FUNC2(type, p) \
- ((void (*)(void *)) ((1 ? p : (void (*)(type))0)))
-
-#define CHECKED_SK_CMP_FUNC(type, p) \
- ((int (*)(const void *, const void *)) \
- ((1 ? p : (int (*)(const type * const *, const type * const *))0)))
-
-#define STACK_OF(type) struct stack_st_##type
-#define PREDECLARE_STACK_OF(type) STACK_OF(type);
-
-#define DECLARE_STACK_OF(type) \
-STACK_OF(type) \
- { \
- _STACK stack; \
- };
-#define DECLARE_SPECIAL_STACK_OF(type, type2) \
-STACK_OF(type) \
- { \
- _STACK stack; \
- };
-
-#define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/
-
-
-/* Strings are special: normally an lhash entry will point to a single
- * (somewhat) mutable object. In the case of strings:
- *
- * a) Instead of a single char, there is an array of chars, NUL-terminated.
- * b) The string may have be immutable.
- *
- * So, they need their own declarations. Especially important for
- * type-checking tools, such as Deputy.
- *
-o * In practice, however, it appears to be hard to have a const
- * string. For now, I'm settling for dealing with the fact it is a
- * string at all.
- */
-typedef char *OPENSSL_STRING;
-
-typedef const char *OPENSSL_CSTRING;
-
-/* Confusingly, LHASH_OF(STRING) deals with char ** throughout, but
- * STACK_OF(STRING) is really more like STACK_OF(char), only, as
- * mentioned above, instead of a single char each entry is a
- * NUL-terminated array of chars. So, we have to implement STRING
- * specially for STACK_OF. This is dealt with in the autogenerated
- * macros below.
- */
-
-DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
-
-/* Similarly, we sometimes use a block of characters, NOT
- * nul-terminated. These should also be distinguished from "normal"
- * stacks. */
-
-typedef void *OPENSSL_BLOCK;
-DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
-
-/* SKM_sk_... stack macros are internal to safestack.h:
- * never use them directly, use sk_<type>_... instead */
-#define SKM_sk_new(type, cmp) \
- ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp)))
-#define SKM_sk_new_null(type) \
- ((STACK_OF(type) *)sk_new_null())
-#define SKM_sk_free(type, st) \
- sk_free(CHECKED_STACK_OF(type, st))
-#define SKM_sk_num(type, st) \
- sk_num(CHECKED_STACK_OF(type, st))
-#define SKM_sk_value(type, st,i) \
- ((type *)sk_value(CHECKED_STACK_OF(type, st), i))
-#define SKM_sk_set(type, st,i,val) \
- sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val))
-#define SKM_sk_zero(type, st) \
- sk_zero(CHECKED_STACK_OF(type, st))
-#define SKM_sk_push(type, st, val) \
- sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
-#define SKM_sk_unshift(type, st, val) \
- sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
-#define SKM_sk_find(type, st, val) \
- sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
-#define SKM_sk_find_ex(type, st, val) \
- sk_find_ex(CHECKED_STACK_OF(type, st), \
- CHECKED_PTR_OF(type, val))
-#define SKM_sk_delete(type, st, i) \
- (type *)sk_delete(CHECKED_STACK_OF(type, st), i)
-#define SKM_sk_delete_ptr(type, st, ptr) \
- (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr))
-#define SKM_sk_insert(type, st,val, i) \
- sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i)
-#define SKM_sk_set_cmp_func(type, st, cmp) \
- ((int (*)(const type * const *,const type * const *)) \
- sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp)))
-#define SKM_sk_dup(type, st) \
- (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st))
-#define SKM_sk_pop_free(type, st, free_func) \
- sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func))
-#define SKM_sk_shift(type, st) \
- (type *)sk_shift(CHECKED_STACK_OF(type, st))
-#define SKM_sk_pop(type, st) \
- (type *)sk_pop(CHECKED_STACK_OF(type, st))
-#define SKM_sk_sort(type, st) \
- sk_sort(CHECKED_STACK_OF(type, st))
-#define SKM_sk_is_sorted(type, st) \
- sk_is_sorted(CHECKED_STACK_OF(type, st))
-
-#define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- (STACK_OF(type) *)d2i_ASN1_SET( \
- (STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \
- pp, length, \
- CHECKED_D2I_OF(type, d2i_func), \
- CHECKED_SK_FREE_FUNC(type, free_func), \
- ex_tag, ex_class)
-
-#define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
- i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \
- CHECKED_I2D_OF(type, i2d_func), \
- ex_tag, ex_class, is_set)
-
-#define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
- ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \
- CHECKED_I2D_OF(type, i2d_func), buf, len)
-
-#define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
- (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func))
-
-#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
- (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \
- CHECKED_D2I_OF(type, d2i_func), \
- CHECKED_SK_FREE_FUNC(type, free_func), \
- pass, passlen, oct, seq)
-
-/* This block of defines is updated by util/mkstack.pl, please do not touch! */
-#define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp))
-#define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION)
-#define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st))
-#define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st))
-#define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i))
-#define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val))
-#define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st))
-#define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val))
-#define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val))
-#define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val))
-#define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val))
-#define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i))
-#define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr))
-#define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i))
-#define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp))
-#define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st)
-#define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func))
-#define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st))
-#define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st))
-#define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
-#define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
-
-#define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp))
-#define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
-#define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
-#define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
-#define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i))
-#define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val))
-#define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st))
-#define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val))
-#define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val))
-#define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val))
-#define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val))
-#define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i))
-#define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr))
-#define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i))
-#define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp))
-#define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st)
-#define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func))
-#define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st))
-#define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st))
-#define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
-#define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
-
-#define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp))
-#define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
-#define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
-#define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st))
-#define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i))
-#define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val))
-#define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st))
-#define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val))
-#define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val))
-#define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val))
-#define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val))
-#define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i))
-#define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr))
-#define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i))
-#define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp))
-#define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st)
-#define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func))
-#define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st))
-#define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st))
-#define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st))
-#define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st))
-
-#define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp))
-#define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER)
-#define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st))
-#define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st))
-#define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i))
-#define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val))
-#define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st))
-#define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val))
-#define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val))
-#define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val))
-#define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val))
-#define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i))
-#define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr))
-#define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i))
-#define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp))
-#define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st)
-#define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func))
-#define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st))
-#define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st))
-#define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st))
-#define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st))
-
-#define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp))
-#define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT)
-#define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st))
-#define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st))
-#define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i))
-#define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val))
-#define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st))
-#define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val))
-#define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val))
-#define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val))
-#define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val))
-#define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i))
-#define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr))
-#define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i))
-#define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp))
-#define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st)
-#define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func))
-#define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st))
-#define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st))
-#define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st))
-#define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st))
-
-#define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp))
-#define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE)
-#define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st))
-#define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st))
-#define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i))
-#define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val))
-#define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st))
-#define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val))
-#define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val))
-#define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val))
-#define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val))
-#define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i))
-#define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr))
-#define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i))
-#define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp))
-#define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st)
-#define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func))
-#define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st))
-#define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st))
-#define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st))
-#define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st))
-
-#define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp))
-#define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE)
-#define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st))
-#define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st))
-#define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i))
-#define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val))
-#define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st))
-#define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val))
-#define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val))
-#define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val))
-#define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val))
-#define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i))
-#define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr))
-#define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i))
-#define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp))
-#define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st)
-#define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func))
-#define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st))
-#define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st))
-#define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st))
-#define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st))
-
-#define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp))
-#define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING)
-#define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st))
-#define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st))
-#define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i))
-#define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val))
-#define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st))
-#define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val))
-#define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val))
-#define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val))
-#define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val))
-#define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i))
-#define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr))
-#define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i))
-#define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp))
-#define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st)
-#define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func))
-#define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st))
-#define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st))
-#define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st))
-#define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st))
-
-#define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp))
-#define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE)
-#define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st))
-#define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st))
-#define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i))
-#define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val))
-#define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st))
-#define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val))
-#define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val))
-#define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val))
-#define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val))
-#define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i))
-#define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr))
-#define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i))
-#define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp))
-#define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st)
-#define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func))
-#define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st))
-#define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st))
-#define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st))
-#define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st))
-
-#define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp))
-#define sk_BIO_new_null() SKM_sk_new_null(BIO)
-#define sk_BIO_free(st) SKM_sk_free(BIO, (st))
-#define sk_BIO_num(st) SKM_sk_num(BIO, (st))
-#define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i))
-#define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val))
-#define sk_BIO_zero(st) SKM_sk_zero(BIO, (st))
-#define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val))
-#define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val))
-#define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val))
-#define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val))
-#define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i))
-#define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr))
-#define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i))
-#define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp))
-#define sk_BIO_dup(st) SKM_sk_dup(BIO, st)
-#define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func))
-#define sk_BIO_shift(st) SKM_sk_shift(BIO, (st))
-#define sk_BIO_pop(st) SKM_sk_pop(BIO, (st))
-#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
-#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
-
-#define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp))
-#define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY)
-#define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st))
-#define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st))
-#define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i))
-#define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val))
-#define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st))
-#define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val))
-#define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val))
-#define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val))
-#define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val))
-#define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i))
-#define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr))
-#define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i))
-#define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp))
-#define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st)
-#define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func))
-#define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st))
-#define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st))
-#define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st))
-#define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st))
-
-#define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp))
-#define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH)
-#define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st))
-#define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st))
-#define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i))
-#define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val))
-#define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st))
-#define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val))
-#define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val))
-#define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val))
-#define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val))
-#define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i))
-#define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr))
-#define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i))
-#define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp))
-#define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st)
-#define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func))
-#define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st))
-#define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st))
-#define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st))
-#define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st))
-
-#define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp))
-#define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices)
-#define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st))
-#define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st))
-#define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i))
-#define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val))
-#define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st))
-#define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val))
-#define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val))
-#define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val))
-#define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val))
-#define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i))
-#define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr))
-#define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i))
-#define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp))
-#define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st)
-#define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func))
-#define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st))
-#define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st))
-#define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st))
-#define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st))
-
-#define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp))
-#define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo)
-#define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st))
-#define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st))
-#define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i))
-#define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val))
-#define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st))
-#define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val))
-#define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val))
-#define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val))
-#define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val))
-#define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i))
-#define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr))
-#define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i))
-#define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp))
-#define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st)
-#define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func))
-#define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st))
-#define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st))
-#define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st))
-#define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st))
-
-#define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp))
-#define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice)
-#define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st))
-#define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st))
-#define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i))
-#define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val))
-#define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st))
-#define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val))
-#define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val))
-#define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val))
-#define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val))
-#define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i))
-#define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr))
-#define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i))
-#define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp))
-#define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st)
-#define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func))
-#define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st))
-#define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st))
-#define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st))
-#define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st))
-
-#define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp))
-#define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo)
-#define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st))
-#define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st))
-#define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i))
-#define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val))
-#define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st))
-#define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val))
-#define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val))
-#define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val))
-#define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val))
-#define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i))
-#define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr))
-#define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i))
-#define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp))
-#define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st)
-#define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func))
-#define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st))
-#define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st))
-#define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st))
-#define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st))
-
-#define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp))
-#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
-#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
-#define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st))
-#define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i))
-#define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val))
-#define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st))
-#define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val))
-#define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val))
-#define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val))
-#define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val))
-#define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i))
-#define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr))
-#define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i))
-#define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp))
-#define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st)
-#define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func))
-#define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st))
-#define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st))
-#define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st))
-#define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st))
-
-#define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp))
-#define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE)
-#define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st))
-#define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st))
-#define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i))
-#define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val))
-#define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st))
-#define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val))
-#define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val))
-#define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val))
-#define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val))
-#define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i))
-#define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr))
-#define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i))
-#define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp))
-#define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st)
-#define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func))
-#define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st))
-#define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st))
-#define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st))
-#define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st))
-
-#define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp))
-#define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE)
-#define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st))
-#define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st))
-#define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i))
-#define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val))
-#define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st))
-#define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val))
-#define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val))
-#define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val))
-#define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val))
-#define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i))
-#define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr))
-#define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i))
-#define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp))
-#define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st)
-#define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func))
-#define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st))
-#define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st))
-#define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st))
-#define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st))
-
-#define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp))
-#define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS)
-#define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st))
-#define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st))
-#define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i))
-#define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val))
-#define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st))
-#define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val))
-#define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val))
-#define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val))
-#define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val))
-#define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i))
-#define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr))
-#define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i))
-#define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp))
-#define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st)
-#define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func))
-#define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st))
-#define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st))
-#define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st))
-#define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st))
-
-#define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp))
-#define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock)
-#define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st))
-#define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st))
-#define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i))
-#define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val))
-#define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st))
-#define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val))
-#define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val))
-#define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val))
-#define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val))
-#define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i))
-#define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr))
-#define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i))
-#define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp))
-#define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st)
-#define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func))
-#define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st))
-#define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st))
-#define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st))
-#define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st))
-
-#define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp))
-#define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT)
-#define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st))
-#define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st))
-#define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i))
-#define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val))
-#define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st))
-#define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val))
-#define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val))
-#define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val))
-#define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val))
-#define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i))
-#define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr))
-#define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i))
-#define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp))
-#define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st)
-#define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func))
-#define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st))
-#define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st))
-#define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st))
-#define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st))
-
-#define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp))
-#define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE)
-#define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st))
-#define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st))
-#define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i))
-#define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val))
-#define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st))
-#define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val))
-#define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val))
-#define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val))
-#define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val))
-#define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i))
-#define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr))
-#define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i))
-#define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp))
-#define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st)
-#define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func))
-#define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st))
-#define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st))
-#define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st))
-#define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st))
-
-#define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp))
-#define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM)
-#define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st))
-#define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st))
-#define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i))
-#define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val))
-#define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st))
-#define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val))
-#define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val))
-#define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val))
-#define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val))
-#define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i))
-#define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr))
-#define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i))
-#define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp))
-#define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st)
-#define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func))
-#define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st))
-#define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st))
-#define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st))
-#define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st))
-
-#define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp))
-#define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID)
-#define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st))
-#define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st))
-#define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i))
-#define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val))
-#define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st))
-#define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val))
-#define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val))
-#define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val))
-#define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val))
-#define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i))
-#define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr))
-#define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i))
-#define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp))
-#define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st)
-#define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func))
-#define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st))
-#define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st))
-#define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st))
-#define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st))
-
-#define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp))
-#define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD)
-#define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st))
-#define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st))
-#define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i))
-#define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val))
-#define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st))
-#define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val))
-#define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val))
-#define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val))
-#define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val))
-#define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i))
-#define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr))
-#define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i))
-#define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp))
-#define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st)
-#define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func))
-#define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st))
-#define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st))
-#define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st))
-#define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st))
-
-#define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp))
-#define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL)
-#define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st))
-#define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st))
-#define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i))
-#define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val))
-#define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st))
-#define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val))
-#define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val))
-#define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val))
-#define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val))
-#define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i))
-#define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr))
-#define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i))
-#define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp))
-#define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st)
-#define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func))
-#define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st))
-#define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st))
-#define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st))
-#define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st))
-
-#define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp))
-#define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD)
-#define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st))
-#define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st))
-#define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i))
-#define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val))
-#define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st))
-#define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val))
-#define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val))
-#define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val))
-#define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val))
-#define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i))
-#define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr))
-#define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i))
-#define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp))
-#define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st)
-#define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func))
-#define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st))
-#define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st))
-#define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st))
-#define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st))
-
-#define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp))
-#define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD)
-#define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st))
-#define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st))
-#define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i))
-#define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val))
-#define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st))
-#define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val))
-#define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val))
-#define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val))
-#define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val))
-#define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i))
-#define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr))
-#define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i))
-#define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp))
-#define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st)
-#define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func))
-#define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st))
-#define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st))
-#define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st))
-#define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st))
-
-#define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp))
-#define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
-#define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st))
-#define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st))
-#define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i))
-#define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val))
-#define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st))
-#define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val))
-#define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val))
-#define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val))
-#define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val))
-#define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i))
-#define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr))
-#define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i))
-#define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp))
-#define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st)
-#define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func))
-#define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st))
-#define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st))
-#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
-#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
-
-#define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp))
-#define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES)
-#define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st))
-#define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st))
-#define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i))
-#define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val))
-#define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st))
-#define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val))
-#define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val))
-#define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val))
-#define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val))
-#define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i))
-#define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr))
-#define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i))
-#define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp))
-#define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st)
-#define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func))
-#define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st))
-#define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st))
-#define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st))
-#define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st))
-
-#define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp))
-#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
-#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
-#define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st))
-#define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i))
-#define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val))
-#define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st))
-#define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val))
-#define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val))
-#define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val))
-#define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val))
-#define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i))
-#define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr))
-#define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i))
-#define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp))
-#define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st)
-#define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func))
-#define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st))
-#define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st))
-#define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
-#define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
-
-#define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp))
-#define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
-#define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
-#define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
-#define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i))
-#define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val))
-#define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st))
-#define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val))
-#define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val))
-#define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val))
-#define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val))
-#define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i))
-#define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr))
-#define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i))
-#define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp))
-#define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st)
-#define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func))
-#define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st))
-#define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st))
-#define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
-#define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
-
-#define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp))
-#define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
-#define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
-#define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
-#define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i))
-#define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val))
-#define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st))
-#define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val))
-#define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val))
-#define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val))
-#define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val))
-#define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i))
-#define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr))
-#define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i))
-#define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp))
-#define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st)
-#define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func))
-#define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st))
-#define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st))
-#define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
-#define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
-
-#define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp))
-#define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
-#define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
-#define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st))
-#define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i))
-#define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val))
-#define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st))
-#define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val))
-#define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val))
-#define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val))
-#define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val))
-#define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i))
-#define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr))
-#define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i))
-#define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp))
-#define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st)
-#define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func))
-#define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st))
-#define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st))
-#define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st))
-#define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st))
-
-#define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp))
-#define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA)
-#define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st))
-#define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st))
-#define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i))
-#define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val))
-#define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st))
-#define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val))
-#define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val))
-#define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val))
-#define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val))
-#define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i))
-#define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr))
-#define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i))
-#define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp))
-#define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st)
-#define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func))
-#define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st))
-#define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st))
-#define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st))
-#define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st))
-
-#define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp))
-#define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY)
-#define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st))
-#define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st))
-#define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i))
-#define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val))
-#define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st))
-#define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val))
-#define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val))
-#define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val))
-#define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val))
-#define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i))
-#define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr))
-#define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i))
-#define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp))
-#define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st)
-#define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func))
-#define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st))
-#define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st))
-#define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st))
-#define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st))
-
-#define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp))
-#define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM)
-#define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st))
-#define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st))
-#define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i))
-#define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val))
-#define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st))
-#define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val))
-#define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val))
-#define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val))
-#define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val))
-#define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i))
-#define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr))
-#define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i))
-#define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp))
-#define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st)
-#define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func))
-#define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st))
-#define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st))
-#define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st))
-#define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st))
-
-#define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp))
-#define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA)
-#define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st))
-#define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st))
-#define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i))
-#define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val))
-#define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st))
-#define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val))
-#define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val))
-#define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val))
-#define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val))
-#define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i))
-#define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr))
-#define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i))
-#define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp))
-#define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st)
-#define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func))
-#define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st))
-#define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st))
-#define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st))
-#define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st))
-
-#define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp))
-#define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY)
-#define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st))
-#define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st))
-#define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i))
-#define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val))
-#define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st))
-#define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val))
-#define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val))
-#define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val))
-#define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val))
-#define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i))
-#define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr))
-#define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i))
-#define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp))
-#define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st)
-#define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func))
-#define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st))
-#define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st))
-#define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st))
-#define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st))
-
-#define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp))
-#define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME)
-#define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st))
-#define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st))
-#define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i))
-#define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val))
-#define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st))
-#define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val))
-#define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val))
-#define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val))
-#define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val))
-#define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i))
-#define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr))
-#define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i))
-#define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp))
-#define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st)
-#define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func))
-#define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st))
-#define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st))
-#define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st))
-#define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st))
-
-#define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp))
-#define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY)
-#define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st))
-#define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st))
-#define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i))
-#define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val))
-#define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st))
-#define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val))
-#define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val))
-#define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val))
-#define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val))
-#define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i))
-#define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr))
-#define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i))
-#define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp))
-#define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st)
-#define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func))
-#define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st))
-#define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st))
-#define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st))
-#define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st))
-
-#define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp))
-#define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA)
-#define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st))
-#define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st))
-#define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i))
-#define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val))
-#define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st))
-#define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val))
-#define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val))
-#define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val))
-#define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val))
-#define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i))
-#define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr))
-#define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i))
-#define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp))
-#define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st)
-#define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func))
-#define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st))
-#define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st))
-#define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st))
-#define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st))
-
-#define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp))
-#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
-#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
-#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
-#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i))
-#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val))
-#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st))
-#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val))
-#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val))
-#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val))
-#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val))
-#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i))
-#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr))
-#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i))
-#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp))
-#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st)
-#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func))
-#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st))
-#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st))
-#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
-#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
-
-#define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp))
-#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
-#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
-#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
-#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i))
-#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val))
-#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st))
-#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val))
-#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val))
-#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val))
-#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val))
-#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i))
-#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr))
-#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i))
-#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp))
-#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st)
-#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func))
-#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st))
-#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st))
-#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
-#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
-
-#define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp))
-#define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS)
-#define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st))
-#define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st))
-#define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i))
-#define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val))
-#define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st))
-#define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val))
-#define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val))
-#define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val))
-#define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val))
-#define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i))
-#define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr))
-#define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i))
-#define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp))
-#define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st)
-#define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func))
-#define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st))
-#define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st))
-#define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
-#define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st))
-
-#define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp))
-#define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
-#define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
-#define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
-#define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i))
-#define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val))
-#define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st))
-#define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val))
-#define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val))
-#define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val))
-#define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val))
-#define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i))
-#define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr))
-#define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i))
-#define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp))
-#define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st)
-#define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func))
-#define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st))
-#define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st))
-#define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
-#define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st))
-
-#define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp))
-#define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
-#define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
-#define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st))
-#define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i))
-#define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val))
-#define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st))
-#define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val))
-#define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val))
-#define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val))
-#define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val))
-#define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i))
-#define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr))
-#define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i))
-#define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp))
-#define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st)
-#define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func))
-#define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st))
-#define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st))
-#define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
-#define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
-
-#define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp))
-#define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID)
-#define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st))
-#define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st))
-#define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i))
-#define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val))
-#define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st))
-#define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val))
-#define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val))
-#define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val))
-#define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val))
-#define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i))
-#define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr))
-#define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i))
-#define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp))
-#define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st)
-#define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func))
-#define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st))
-#define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st))
-#define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st))
-#define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st))
-
-#define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp))
-#define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
-#define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
-#define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st))
-#define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i))
-#define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val))
-#define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st))
-#define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val))
-#define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val))
-#define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val))
-#define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val))
-#define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i))
-#define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr))
-#define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i))
-#define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp))
-#define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st)
-#define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func))
-#define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st))
-#define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st))
-#define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st))
-#define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st))
-
-#define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp))
-#define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG)
-#define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st))
-#define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st))
-#define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i))
-#define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val))
-#define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st))
-#define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val))
-#define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val))
-#define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val))
-#define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val))
-#define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i))
-#define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr))
-#define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i))
-#define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp))
-#define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st)
-#define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func))
-#define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st))
-#define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st))
-#define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st))
-#define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st))
-
-#define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp))
-#define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7)
-#define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st))
-#define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st))
-#define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i))
-#define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val))
-#define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st))
-#define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val))
-#define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val))
-#define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val))
-#define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val))
-#define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i))
-#define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr))
-#define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i))
-#define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp))
-#define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st)
-#define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func))
-#define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st))
-#define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st))
-#define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st))
-#define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st))
-
-#define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp))
-#define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO)
-#define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st))
-#define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st))
-#define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i))
-#define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val))
-#define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st))
-#define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val))
-#define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val))
-#define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val))
-#define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val))
-#define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i))
-#define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr))
-#define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i))
-#define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp))
-#define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st)
-#define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func))
-#define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st))
-#define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st))
-#define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st))
-#define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st))
-
-#define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp))
-#define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO)
-#define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st))
-#define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st))
-#define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i))
-#define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val))
-#define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st))
-#define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val))
-#define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val))
-#define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val))
-#define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val))
-#define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i))
-#define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr))
-#define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i))
-#define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp))
-#define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st)
-#define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func))
-#define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st))
-#define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st))
-#define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st))
-#define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st))
-
-#define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp))
-#define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO)
-#define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st))
-#define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st))
-#define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i))
-#define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val))
-#define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st))
-#define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val))
-#define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val))
-#define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val))
-#define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val))
-#define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i))
-#define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr))
-#define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i))
-#define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp))
-#define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st)
-#define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func))
-#define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st))
-#define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st))
-#define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st))
-#define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st))
-
-#define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp))
-#define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO)
-#define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st))
-#define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st))
-#define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i))
-#define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val))
-#define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st))
-#define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val))
-#define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val))
-#define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val))
-#define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val))
-#define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i))
-#define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr))
-#define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i))
-#define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp))
-#define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st)
-#define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func))
-#define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st))
-#define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st))
-#define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st))
-#define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st))
-
-#define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp))
-#define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING)
-#define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st))
-#define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st))
-#define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i))
-#define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val))
-#define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st))
-#define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val))
-#define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val))
-#define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val))
-#define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val))
-#define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i))
-#define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr))
-#define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i))
-#define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp))
-#define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st)
-#define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func))
-#define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st))
-#define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st))
-#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
-#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
-
-#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
-#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
-#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
-#define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st))
-#define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i))
-#define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val))
-#define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st))
-#define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val))
-#define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val))
-#define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val))
-#define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val))
-#define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i))
-#define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr))
-#define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i))
-#define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp))
-#define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st)
-#define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func))
-#define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st))
-#define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st))
-#define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st))
-#define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st))
-
-#define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp))
-#define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP)
-#define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st))
-#define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st))
-#define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i))
-#define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val))
-#define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st))
-#define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val))
-#define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val))
-#define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val))
-#define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val))
-#define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i))
-#define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr))
-#define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i))
-#define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp))
-#define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st)
-#define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func))
-#define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st))
-#define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st))
-#define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st))
-#define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st))
-
-#define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp))
-#define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY)
-#define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st))
-#define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st))
-#define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i))
-#define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val))
-#define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st))
-#define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val))
-#define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val))
-#define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val))
-#define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val))
-#define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i))
-#define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr))
-#define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i))
-#define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp))
-#define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st)
-#define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func))
-#define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st))
-#define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st))
-#define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st))
-#define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st))
-
-#define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp))
-#define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO)
-#define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st))
-#define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st))
-#define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i))
-#define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val))
-#define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st))
-#define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val))
-#define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val))
-#define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val))
-#define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val))
-#define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i))
-#define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr))
-#define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i))
-#define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp))
-#define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st)
-#define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func))
-#define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st))
-#define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st))
-#define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st))
-#define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st))
-
-#define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp))
-#define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT)
-#define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st))
-#define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st))
-#define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i))
-#define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val))
-#define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st))
-#define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val))
-#define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val))
-#define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val))
-#define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val))
-#define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i))
-#define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr))
-#define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i))
-#define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp))
-#define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st)
-#define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func))
-#define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st))
-#define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st))
-#define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st))
-#define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st))
-
-#define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp))
-#define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID)
-#define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st))
-#define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st))
-#define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i))
-#define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val))
-#define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st))
-#define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val))
-#define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val))
-#define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val))
-#define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val))
-#define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i))
-#define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr))
-#define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i))
-#define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp))
-#define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st)
-#define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func))
-#define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st))
-#define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st))
-#define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st))
-#define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st))
-
-#define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp))
-#define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING)
-#define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st))
-#define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st))
-#define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i))
-#define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val))
-#define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st))
-#define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val))
-#define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val))
-#define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val))
-#define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val))
-#define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i))
-#define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr))
-#define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i))
-#define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp))
-#define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st)
-#define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func))
-#define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st))
-#define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st))
-#define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st))
-#define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st))
-
-#define sk_X509_new(cmp) SKM_sk_new(X509, (cmp))
-#define sk_X509_new_null() SKM_sk_new_null(X509)
-#define sk_X509_free(st) SKM_sk_free(X509, (st))
-#define sk_X509_num(st) SKM_sk_num(X509, (st))
-#define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i))
-#define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val))
-#define sk_X509_zero(st) SKM_sk_zero(X509, (st))
-#define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val))
-#define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val))
-#define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val))
-#define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val))
-#define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i))
-#define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr))
-#define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i))
-#define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp))
-#define sk_X509_dup(st) SKM_sk_dup(X509, st)
-#define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func))
-#define sk_X509_shift(st) SKM_sk_shift(X509, (st))
-#define sk_X509_pop(st) SKM_sk_pop(X509, (st))
-#define sk_X509_sort(st) SKM_sk_sort(X509, (st))
-#define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st))
-
-#define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp))
-#define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD)
-#define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st))
-#define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st))
-#define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i))
-#define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val))
-#define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st))
-#define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val))
-#define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val))
-#define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val))
-#define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val))
-#define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i))
-#define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr))
-#define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i))
-#define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp))
-#define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st)
-#define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func))
-#define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st))
-#define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st))
-#define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st))
-#define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st))
-
-#define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp))
-#define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR)
-#define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st))
-#define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st))
-#define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i))
-#define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val))
-#define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st))
-#define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val))
-#define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val))
-#define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val))
-#define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val))
-#define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i))
-#define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr))
-#define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i))
-#define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp))
-#define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st)
-#define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func))
-#define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st))
-#define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st))
-#define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st))
-#define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st))
-
-#define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp))
-#define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE)
-#define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st))
-#define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st))
-#define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i))
-#define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val))
-#define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st))
-#define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val))
-#define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val))
-#define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val))
-#define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val))
-#define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i))
-#define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr))
-#define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i))
-#define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp))
-#define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st)
-#define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func))
-#define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st))
-#define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st))
-#define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st))
-#define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st))
-
-#define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp))
-#define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL)
-#define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st))
-#define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st))
-#define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i))
-#define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val))
-#define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st))
-#define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val))
-#define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val))
-#define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val))
-#define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val))
-#define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i))
-#define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr))
-#define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i))
-#define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp))
-#define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st)
-#define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func))
-#define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st))
-#define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st))
-#define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st))
-#define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st))
-
-#define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp))
-#define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION)
-#define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st))
-#define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st))
-#define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i))
-#define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val))
-#define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st))
-#define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val))
-#define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val))
-#define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val))
-#define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val))
-#define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i))
-#define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr))
-#define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i))
-#define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp))
-#define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st)
-#define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func))
-#define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st))
-#define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st))
-#define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st))
-#define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st))
-
-#define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp))
-#define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO)
-#define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st))
-#define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st))
-#define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i))
-#define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val))
-#define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st))
-#define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val))
-#define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val))
-#define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val))
-#define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val))
-#define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i))
-#define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr))
-#define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i))
-#define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp))
-#define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st)
-#define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func))
-#define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st))
-#define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st))
-#define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st))
-#define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st))
-
-#define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp))
-#define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP)
-#define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st))
-#define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st))
-#define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i))
-#define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val))
-#define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st))
-#define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val))
-#define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val))
-#define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val))
-#define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val))
-#define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i))
-#define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr))
-#define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i))
-#define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp))
-#define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st)
-#define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func))
-#define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st))
-#define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st))
-#define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st))
-#define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st))
-
-#define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp))
-#define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME)
-#define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st))
-#define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st))
-#define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i))
-#define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val))
-#define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st))
-#define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val))
-#define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val))
-#define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val))
-#define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val))
-#define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i))
-#define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr))
-#define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i))
-#define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp))
-#define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st)
-#define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func))
-#define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st))
-#define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st))
-#define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st))
-#define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st))
-
-#define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp))
-#define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY)
-#define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st))
-#define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st))
-#define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i))
-#define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val))
-#define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st))
-#define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val))
-#define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val))
-#define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val))
-#define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val))
-#define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i))
-#define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr))
-#define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i))
-#define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp))
-#define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st)
-#define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func))
-#define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st))
-#define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st))
-#define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st))
-#define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st))
-
-#define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp))
-#define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT)
-#define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st))
-#define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st))
-#define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i))
-#define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val))
-#define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st))
-#define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val))
-#define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val))
-#define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val))
-#define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val))
-#define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i))
-#define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr))
-#define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i))
-#define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp))
-#define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st)
-#define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func))
-#define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st))
-#define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st))
-#define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st))
-#define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st))
-
-#define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp))
-#define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA)
-#define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st))
-#define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st))
-#define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i))
-#define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val))
-#define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st))
-#define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val))
-#define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val))
-#define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val))
-#define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val))
-#define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i))
-#define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr))
-#define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i))
-#define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp))
-#define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st)
-#define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func))
-#define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st))
-#define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st))
-#define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st))
-#define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st))
-
-#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp))
-#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
-#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
-#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
-#define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i))
-#define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val))
-#define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st))
-#define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val))
-#define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val))
-#define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val))
-#define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val))
-#define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i))
-#define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr))
-#define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i))
-#define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp))
-#define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st)
-#define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func))
-#define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st))
-#define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st))
-#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
-#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
-
-#define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp))
-#define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE)
-#define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st))
-#define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st))
-#define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i))
-#define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val))
-#define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st))
-#define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val))
-#define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val))
-#define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val))
-#define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val))
-#define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i))
-#define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr))
-#define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i))
-#define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp))
-#define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st)
-#define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func))
-#define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st))
-#define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st))
-#define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st))
-#define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st))
-
-#define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp))
-#define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED)
-#define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st))
-#define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st))
-#define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i))
-#define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val))
-#define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st))
-#define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val))
-#define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val))
-#define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val))
-#define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val))
-#define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i))
-#define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr))
-#define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i))
-#define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp))
-#define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st)
-#define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func))
-#define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st))
-#define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st))
-#define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st))
-#define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st))
-
-#define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp))
-#define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST)
-#define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st))
-#define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st))
-#define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i))
-#define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val))
-#define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st))
-#define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val))
-#define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val))
-#define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val))
-#define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val))
-#define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i))
-#define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr))
-#define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i))
-#define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp))
-#define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st)
-#define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func))
-#define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st))
-#define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st))
-#define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st))
-#define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st))
-
-#define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp))
-#define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM)
-#define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st))
-#define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st))
-#define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i))
-#define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val))
-#define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st))
-#define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val))
-#define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val))
-#define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val))
-#define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val))
-#define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i))
-#define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr))
-#define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i))
-#define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp))
-#define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st)
-#define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func))
-#define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st))
-#define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st))
-#define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
-#define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
-
-#define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp))
-#define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple)
-#define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st))
-#define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st))
-#define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i))
-#define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val))
-#define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st))
-#define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val))
-#define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val))
-#define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val))
-#define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val))
-#define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i))
-#define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr))
-#define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i))
-#define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp))
-#define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st)
-#define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func))
-#define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st))
-#define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st))
-#define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st))
-#define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st))
-
-#define sk_void_new(cmp) SKM_sk_new(void, (cmp))
-#define sk_void_new_null() SKM_sk_new_null(void)
-#define sk_void_free(st) SKM_sk_free(void, (st))
-#define sk_void_num(st) SKM_sk_num(void, (st))
-#define sk_void_value(st, i) SKM_sk_value(void, (st), (i))
-#define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val))
-#define sk_void_zero(st) SKM_sk_zero(void, (st))
-#define sk_void_push(st, val) SKM_sk_push(void, (st), (val))
-#define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val))
-#define sk_void_find(st, val) SKM_sk_find(void, (st), (val))
-#define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val))
-#define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i))
-#define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr))
-#define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i))
-#define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp))
-#define sk_void_dup(st) SKM_sk_dup(void, st)
-#define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func))
-#define sk_void_shift(st) SKM_sk_shift(void, (st))
-#define sk_void_pop(st) SKM_sk_pop(void, (st))
-#define sk_void_sort(st) SKM_sk_sort(void, (st))
-#define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st))
-
-#define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp)))
-#define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null())
-#define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
-#define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
-#define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i))
-#define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st)
-#define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func))
-#define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i)
-#define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st)
-#define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val))
-#define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st))
-#define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
-#define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val))
-#define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i))
-#define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr))
-#define sk_OPENSSL_STRING_set_cmp_func(st, cmp) \
- ((int (*)(const char * const *,const char * const *)) \
- sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp)))
-#define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st)
-#define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st))
-#define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st))
-#define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st))
-#define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st))
-
-
-#define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp)))
-#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null())
-#define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
-#define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
-#define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i))
-#define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st)
-#define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func))
-#define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i)
-#define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st)
-#define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val))
-#define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st))
-#define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
-#define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val))
-#define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i))
-#define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr))
-#define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp) \
- ((int (*)(const void * const *,const void * const *)) \
- sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp)))
-#define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st)
-#define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st))
-#define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st))
-#define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st))
-#define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st))
-
-
-#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
-#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null())
-#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
-#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
-#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i))
-#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st)
-#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func))
-#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i)
-#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st)
-#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val))
-#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st))
-#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
-#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val))
-#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i))
-#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr))
-#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \
- ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \
- sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
-#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st)
-#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st))
-#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st))
-#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st))
-#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st))
-
-
-#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_X509(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func))
-
-#define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \
- SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \
- SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \
- SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func))
-
-#define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \
- SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
-
-#define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \
- SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
-
-#define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj)
-#define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst)
-#define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst)
-#define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst)
-#define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn)
-#define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg)
-#define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh)
-#define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh)
-#define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh)
-#define lh_ADDED_OBJ_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(ADDED_OBJ,lh,out)
-#define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out)
-#define lh_ADDED_OBJ_stats_bio(lh,out) \
- LHM_lh_stats_bio(ADDED_OBJ,lh,out)
-#define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh)
-
-#define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info)
-#define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst)
-#define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst)
-#define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst)
-#define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn)
-#define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg)
-#define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh)
-#define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh)
-#define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh)
-#define lh_APP_INFO_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(APP_INFO,lh,out)
-#define lh_APP_INFO_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(APP_INFO,lh,out)
-#define lh_APP_INFO_stats_bio(lh,out) \
- LHM_lh_stats_bio(APP_INFO,lh,out)
-#define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh)
-
-#define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value)
-#define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst)
-#define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst)
-#define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst)
-#define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn)
-#define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg)
-#define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh)
-#define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh)
-#define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh)
-#define lh_CONF_VALUE_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(CONF_VALUE,lh,out)
-#define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out)
-#define lh_CONF_VALUE_stats_bio(lh,out) \
- LHM_lh_stats_bio(CONF_VALUE,lh,out)
-#define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh)
-
-#define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile)
-#define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst)
-#define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst)
-#define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst)
-#define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn)
-#define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg)
-#define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh)
-#define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh)
-#define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh)
-#define lh_ENGINE_PILE_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(ENGINE_PILE,lh,out)
-#define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out)
-#define lh_ENGINE_PILE_stats_bio(lh,out) \
- LHM_lh_stats_bio(ENGINE_PILE,lh,out)
-#define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh)
-
-#define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state)
-#define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst)
-#define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst)
-#define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst)
-#define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn)
-#define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg)
-#define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh)
-#define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh)
-#define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh)
-#define lh_ERR_STATE_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(ERR_STATE,lh,out)
-#define lh_ERR_STATE_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out)
-#define lh_ERR_STATE_stats_bio(lh,out) \
- LHM_lh_stats_bio(ERR_STATE,lh,out)
-#define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh)
-
-#define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data)
-#define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst)
-#define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst)
-#define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst)
-#define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn)
-#define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg)
-#define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh)
-#define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh)
-#define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh)
-#define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out)
-#define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out)
-#define lh_ERR_STRING_DATA_stats_bio(lh,out) \
- LHM_lh_stats_bio(ERR_STRING_DATA,lh,out)
-#define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh)
-
-#define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item)
-#define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst)
-#define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst)
-#define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst)
-#define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn)
-#define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg)
-#define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh)
-#define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh)
-#define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh)
-#define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out)
-#define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out)
-#define lh_EX_CLASS_ITEM_stats_bio(lh,out) \
- LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out)
-#define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh)
-
-#define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function)
-#define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst)
-#define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst)
-#define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst)
-#define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn)
-#define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg)
-#define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh)
-#define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh)
-#define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh)
-#define lh_FUNCTION_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(FUNCTION,lh,out)
-#define lh_FUNCTION_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(FUNCTION,lh,out)
-#define lh_FUNCTION_stats_bio(lh,out) \
- LHM_lh_stats_bio(FUNCTION,lh,out)
-#define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh)
-
-#define lh_MEM_new() LHM_lh_new(MEM,mem)
-#define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst)
-#define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst)
-#define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst)
-#define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn)
-#define lh_MEM_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg)
-#define lh_MEM_error(lh) LHM_lh_error(MEM,lh)
-#define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh)
-#define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh)
-#define lh_MEM_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(MEM,lh,out)
-#define lh_MEM_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(MEM,lh,out)
-#define lh_MEM_stats_bio(lh,out) \
- LHM_lh_stats_bio(MEM,lh,out)
-#define lh_MEM_free(lh) LHM_lh_free(MEM,lh)
-
-#define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name)
-#define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst)
-#define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst)
-#define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst)
-#define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn)
-#define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg)
-#define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh)
-#define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh)
-#define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh)
-#define lh_OBJ_NAME_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(OBJ_NAME,lh,out)
-#define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out)
-#define lh_OBJ_NAME_stats_bio(lh,out) \
- LHM_lh_stats_bio(OBJ_NAME,lh,out)
-#define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh)
-
-#define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring)
-#define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst)
-#define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst)
-#define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst)
-#define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn)
-#define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg)
-#define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh)
-#define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh)
-#define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh)
-#define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out)
-#define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out)
-#define lh_OPENSSL_CSTRING_stats_bio(lh,out) \
- LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out)
-#define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh)
-
-#define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string)
-#define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst)
-#define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst)
-#define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst)
-#define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn)
-#define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg)
-#define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh)
-#define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh)
-#define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh)
-#define lh_OPENSSL_STRING_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out)
-#define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out)
-#define lh_OPENSSL_STRING_stats_bio(lh,out) \
- LHM_lh_stats_bio(OPENSSL_STRING,lh,out)
-#define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh)
-
-#define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session)
-#define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst)
-#define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst)
-#define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst)
-#define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn)
-#define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \
- LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg)
-#define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh)
-#define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh)
-#define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh)
-#define lh_SSL_SESSION_node_stats_bio(lh,out) \
- LHM_lh_node_stats_bio(SSL_SESSION,lh,out)
-#define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \
- LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out)
-#define lh_SSL_SESSION_stats_bio(lh,out) \
- LHM_lh_stats_bio(SSL_SESSION,lh,out)
-#define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh)
-/* End of util/mkstack.pl block, you may now edit :-) */
-
-#endif /* !defined HEADER_SAFESTACK_H */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_SAFESTACK_H
+#define HEADER_SAFESTACK_H
+
+#include <openssl/stack.h>
+
+#ifndef CHECKED_PTR_OF
+#define CHECKED_PTR_OF(type, p) \
+ ((void*) (1 ? p : (type*)0))
+#endif
+
+/* In C++ we get problems because an explicit cast is needed from (void *)
+ * we use CHECKED_STACK_OF to ensure the correct type is passed in the macros
+ * below.
+ */
+
+#define CHECKED_STACK_OF(type, p) \
+ ((_STACK*) (1 ? p : (STACK_OF(type)*)0))
+
+#define CHECKED_SK_FREE_FUNC(type, p) \
+ ((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))
+
+#define CHECKED_SK_FREE_FUNC2(type, p) \
+ ((void (*)(void *)) ((1 ? p : (void (*)(type))0)))
+
+#define CHECKED_SK_CMP_FUNC(type, p) \
+ ((int (*)(const void *, const void *)) \
+ ((1 ? p : (int (*)(const type * const *, const type * const *))0)))
+
+#define STACK_OF(type) struct stack_st_##type
+#define PREDECLARE_STACK_OF(type) STACK_OF(type);
+
+#define DECLARE_STACK_OF(type) \
+STACK_OF(type) \
+ { \
+ _STACK stack; \
+ };
+#define DECLARE_SPECIAL_STACK_OF(type, type2) \
+STACK_OF(type) \
+ { \
+ _STACK stack; \
+ };
+
+#define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/
+
+
+/* Strings are special: normally an lhash entry will point to a single
+ * (somewhat) mutable object. In the case of strings:
+ *
+ * a) Instead of a single char, there is an array of chars, NUL-terminated.
+ * b) The string may have be immutable.
+ *
+ * So, they need their own declarations. Especially important for
+ * type-checking tools, such as Deputy.
+ *
+o * In practice, however, it appears to be hard to have a const
+ * string. For now, I'm settling for dealing with the fact it is a
+ * string at all.
+ */
+typedef char *OPENSSL_STRING;
+
+typedef const char *OPENSSL_CSTRING;
+
+/* Confusingly, LHASH_OF(STRING) deals with char ** throughout, but
+ * STACK_OF(STRING) is really more like STACK_OF(char), only, as
+ * mentioned above, instead of a single char each entry is a
+ * NUL-terminated array of chars. So, we have to implement STRING
+ * specially for STACK_OF. This is dealt with in the autogenerated
+ * macros below.
+ */
+
+DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
+
+/* Similarly, we sometimes use a block of characters, NOT
+ * nul-terminated. These should also be distinguished from "normal"
+ * stacks. */
+
+typedef void *OPENSSL_BLOCK;
+DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
+
+/* SKM_sk_... stack macros are internal to safestack.h:
+ * never use them directly, use sk_<type>_... instead */
+#define SKM_sk_new(type, cmp) \
+ ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp)))
+#define SKM_sk_new_null(type) \
+ ((STACK_OF(type) *)sk_new_null())
+#define SKM_sk_free(type, st) \
+ sk_free(CHECKED_STACK_OF(type, st))
+#define SKM_sk_num(type, st) \
+ sk_num(CHECKED_STACK_OF(type, st))
+#define SKM_sk_value(type, st,i) \
+ ((type *)sk_value(CHECKED_STACK_OF(type, st), i))
+#define SKM_sk_set(type, st,i,val) \
+ sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val))
+#define SKM_sk_zero(type, st) \
+ sk_zero(CHECKED_STACK_OF(type, st))
+#define SKM_sk_push(type, st, val) \
+ sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+#define SKM_sk_unshift(type, st, val) \
+ sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+#define SKM_sk_find(type, st, val) \
+ sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+#define SKM_sk_find_ex(type, st, val) \
+ sk_find_ex(CHECKED_STACK_OF(type, st), \
+ CHECKED_PTR_OF(type, val))
+#define SKM_sk_delete(type, st, i) \
+ (type *)sk_delete(CHECKED_STACK_OF(type, st), i)
+#define SKM_sk_delete_ptr(type, st, ptr) \
+ (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr))
+#define SKM_sk_insert(type, st,val, i) \
+ sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i)
+#define SKM_sk_set_cmp_func(type, st, cmp) \
+ ((int (*)(const type * const *,const type * const *)) \
+ sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp)))
+#define SKM_sk_dup(type, st) \
+ (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st))
+#define SKM_sk_pop_free(type, st, free_func) \
+ sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func))
+#define SKM_sk_shift(type, st) \
+ (type *)sk_shift(CHECKED_STACK_OF(type, st))
+#define SKM_sk_pop(type, st) \
+ (type *)sk_pop(CHECKED_STACK_OF(type, st))
+#define SKM_sk_sort(type, st) \
+ sk_sort(CHECKED_STACK_OF(type, st))
+#define SKM_sk_is_sorted(type, st) \
+ sk_is_sorted(CHECKED_STACK_OF(type, st))
+
+#define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ (STACK_OF(type) *)d2i_ASN1_SET( \
+ (STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \
+ pp, length, \
+ CHECKED_D2I_OF(type, d2i_func), \
+ CHECKED_SK_FREE_FUNC(type, free_func), \
+ ex_tag, ex_class)
+
+#define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \
+ CHECKED_I2D_OF(type, i2d_func), \
+ ex_tag, ex_class, is_set)
+
+#define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
+ ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \
+ CHECKED_I2D_OF(type, i2d_func), buf, len)
+
+#define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
+ (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func))
+
+#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
+ (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \
+ CHECKED_D2I_OF(type, d2i_func), \
+ CHECKED_SK_FREE_FUNC(type, free_func), \
+ pass, passlen, oct, seq)
+
+/* This block of defines is updated by util/mkstack.pl, please do not touch! */
+#define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp))
+#define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION)
+#define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i))
+#define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val))
+#define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i))
+#define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr))
+#define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i))
+#define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp))
+#define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st)
+#define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func))
+#define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
+
+#define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp))
+#define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
+#define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
+#define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
+#define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i))
+#define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val))
+#define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st))
+#define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val))
+#define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i))
+#define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr))
+#define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i))
+#define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp))
+#define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st)
+#define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func))
+#define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st))
+#define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st))
+#define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
+#define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
+
+#define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp))
+#define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
+#define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i))
+#define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val))
+#define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i))
+#define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr))
+#define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i))
+#define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp))
+#define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st)
+#define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func))
+#define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st))
+
+#define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp))
+#define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER)
+#define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i))
+#define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val))
+#define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i))
+#define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr))
+#define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i))
+#define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp))
+#define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st)
+#define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func))
+#define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st))
+
+#define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp))
+#define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT)
+#define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i))
+#define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val))
+#define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i))
+#define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr))
+#define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i))
+#define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp))
+#define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st)
+#define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func))
+#define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st))
+
+#define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp))
+#define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE)
+#define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i))
+#define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val))
+#define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i))
+#define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr))
+#define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i))
+#define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp))
+#define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st)
+#define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func))
+#define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st))
+
+#define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp))
+#define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE)
+#define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i))
+#define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val))
+#define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i))
+#define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr))
+#define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i))
+#define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp))
+#define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st)
+#define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func))
+#define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st))
+
+#define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp))
+#define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING)
+#define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i))
+#define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val))
+#define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i))
+#define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr))
+#define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i))
+#define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp))
+#define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st)
+#define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func))
+#define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st))
+
+#define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp))
+#define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE)
+#define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i))
+#define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val))
+#define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i))
+#define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr))
+#define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i))
+#define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp))
+#define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st)
+#define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func))
+#define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st))
+
+#define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp))
+#define sk_BIO_new_null() SKM_sk_new_null(BIO)
+#define sk_BIO_free(st) SKM_sk_free(BIO, (st))
+#define sk_BIO_num(st) SKM_sk_num(BIO, (st))
+#define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i))
+#define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val))
+#define sk_BIO_zero(st) SKM_sk_zero(BIO, (st))
+#define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val))
+#define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val))
+#define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val))
+#define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val))
+#define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i))
+#define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr))
+#define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i))
+#define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp))
+#define sk_BIO_dup(st) SKM_sk_dup(BIO, st)
+#define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func))
+#define sk_BIO_shift(st) SKM_sk_shift(BIO, (st))
+#define sk_BIO_pop(st) SKM_sk_pop(BIO, (st))
+#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
+#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
+
+#define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp))
+#define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY)
+#define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i))
+#define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val))
+#define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i))
+#define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr))
+#define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i))
+#define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp))
+#define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st)
+#define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func))
+#define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st))
+
+#define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp))
+#define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH)
+#define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i))
+#define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val))
+#define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i))
+#define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr))
+#define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i))
+#define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp))
+#define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st)
+#define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func))
+#define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st))
+
+#define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp))
+#define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices)
+#define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st))
+#define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st))
+#define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i))
+#define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val))
+#define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st))
+#define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val))
+#define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val))
+#define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val))
+#define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val))
+#define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i))
+#define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr))
+#define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i))
+#define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp))
+#define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st)
+#define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func))
+#define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st))
+#define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st))
+#define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st))
+#define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st))
+
+#define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp))
+#define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo)
+#define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i))
+#define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val))
+#define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val))
+#define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val))
+#define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val))
+#define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val))
+#define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i))
+#define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr))
+#define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i))
+#define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp))
+#define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st)
+#define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func))
+#define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st))
+
+#define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp))
+#define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice)
+#define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i))
+#define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val))
+#define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val))
+#define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val))
+#define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val))
+#define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val))
+#define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i))
+#define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr))
+#define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i))
+#define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp))
+#define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st)
+#define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func))
+#define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st))
+
+#define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp))
+#define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo)
+#define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i))
+#define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val))
+#define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val))
+#define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val))
+#define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val))
+#define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val))
+#define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i))
+#define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr))
+#define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i))
+#define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp))
+#define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st)
+#define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func))
+#define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st))
+
+#define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp))
+#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
+#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i))
+#define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val))
+#define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i))
+#define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr))
+#define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i))
+#define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp))
+#define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st)
+#define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func))
+#define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st))
+
+#define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp))
+#define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE)
+#define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st))
+#define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st))
+#define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i))
+#define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val))
+#define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st))
+#define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i))
+#define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr))
+#define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i))
+#define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp))
+#define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st)
+#define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func))
+#define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st))
+#define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st))
+#define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st))
+#define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st))
+
+#define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp))
+#define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE)
+#define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st))
+#define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st))
+#define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i))
+#define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val))
+#define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st))
+#define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i))
+#define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr))
+#define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i))
+#define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp))
+#define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st)
+#define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func))
+#define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st))
+#define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st))
+#define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st))
+#define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st))
+
+#define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp))
+#define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS)
+#define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i))
+#define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i))
+#define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr))
+#define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i))
+#define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp))
+#define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st)
+#define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func))
+#define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st))
+
+#define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp))
+#define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock)
+#define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i))
+#define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val))
+#define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i))
+#define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr))
+#define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i))
+#define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp))
+#define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st)
+#define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func))
+#define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st))
+
+#define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp))
+#define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT)
+#define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st))
+#define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st))
+#define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i))
+#define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val))
+#define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st))
+#define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i))
+#define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr))
+#define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i))
+#define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp))
+#define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st)
+#define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func))
+#define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st))
+#define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st))
+#define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st))
+#define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st))
+
+#define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp))
+#define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE)
+#define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st))
+#define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st))
+#define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i))
+#define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val))
+#define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st))
+#define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val))
+#define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val))
+#define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val))
+#define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val))
+#define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i))
+#define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr))
+#define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i))
+#define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp))
+#define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st)
+#define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func))
+#define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st))
+#define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st))
+#define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st))
+#define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st))
+
+#define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp))
+#define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM)
+#define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i))
+#define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val))
+#define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i))
+#define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr))
+#define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i))
+#define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp))
+#define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st)
+#define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func))
+#define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st))
+
+#define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp))
+#define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID)
+#define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i))
+#define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val))
+#define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i))
+#define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr))
+#define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i))
+#define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp))
+#define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st)
+#define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func))
+#define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st))
+
+#define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp))
+#define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD)
+#define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st))
+#define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st))
+#define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i))
+#define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val))
+#define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st))
+#define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val))
+#define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val))
+#define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val))
+#define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val))
+#define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i))
+#define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr))
+#define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i))
+#define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp))
+#define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st)
+#define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func))
+#define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st))
+#define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st))
+#define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st))
+#define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st))
+
+#define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp))
+#define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL)
+#define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i))
+#define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val))
+#define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i))
+#define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr))
+#define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i))
+#define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp))
+#define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st)
+#define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func))
+#define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st))
+
+#define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp))
+#define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD)
+#define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i))
+#define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i))
+#define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr))
+#define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i))
+#define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp))
+#define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st)
+#define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func))
+#define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st))
+
+#define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp))
+#define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD)
+#define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i))
+#define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val))
+#define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i))
+#define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr))
+#define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i))
+#define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp))
+#define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st)
+#define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func))
+#define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st))
+
+#define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp))
+#define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
+#define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i))
+#define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val))
+#define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i))
+#define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr))
+#define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i))
+#define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp))
+#define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st)
+#define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func))
+#define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
+
+#define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp))
+#define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES)
+#define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i))
+#define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val))
+#define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val))
+#define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val))
+#define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val))
+#define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val))
+#define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i))
+#define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr))
+#define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i))
+#define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp))
+#define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st)
+#define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func))
+#define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st))
+
+#define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp))
+#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
+#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i))
+#define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val))
+#define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i))
+#define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr))
+#define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i))
+#define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp))
+#define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st)
+#define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func))
+#define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
+
+#define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp))
+#define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
+#define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
+#define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
+#define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i))
+#define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val))
+#define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st))
+#define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val))
+#define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i))
+#define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr))
+#define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i))
+#define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp))
+#define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st)
+#define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func))
+#define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st))
+#define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st))
+#define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
+#define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
+
+#define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp))
+#define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
+#define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i))
+#define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val))
+#define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val))
+#define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i))
+#define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr))
+#define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i))
+#define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp))
+#define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st)
+#define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func))
+#define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
+
+#define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp))
+#define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
+#define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i))
+#define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val))
+#define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i))
+#define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr))
+#define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i))
+#define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp))
+#define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st)
+#define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func))
+#define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st))
+
+#define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp))
+#define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA)
+#define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i))
+#define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val))
+#define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i))
+#define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr))
+#define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i))
+#define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp))
+#define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st)
+#define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func))
+#define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st))
+
+#define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp))
+#define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY)
+#define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i))
+#define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val))
+#define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i))
+#define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr))
+#define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i))
+#define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp))
+#define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st)
+#define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func))
+#define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st))
+
+#define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp))
+#define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM)
+#define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i))
+#define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val))
+#define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i))
+#define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr))
+#define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i))
+#define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp))
+#define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st)
+#define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func))
+#define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st))
+
+#define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp))
+#define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA)
+#define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i))
+#define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val))
+#define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i))
+#define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr))
+#define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i))
+#define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp))
+#define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st)
+#define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func))
+#define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st))
+
+#define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp))
+#define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY)
+#define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i))
+#define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val))
+#define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i))
+#define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr))
+#define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i))
+#define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp))
+#define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st)
+#define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func))
+#define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st))
+
+#define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp))
+#define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME)
+#define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i))
+#define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val))
+#define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i))
+#define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr))
+#define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i))
+#define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp))
+#define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st)
+#define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func))
+#define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st))
+
+#define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp))
+#define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY)
+#define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i))
+#define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val))
+#define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i))
+#define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr))
+#define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i))
+#define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp))
+#define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st)
+#define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func))
+#define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st))
+
+#define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp))
+#define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA)
+#define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i))
+#define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val))
+#define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i))
+#define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr))
+#define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i))
+#define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp))
+#define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st)
+#define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func))
+#define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st))
+
+#define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp))
+#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
+#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
+#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
+#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i))
+#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val))
+#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st))
+#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i))
+#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr))
+#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i))
+#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp))
+#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st)
+#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func))
+#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st))
+#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st))
+#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
+#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
+
+#define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp))
+#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
+#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
+#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
+#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i))
+#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val))
+#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st))
+#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i))
+#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr))
+#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i))
+#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp))
+#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st)
+#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func))
+#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st))
+#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st))
+#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
+#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
+
+#define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp))
+#define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS)
+#define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i))
+#define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val))
+#define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i))
+#define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr))
+#define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i))
+#define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp))
+#define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st)
+#define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func))
+#define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st))
+
+#define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp))
+#define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
+#define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i))
+#define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val))
+#define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i))
+#define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr))
+#define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i))
+#define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp))
+#define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st)
+#define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func))
+#define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st))
+
+#define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp))
+#define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
+#define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i))
+#define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val))
+#define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i))
+#define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr))
+#define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i))
+#define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp))
+#define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st)
+#define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func))
+#define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
+
+#define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp))
+#define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID)
+#define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i))
+#define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val))
+#define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val))
+#define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val))
+#define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val))
+#define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val))
+#define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i))
+#define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr))
+#define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i))
+#define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp))
+#define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st)
+#define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func))
+#define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st))
+
+#define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp))
+#define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
+#define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i))
+#define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val))
+#define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i))
+#define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr))
+#define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i))
+#define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp))
+#define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st)
+#define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func))
+#define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st))
+
+#define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp))
+#define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG)
+#define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i))
+#define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val))
+#define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i))
+#define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr))
+#define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i))
+#define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp))
+#define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st)
+#define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func))
+#define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st))
+
+#define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp))
+#define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7)
+#define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st))
+#define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st))
+#define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i))
+#define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val))
+#define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st))
+#define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val))
+#define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val))
+#define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val))
+#define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val))
+#define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i))
+#define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr))
+#define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i))
+#define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp))
+#define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st)
+#define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func))
+#define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st))
+#define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st))
+#define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st))
+#define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st))
+
+#define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp))
+#define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO)
+#define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i))
+#define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val))
+#define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i))
+#define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr))
+#define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i))
+#define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp))
+#define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st)
+#define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func))
+#define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st))
+
+#define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp))
+#define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO)
+#define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i))
+#define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val))
+#define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i))
+#define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr))
+#define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i))
+#define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp))
+#define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st)
+#define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func))
+#define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st))
+
+#define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp))
+#define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO)
+#define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st))
+#define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st))
+#define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i))
+#define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val))
+#define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st))
+#define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i))
+#define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr))
+#define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i))
+#define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp))
+#define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st)
+#define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func))
+#define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st))
+#define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st))
+#define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st))
+#define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st))
+
+#define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp))
+#define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO)
+#define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i))
+#define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val))
+#define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i))
+#define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr))
+#define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i))
+#define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp))
+#define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st)
+#define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func))
+#define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st))
+
+#define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp))
+#define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING)
+#define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i))
+#define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val))
+#define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i))
+#define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr))
+#define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i))
+#define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp))
+#define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st)
+#define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func))
+#define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
+
+#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
+#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
+#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i))
+#define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val))
+#define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i))
+#define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr))
+#define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i))
+#define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp))
+#define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st)
+#define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func))
+#define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st))
+
+#define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp))
+#define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP)
+#define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st))
+#define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st))
+#define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i))
+#define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val))
+#define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st))
+#define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i))
+#define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr))
+#define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i))
+#define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp))
+#define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st)
+#define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func))
+#define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st))
+#define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st))
+#define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st))
+#define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st))
+
+#define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp))
+#define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY)
+#define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i))
+#define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i))
+#define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr))
+#define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i))
+#define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp))
+#define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st)
+#define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func))
+#define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st))
+
+#define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp))
+#define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO)
+#define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i))
+#define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val))
+#define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i))
+#define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr))
+#define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i))
+#define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp))
+#define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st)
+#define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func))
+#define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st))
+
+#define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp))
+#define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT)
+#define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i))
+#define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val))
+#define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i))
+#define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr))
+#define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i))
+#define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp))
+#define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st)
+#define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func))
+#define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st))
+
+#define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp))
+#define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID)
+#define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st))
+#define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st))
+#define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i))
+#define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val))
+#define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st))
+#define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val))
+#define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val))
+#define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val))
+#define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val))
+#define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i))
+#define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr))
+#define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i))
+#define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp))
+#define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st)
+#define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func))
+#define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st))
+#define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st))
+#define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st))
+#define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st))
+
+#define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp))
+#define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING)
+#define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st))
+#define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st))
+#define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i))
+#define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val))
+#define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st))
+#define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val))
+#define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val))
+#define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val))
+#define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val))
+#define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i))
+#define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr))
+#define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i))
+#define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp))
+#define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st)
+#define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func))
+#define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st))
+#define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st))
+#define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st))
+#define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st))
+
+#define sk_X509_new(cmp) SKM_sk_new(X509, (cmp))
+#define sk_X509_new_null() SKM_sk_new_null(X509)
+#define sk_X509_free(st) SKM_sk_free(X509, (st))
+#define sk_X509_num(st) SKM_sk_num(X509, (st))
+#define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i))
+#define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val))
+#define sk_X509_zero(st) SKM_sk_zero(X509, (st))
+#define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val))
+#define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val))
+#define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val))
+#define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val))
+#define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i))
+#define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr))
+#define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i))
+#define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp))
+#define sk_X509_dup(st) SKM_sk_dup(X509, st)
+#define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func))
+#define sk_X509_shift(st) SKM_sk_shift(X509, (st))
+#define sk_X509_pop(st) SKM_sk_pop(X509, (st))
+#define sk_X509_sort(st) SKM_sk_sort(X509, (st))
+#define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st))
+
+#define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp))
+#define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD)
+#define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i))
+#define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val))
+#define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i))
+#define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr))
+#define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i))
+#define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp))
+#define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st)
+#define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func))
+#define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st))
+
+#define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp))
+#define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR)
+#define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st))
+#define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st))
+#define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i))
+#define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val))
+#define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st))
+#define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i))
+#define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr))
+#define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i))
+#define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp))
+#define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st)
+#define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func))
+#define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st))
+#define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st))
+#define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st))
+#define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st))
+
+#define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp))
+#define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE)
+#define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i))
+#define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val))
+#define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i))
+#define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr))
+#define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i))
+#define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp))
+#define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st)
+#define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func))
+#define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st))
+
+#define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp))
+#define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL)
+#define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st))
+#define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st))
+#define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i))
+#define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val))
+#define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st))
+#define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val))
+#define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val))
+#define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val))
+#define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val))
+#define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i))
+#define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr))
+#define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i))
+#define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp))
+#define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st)
+#define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func))
+#define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st))
+#define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st))
+#define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st))
+#define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st))
+
+#define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp))
+#define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION)
+#define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i))
+#define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val))
+#define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i))
+#define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr))
+#define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i))
+#define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp))
+#define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st)
+#define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func))
+#define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st))
+
+#define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp))
+#define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO)
+#define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st))
+#define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st))
+#define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i))
+#define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val))
+#define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st))
+#define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val))
+#define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val))
+#define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val))
+#define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val))
+#define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i))
+#define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr))
+#define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i))
+#define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp))
+#define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st)
+#define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func))
+#define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st))
+#define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st))
+#define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st))
+#define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st))
+
+#define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp))
+#define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP)
+#define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i))
+#define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val))
+#define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i))
+#define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr))
+#define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i))
+#define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp))
+#define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st)
+#define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func))
+#define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st))
+
+#define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp))
+#define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME)
+#define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st))
+#define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st))
+#define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i))
+#define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val))
+#define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st))
+#define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val))
+#define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val))
+#define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val))
+#define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val))
+#define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i))
+#define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr))
+#define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i))
+#define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp))
+#define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st)
+#define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func))
+#define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st))
+#define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st))
+#define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st))
+#define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st))
+
+#define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp))
+#define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY)
+#define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i))
+#define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val))
+#define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i))
+#define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr))
+#define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i))
+#define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp))
+#define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st)
+#define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func))
+#define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st))
+
+#define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp))
+#define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT)
+#define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st))
+#define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st))
+#define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i))
+#define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val))
+#define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st))
+#define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i))
+#define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr))
+#define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i))
+#define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp))
+#define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st)
+#define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func))
+#define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st))
+#define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st))
+#define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st))
+#define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st))
+
+#define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp))
+#define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA)
+#define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i))
+#define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val))
+#define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i))
+#define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr))
+#define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i))
+#define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp))
+#define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st)
+#define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func))
+#define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st))
+
+#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp))
+#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
+#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i))
+#define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val))
+#define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i))
+#define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr))
+#define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i))
+#define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp))
+#define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st)
+#define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func))
+#define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
+
+#define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp))
+#define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE)
+#define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i))
+#define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val))
+#define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i))
+#define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr))
+#define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i))
+#define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp))
+#define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st)
+#define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func))
+#define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st))
+
+#define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp))
+#define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED)
+#define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st))
+#define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st))
+#define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i))
+#define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val))
+#define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st))
+#define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i))
+#define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr))
+#define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i))
+#define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp))
+#define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st)
+#define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func))
+#define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st))
+#define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st))
+#define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st))
+#define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st))
+
+#define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp))
+#define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST)
+#define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st))
+#define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st))
+#define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i))
+#define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val))
+#define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st))
+#define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i))
+#define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr))
+#define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i))
+#define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp))
+#define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st)
+#define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func))
+#define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st))
+#define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st))
+#define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st))
+#define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st))
+
+#define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp))
+#define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM)
+#define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i))
+#define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val))
+#define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i))
+#define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr))
+#define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i))
+#define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp))
+#define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st)
+#define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func))
+#define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
+
+#define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp))
+#define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple)
+#define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st))
+#define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st))
+#define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i))
+#define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val))
+#define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st))
+#define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val))
+#define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val))
+#define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val))
+#define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val))
+#define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i))
+#define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr))
+#define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i))
+#define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp))
+#define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st)
+#define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func))
+#define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st))
+#define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st))
+#define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st))
+#define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st))
+
+#define sk_void_new(cmp) SKM_sk_new(void, (cmp))
+#define sk_void_new_null() SKM_sk_new_null(void)
+#define sk_void_free(st) SKM_sk_free(void, (st))
+#define sk_void_num(st) SKM_sk_num(void, (st))
+#define sk_void_value(st, i) SKM_sk_value(void, (st), (i))
+#define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val))
+#define sk_void_zero(st) SKM_sk_zero(void, (st))
+#define sk_void_push(st, val) SKM_sk_push(void, (st), (val))
+#define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val))
+#define sk_void_find(st, val) SKM_sk_find(void, (st), (val))
+#define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val))
+#define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i))
+#define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr))
+#define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i))
+#define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp))
+#define sk_void_dup(st) SKM_sk_dup(void, st)
+#define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func))
+#define sk_void_shift(st) SKM_sk_shift(void, (st))
+#define sk_void_pop(st) SKM_sk_pop(void, (st))
+#define sk_void_sort(st) SKM_sk_sort(void, (st))
+#define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st))
+
+#define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp)))
+#define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null())
+#define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i))
+#define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st)
+#define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func))
+#define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i)
+#define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st)
+#define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st))
+#define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i))
+#define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr))
+#define sk_OPENSSL_STRING_set_cmp_func(st, cmp) \
+ ((int (*)(const char * const *,const char * const *)) \
+ sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp)))
+#define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st)
+#define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st))
+#define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st))
+#define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st))
+#define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st))
+
+
+#define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp)))
+#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null())
+#define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i))
+#define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st)
+#define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func))
+#define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i)
+#define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st)
+#define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i))
+#define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr))
+#define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp) \
+ ((int (*)(const void * const *,const void * const *)) \
+ sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp)))
+#define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st)
+#define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st))
+#define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st))
+
+
+#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null())
+#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i))
+#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func))
+#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i)
+#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i))
+#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr))
+#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \
+ ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \
+ sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st))
+#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st))
+
+
+#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func))
+
+#define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \
+ SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+
+#define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \
+ SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+
+#define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj)
+#define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst)
+#define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst)
+#define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst)
+#define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn)
+#define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg)
+#define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh)
+#define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh)
+#define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh)
+#define lh_ADDED_OBJ_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(ADDED_OBJ,lh,out)
+#define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out)
+#define lh_ADDED_OBJ_stats_bio(lh,out) \
+ LHM_lh_stats_bio(ADDED_OBJ,lh,out)
+#define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh)
+
+#define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info)
+#define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst)
+#define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst)
+#define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst)
+#define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn)
+#define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg)
+#define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh)
+#define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh)
+#define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh)
+#define lh_APP_INFO_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(APP_INFO,lh,out)
+#define lh_APP_INFO_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(APP_INFO,lh,out)
+#define lh_APP_INFO_stats_bio(lh,out) \
+ LHM_lh_stats_bio(APP_INFO,lh,out)
+#define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh)
+
+#define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value)
+#define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst)
+#define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst)
+#define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst)
+#define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn)
+#define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg)
+#define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh)
+#define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh)
+#define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh)
+#define lh_CONF_VALUE_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(CONF_VALUE,lh,out)
+#define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out)
+#define lh_CONF_VALUE_stats_bio(lh,out) \
+ LHM_lh_stats_bio(CONF_VALUE,lh,out)
+#define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh)
+
+#define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile)
+#define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst)
+#define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst)
+#define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst)
+#define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn)
+#define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg)
+#define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh)
+#define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh)
+#define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh)
+#define lh_ENGINE_PILE_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(ENGINE_PILE,lh,out)
+#define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out)
+#define lh_ENGINE_PILE_stats_bio(lh,out) \
+ LHM_lh_stats_bio(ENGINE_PILE,lh,out)
+#define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh)
+
+#define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state)
+#define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst)
+#define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst)
+#define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst)
+#define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn)
+#define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg)
+#define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh)
+#define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh)
+#define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh)
+#define lh_ERR_STATE_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(ERR_STATE,lh,out)
+#define lh_ERR_STATE_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out)
+#define lh_ERR_STATE_stats_bio(lh,out) \
+ LHM_lh_stats_bio(ERR_STATE,lh,out)
+#define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh)
+
+#define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data)
+#define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst)
+#define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst)
+#define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst)
+#define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn)
+#define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg)
+#define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh)
+#define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh)
+#define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh)
+#define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out)
+#define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out)
+#define lh_ERR_STRING_DATA_stats_bio(lh,out) \
+ LHM_lh_stats_bio(ERR_STRING_DATA,lh,out)
+#define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh)
+
+#define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item)
+#define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst)
+#define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst)
+#define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst)
+#define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn)
+#define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg)
+#define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh)
+#define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh)
+#define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh)
+#define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out)
+#define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out)
+#define lh_EX_CLASS_ITEM_stats_bio(lh,out) \
+ LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out)
+#define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh)
+
+#define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function)
+#define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst)
+#define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst)
+#define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst)
+#define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn)
+#define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg)
+#define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh)
+#define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh)
+#define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh)
+#define lh_FUNCTION_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(FUNCTION,lh,out)
+#define lh_FUNCTION_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(FUNCTION,lh,out)
+#define lh_FUNCTION_stats_bio(lh,out) \
+ LHM_lh_stats_bio(FUNCTION,lh,out)
+#define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh)
+
+#define lh_MEM_new() LHM_lh_new(MEM,mem)
+#define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst)
+#define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst)
+#define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst)
+#define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn)
+#define lh_MEM_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg)
+#define lh_MEM_error(lh) LHM_lh_error(MEM,lh)
+#define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh)
+#define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh)
+#define lh_MEM_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(MEM,lh,out)
+#define lh_MEM_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(MEM,lh,out)
+#define lh_MEM_stats_bio(lh,out) \
+ LHM_lh_stats_bio(MEM,lh,out)
+#define lh_MEM_free(lh) LHM_lh_free(MEM,lh)
+
+#define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name)
+#define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst)
+#define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst)
+#define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst)
+#define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn)
+#define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg)
+#define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh)
+#define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh)
+#define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh)
+#define lh_OBJ_NAME_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(OBJ_NAME,lh,out)
+#define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out)
+#define lh_OBJ_NAME_stats_bio(lh,out) \
+ LHM_lh_stats_bio(OBJ_NAME,lh,out)
+#define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh)
+
+#define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring)
+#define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst)
+#define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst)
+#define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst)
+#define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn)
+#define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg)
+#define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh)
+#define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh)
+#define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh)
+#define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out)
+#define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out)
+#define lh_OPENSSL_CSTRING_stats_bio(lh,out) \
+ LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out)
+#define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh)
+
+#define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string)
+#define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst)
+#define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst)
+#define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst)
+#define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn)
+#define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg)
+#define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh)
+#define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh)
+#define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh)
+#define lh_OPENSSL_STRING_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out)
+#define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out)
+#define lh_OPENSSL_STRING_stats_bio(lh,out) \
+ LHM_lh_stats_bio(OPENSSL_STRING,lh,out)
+#define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh)
+
+#define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session)
+#define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst)
+#define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst)
+#define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst)
+#define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn)
+#define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg)
+#define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh)
+#define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh)
+#define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh)
+#define lh_SSL_SESSION_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(SSL_SESSION,lh,out)
+#define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out)
+#define lh_SSL_SESSION_stats_bio(lh,out) \
+ LHM_lh_stats_bio(SSL_SESSION,lh,out)
+#define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh)
+/* End of util/mkstack.pl block, you may now edit :-) */
+
+#endif /* !defined HEADER_SAFESTACK_H */
diff --git a/openssl/crypto/ts/ts_verify_ctx.c b/openssl/crypto/ts/ts_verify_ctx.c
index b008687a2..609b7735d 100644
--- a/openssl/crypto/ts/ts_verify_ctx.c
+++ b/openssl/crypto/ts/ts_verify_ctx.c
@@ -1,159 +1,159 @@
-/* crypto/ts/ts_verify_ctx.c */
-/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
- * project 2003.
- */
-/* ====================================================================
- * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include "cryptlib.h"
-#include <openssl/objects.h>
-#include <openssl/ts.h>
-
-TS_VERIFY_CTX *TS_VERIFY_CTX_new(void)
- {
- TS_VERIFY_CTX *ctx =
- (TS_VERIFY_CTX *) OPENSSL_malloc(sizeof(TS_VERIFY_CTX));
- if (ctx)
- memset(ctx, 0, sizeof(TS_VERIFY_CTX));
- else
- TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE);
- return ctx;
- }
-
-void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx)
- {
- OPENSSL_assert(ctx != NULL);
- memset(ctx, 0, sizeof(TS_VERIFY_CTX));
- }
-
-void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx)
- {
- if (!ctx) return;
-
- TS_VERIFY_CTX_cleanup(ctx);
- OPENSSL_free(ctx);
- }
-
-void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx)
- {
- if (!ctx) return;
-
- X509_STORE_free(ctx->store);
- sk_X509_pop_free(ctx->certs, X509_free);
-
- ASN1_OBJECT_free(ctx->policy);
-
- X509_ALGOR_free(ctx->md_alg);
- OPENSSL_free(ctx->imprint);
-
- BIO_free_all(ctx->data);
-
- ASN1_INTEGER_free(ctx->nonce);
-
- GENERAL_NAME_free(ctx->tsa_name);
-
- TS_VERIFY_CTX_init(ctx);
- }
-
-TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx)
- {
- TS_VERIFY_CTX *ret = ctx;
- ASN1_OBJECT *policy;
- TS_MSG_IMPRINT *imprint;
- X509_ALGOR *md_alg;
- ASN1_OCTET_STRING *msg;
- const ASN1_INTEGER *nonce;
-
- OPENSSL_assert(req != NULL);
- if (ret)
- TS_VERIFY_CTX_cleanup(ret);
- else
- if (!(ret = TS_VERIFY_CTX_new())) return NULL;
-
- /* Setting flags. */
- ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE);
-
- /* Setting policy. */
- if ((policy = TS_REQ_get_policy_id(req)) != NULL)
- {
- if (!(ret->policy = OBJ_dup(policy))) goto err;
- }
- else
- ret->flags &= ~TS_VFY_POLICY;
-
- /* Setting md_alg, imprint and imprint_len. */
- imprint = TS_REQ_get_msg_imprint(req);
- md_alg = TS_MSG_IMPRINT_get_algo(imprint);
- if (!(ret->md_alg = X509_ALGOR_dup(md_alg))) goto err;
- msg = TS_MSG_IMPRINT_get_msg(imprint);
- ret->imprint_len = ASN1_STRING_length(msg);
- if (!(ret->imprint = OPENSSL_malloc(ret->imprint_len))) goto err;
- memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len);
-
- /* Setting nonce. */
- if ((nonce = TS_REQ_get_nonce(req)) != NULL)
- {
- if (!(ret->nonce = ASN1_INTEGER_dup(nonce))) goto err;
- }
- else
- ret->flags &= ~TS_VFY_NONCE;
-
- return ret;
- err:
- if (ctx)
- TS_VERIFY_CTX_cleanup(ctx);
- else
- TS_VERIFY_CTX_free(ret);
- return NULL;
- }
+/* crypto/ts/ts_verify_ctx.c */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/ts.h>
+
+TS_VERIFY_CTX *TS_VERIFY_CTX_new(void)
+ {
+ TS_VERIFY_CTX *ctx =
+ (TS_VERIFY_CTX *) OPENSSL_malloc(sizeof(TS_VERIFY_CTX));
+ if (ctx)
+ memset(ctx, 0, sizeof(TS_VERIFY_CTX));
+ else
+ TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ return ctx;
+ }
+
+void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx)
+ {
+ OPENSSL_assert(ctx != NULL);
+ memset(ctx, 0, sizeof(TS_VERIFY_CTX));
+ }
+
+void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx)
+ {
+ if (!ctx) return;
+
+ TS_VERIFY_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+ }
+
+void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx)
+ {
+ if (!ctx) return;
+
+ X509_STORE_free(ctx->store);
+ sk_X509_pop_free(ctx->certs, X509_free);
+
+ ASN1_OBJECT_free(ctx->policy);
+
+ X509_ALGOR_free(ctx->md_alg);
+ OPENSSL_free(ctx->imprint);
+
+ BIO_free_all(ctx->data);
+
+ ASN1_INTEGER_free(ctx->nonce);
+
+ GENERAL_NAME_free(ctx->tsa_name);
+
+ TS_VERIFY_CTX_init(ctx);
+ }
+
+TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx)
+ {
+ TS_VERIFY_CTX *ret = ctx;
+ ASN1_OBJECT *policy;
+ TS_MSG_IMPRINT *imprint;
+ X509_ALGOR *md_alg;
+ ASN1_OCTET_STRING *msg;
+ const ASN1_INTEGER *nonce;
+
+ OPENSSL_assert(req != NULL);
+ if (ret)
+ TS_VERIFY_CTX_cleanup(ret);
+ else
+ if (!(ret = TS_VERIFY_CTX_new())) return NULL;
+
+ /* Setting flags. */
+ ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE);
+
+ /* Setting policy. */
+ if ((policy = TS_REQ_get_policy_id(req)) != NULL)
+ {
+ if (!(ret->policy = OBJ_dup(policy))) goto err;
+ }
+ else
+ ret->flags &= ~TS_VFY_POLICY;
+
+ /* Setting md_alg, imprint and imprint_len. */
+ imprint = TS_REQ_get_msg_imprint(req);
+ md_alg = TS_MSG_IMPRINT_get_algo(imprint);
+ if (!(ret->md_alg = X509_ALGOR_dup(md_alg))) goto err;
+ msg = TS_MSG_IMPRINT_get_msg(imprint);
+ ret->imprint_len = ASN1_STRING_length(msg);
+ if (!(ret->imprint = OPENSSL_malloc(ret->imprint_len))) goto err;
+ memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len);
+
+ /* Setting nonce. */
+ if ((nonce = TS_REQ_get_nonce(req)) != NULL)
+ {
+ if (!(ret->nonce = ASN1_INTEGER_dup(nonce))) goto err;
+ }
+ else
+ ret->flags &= ~TS_VFY_NONCE;
+
+ return ret;
+ err:
+ if (ctx)
+ TS_VERIFY_CTX_cleanup(ctx);
+ else
+ TS_VERIFY_CTX_free(ret);
+ return NULL;
+ }
diff --git a/openssl/crypto/x509v3/v3_addr.c b/openssl/crypto/x509v3/v3_addr.c
index 247d671a8..0d70e8696 100644
--- a/openssl/crypto/x509v3/v3_addr.c
+++ b/openssl/crypto/x509v3/v3_addr.c
@@ -1,1293 +1,1293 @@
-/*
- * Contributed to the OpenSSL Project by the American Registry for
- * Internet Numbers ("ARIN").
- */
-/* ====================================================================
- * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- */
-
-/*
- * Implementation of RFC 3779 section 2.2.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "cryptlib.h"
-#include <openssl/conf.h>
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
-#include <openssl/buffer.h>
-#include <openssl/x509v3.h>
-
-#ifndef OPENSSL_NO_RFC3779
-
-/*
- * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
- */
-
-ASN1_SEQUENCE(IPAddressRange) = {
- ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),
- ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)
-} ASN1_SEQUENCE_END(IPAddressRange)
-
-ASN1_CHOICE(IPAddressOrRange) = {
- ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),
- ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange)
-} ASN1_CHOICE_END(IPAddressOrRange)
-
-ASN1_CHOICE(IPAddressChoice) = {
- ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL),
- ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)
-} ASN1_CHOICE_END(IPAddressChoice)
-
-ASN1_SEQUENCE(IPAddressFamily) = {
- ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING),
- ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)
-} ASN1_SEQUENCE_END(IPAddressFamily)
-
-ASN1_ITEM_TEMPLATE(IPAddrBlocks) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
- IPAddrBlocks, IPAddressFamily)
-ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)
-
-IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)
-IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)
-IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)
-IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)
-
-/*
- * How much buffer space do we need for a raw address?
- */
-#define ADDR_RAW_BUF_LEN 16
-
-/*
- * What's the address length associated with this AFI?
- */
-static int length_from_afi(const unsigned afi)
-{
- switch (afi) {
- case IANA_AFI_IPV4:
- return 4;
- case IANA_AFI_IPV6:
- return 16;
- default:
- return 0;
- }
-}
-
-/*
- * Extract the AFI from an IPAddressFamily.
- */
-unsigned int v3_addr_get_afi(const IPAddressFamily *f)
-{
- return ((f != NULL &&
- f->addressFamily != NULL &&
- f->addressFamily->data != NULL)
- ? ((f->addressFamily->data[0] << 8) |
- (f->addressFamily->data[1]))
- : 0);
-}
-
-/*
- * Expand the bitstring form of an address into a raw byte array.
- * At the moment this is coded for simplicity, not speed.
- */
-static void addr_expand(unsigned char *addr,
- const ASN1_BIT_STRING *bs,
- const int length,
- const unsigned char fill)
-{
- OPENSSL_assert(bs->length >= 0 && bs->length <= length);
- if (bs->length > 0) {
- memcpy(addr, bs->data, bs->length);
- if ((bs->flags & 7) != 0) {
- unsigned char mask = 0xFF >> (8 - (bs->flags & 7));
- if (fill == 0)
- addr[bs->length - 1] &= ~mask;
- else
- addr[bs->length - 1] |= mask;
- }
- }
- memset(addr + bs->length, fill, length - bs->length);
-}
-
-/*
- * Extract the prefix length from a bitstring.
- */
-#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))
-
-/*
- * i2r handler for one address bitstring.
- */
-static int i2r_address(BIO *out,
- const unsigned afi,
- const unsigned char fill,
- const ASN1_BIT_STRING *bs)
-{
- unsigned char addr[ADDR_RAW_BUF_LEN];
- int i, n;
-
- if (bs->length < 0)
- return 0;
- switch (afi) {
- case IANA_AFI_IPV4:
- if (bs->length > 4)
- return 0;
- addr_expand(addr, bs, 4, fill);
- BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
- break;
- case IANA_AFI_IPV6:
- if (bs->length > 16)
- return 0;
- addr_expand(addr, bs, 16, fill);
- for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
- ;
- for (i = 0; i < n; i += 2)
- BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i+1], (i < 14 ? ":" : ""));
- if (i < 16)
- BIO_puts(out, ":");
- if (i == 0)
- BIO_puts(out, ":");
- break;
- default:
- for (i = 0; i < bs->length; i++)
- BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);
- BIO_printf(out, "[%d]", (int) (bs->flags & 7));
- break;
- }
- return 1;
-}
-
-/*
- * i2r handler for a sequence of addresses and ranges.
- */
-static int i2r_IPAddressOrRanges(BIO *out,
- const int indent,
- const IPAddressOrRanges *aors,
- const unsigned afi)
-{
- int i;
- for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
- const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);
- BIO_printf(out, "%*s", indent, "");
- switch (aor->type) {
- case IPAddressOrRange_addressPrefix:
- if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))
- return 0;
- BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));
- continue;
- case IPAddressOrRange_addressRange:
- if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))
- return 0;
- BIO_puts(out, "-");
- if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))
- return 0;
- BIO_puts(out, "\n");
- continue;
- }
- }
- return 1;
-}
-
-/*
- * i2r handler for an IPAddrBlocks extension.
- */
-static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method,
- void *ext,
- BIO *out,
- int indent)
-{
- const IPAddrBlocks *addr = ext;
- int i;
- for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
- IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
- const unsigned int afi = v3_addr_get_afi(f);
- switch (afi) {
- case IANA_AFI_IPV4:
- BIO_printf(out, "%*sIPv4", indent, "");
- break;
- case IANA_AFI_IPV6:
- BIO_printf(out, "%*sIPv6", indent, "");
- break;
- default:
- BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
- break;
- }
- if (f->addressFamily->length > 2) {
- switch (f->addressFamily->data[2]) {
- case 1:
- BIO_puts(out, " (Unicast)");
- break;
- case 2:
- BIO_puts(out, " (Multicast)");
- break;
- case 3:
- BIO_puts(out, " (Unicast/Multicast)");
- break;
- case 4:
- BIO_puts(out, " (MPLS)");
- break;
- case 64:
- BIO_puts(out, " (Tunnel)");
- break;
- case 65:
- BIO_puts(out, " (VPLS)");
- break;
- case 66:
- BIO_puts(out, " (BGP MDT)");
- break;
- case 128:
- BIO_puts(out, " (MPLS-labeled VPN)");
- break;
- default:
- BIO_printf(out, " (Unknown SAFI %u)",
- (unsigned) f->addressFamily->data[2]);
- break;
- }
- }
- switch (f->ipAddressChoice->type) {
- case IPAddressChoice_inherit:
- BIO_puts(out, ": inherit\n");
- break;
- case IPAddressChoice_addressesOrRanges:
- BIO_puts(out, ":\n");
- if (!i2r_IPAddressOrRanges(out,
- indent + 2,
- f->ipAddressChoice->u.addressesOrRanges,
- afi))
- return 0;
- break;
- }
- }
- return 1;
-}
-
-/*
- * Sort comparison function for a sequence of IPAddressOrRange
- * elements.
- */
-static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
- const IPAddressOrRange *b,
- const int length)
-{
- unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
- int prefixlen_a = 0, prefixlen_b = 0;
- int r;
-
- switch (a->type) {
- case IPAddressOrRange_addressPrefix:
- addr_expand(addr_a, a->u.addressPrefix, length, 0x00);
- prefixlen_a = addr_prefixlen(a->u.addressPrefix);
- break;
- case IPAddressOrRange_addressRange:
- addr_expand(addr_a, a->u.addressRange->min, length, 0x00);
- prefixlen_a = length * 8;
- break;
- }
-
- switch (b->type) {
- case IPAddressOrRange_addressPrefix:
- addr_expand(addr_b, b->u.addressPrefix, length, 0x00);
- prefixlen_b = addr_prefixlen(b->u.addressPrefix);
- break;
- case IPAddressOrRange_addressRange:
- addr_expand(addr_b, b->u.addressRange->min, length, 0x00);
- prefixlen_b = length * 8;
- break;
- }
-
- if ((r = memcmp(addr_a, addr_b, length)) != 0)
- return r;
- else
- return prefixlen_a - prefixlen_b;
-}
-
-/*
- * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
- * comparision routines are only allowed two arguments.
- */
-static int v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
- const IPAddressOrRange * const *b)
-{
- return IPAddressOrRange_cmp(*a, *b, 4);
-}
-
-/*
- * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
- * comparision routines are only allowed two arguments.
- */
-static int v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
- const IPAddressOrRange * const *b)
-{
- return IPAddressOrRange_cmp(*a, *b, 16);
-}
-
-/*
- * Calculate whether a range collapses to a prefix.
- * See last paragraph of RFC 3779 2.2.3.7.
- */
-static int range_should_be_prefix(const unsigned char *min,
- const unsigned char *max,
- const int length)
-{
- unsigned char mask;
- int i, j;
-
- for (i = 0; i < length && min[i] == max[i]; i++)
- ;
- for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--)
- ;
- if (i < j)
- return -1;
- if (i > j)
- return i * 8;
- mask = min[i] ^ max[i];
- switch (mask) {
- case 0x01: j = 7; break;
- case 0x03: j = 6; break;
- case 0x07: j = 5; break;
- case 0x0F: j = 4; break;
- case 0x1F: j = 3; break;
- case 0x3F: j = 2; break;
- case 0x7F: j = 1; break;
- default: return -1;
- }
- if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
- return -1;
- else
- return i * 8 + j;
-}
-
-/*
- * Construct a prefix.
- */
-static int make_addressPrefix(IPAddressOrRange **result,
- unsigned char *addr,
- const int prefixlen)
-{
- int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
- IPAddressOrRange *aor = IPAddressOrRange_new();
-
- if (aor == NULL)
- return 0;
- aor->type = IPAddressOrRange_addressPrefix;
- if (aor->u.addressPrefix == NULL &&
- (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
- goto err;
- if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
- goto err;
- aor->u.addressPrefix->flags &= ~7;
- aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
- if (bitlen > 0) {
- aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);
- aor->u.addressPrefix->flags |= 8 - bitlen;
- }
-
- *result = aor;
- return 1;
-
- err:
- IPAddressOrRange_free(aor);
- return 0;
-}
-
-/*
- * Construct a range. If it can be expressed as a prefix,
- * return a prefix instead. Doing this here simplifies
- * the rest of the code considerably.
- */
-static int make_addressRange(IPAddressOrRange **result,
- unsigned char *min,
- unsigned char *max,
- const int length)
-{
- IPAddressOrRange *aor;
- int i, prefixlen;
-
- if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
- return make_addressPrefix(result, min, prefixlen);
-
- if ((aor = IPAddressOrRange_new()) == NULL)
- return 0;
- aor->type = IPAddressOrRange_addressRange;
- OPENSSL_assert(aor->u.addressRange == NULL);
- if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
- goto err;
- if (aor->u.addressRange->min == NULL &&
- (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)
- goto err;
- if (aor->u.addressRange->max == NULL &&
- (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)
- goto err;
-
- for (i = length; i > 0 && min[i - 1] == 0x00; --i)
- ;
- if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))
- goto err;
- aor->u.addressRange->min->flags &= ~7;
- aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;
- if (i > 0) {
- unsigned char b = min[i - 1];
- int j = 1;
- while ((b & (0xFFU >> j)) != 0)
- ++j;
- aor->u.addressRange->min->flags |= 8 - j;
- }
-
- for (i = length; i > 0 && max[i - 1] == 0xFF; --i)
- ;
- if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))
- goto err;
- aor->u.addressRange->max->flags &= ~7;
- aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;
- if (i > 0) {
- unsigned char b = max[i - 1];
- int j = 1;
- while ((b & (0xFFU >> j)) != (0xFFU >> j))
- ++j;
- aor->u.addressRange->max->flags |= 8 - j;
- }
-
- *result = aor;
- return 1;
-
- err:
- IPAddressOrRange_free(aor);
- return 0;
-}
-
-/*
- * Construct a new address family or find an existing one.
- */
-static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
- const unsigned afi,
- const unsigned *safi)
-{
- IPAddressFamily *f;
- unsigned char key[3];
- unsigned keylen;
- int i;
-
- key[0] = (afi >> 8) & 0xFF;
- key[1] = afi & 0xFF;
- if (safi != NULL) {
- key[2] = *safi & 0xFF;
- keylen = 3;
- } else {
- keylen = 2;
- }
-
- for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
- f = sk_IPAddressFamily_value(addr, i);
- OPENSSL_assert(f->addressFamily->data != NULL);
- if (f->addressFamily->length == keylen &&
- !memcmp(f->addressFamily->data, key, keylen))
- return f;
- }
-
- if ((f = IPAddressFamily_new()) == NULL)
- goto err;
- if (f->ipAddressChoice == NULL &&
- (f->ipAddressChoice = IPAddressChoice_new()) == NULL)
- goto err;
- if (f->addressFamily == NULL &&
- (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)
- goto err;
- if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))
- goto err;
- if (!sk_IPAddressFamily_push(addr, f))
- goto err;
-
- return f;
-
- err:
- IPAddressFamily_free(f);
- return NULL;
-}
-
-/*
- * Add an inheritance element.
- */
-int v3_addr_add_inherit(IPAddrBlocks *addr,
- const unsigned afi,
- const unsigned *safi)
-{
- IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
- if (f == NULL ||
- f->ipAddressChoice == NULL ||
- (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
- f->ipAddressChoice->u.addressesOrRanges != NULL))
- return 0;
- if (f->ipAddressChoice->type == IPAddressChoice_inherit &&
- f->ipAddressChoice->u.inherit != NULL)
- return 1;
- if (f->ipAddressChoice->u.inherit == NULL &&
- (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
- return 0;
- f->ipAddressChoice->type = IPAddressChoice_inherit;
- return 1;
-}
-
-/*
- * Construct an IPAddressOrRange sequence, or return an existing one.
- */
-static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
- const unsigned afi,
- const unsigned *safi)
-{
- IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
- IPAddressOrRanges *aors = NULL;
-
- if (f == NULL ||
- f->ipAddressChoice == NULL ||
- (f->ipAddressChoice->type == IPAddressChoice_inherit &&
- f->ipAddressChoice->u.inherit != NULL))
- return NULL;
- if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)
- aors = f->ipAddressChoice->u.addressesOrRanges;
- if (aors != NULL)
- return aors;
- if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
- return NULL;
- switch (afi) {
- case IANA_AFI_IPV4:
- sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
- break;
- case IANA_AFI_IPV6:
- sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
- break;
- }
- f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
- f->ipAddressChoice->u.addressesOrRanges = aors;
- return aors;
-}
-
-/*
- * Add a prefix.
- */
-int v3_addr_add_prefix(IPAddrBlocks *addr,
- const unsigned afi,
- const unsigned *safi,
- unsigned char *a,
- const int prefixlen)
-{
- IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
- IPAddressOrRange *aor;
- if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
- return 0;
- if (sk_IPAddressOrRange_push(aors, aor))
- return 1;
- IPAddressOrRange_free(aor);
- return 0;
-}
-
-/*
- * Add a range.
- */
-int v3_addr_add_range(IPAddrBlocks *addr,
- const unsigned afi,
- const unsigned *safi,
- unsigned char *min,
- unsigned char *max)
-{
- IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
- IPAddressOrRange *aor;
- int length = length_from_afi(afi);
- if (aors == NULL)
- return 0;
- if (!make_addressRange(&aor, min, max, length))
- return 0;
- if (sk_IPAddressOrRange_push(aors, aor))
- return 1;
- IPAddressOrRange_free(aor);
- return 0;
-}
-
-/*
- * Extract min and max values from an IPAddressOrRange.
- */
-static void extract_min_max(IPAddressOrRange *aor,
- unsigned char *min,
- unsigned char *max,
- int length)
-{
- OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
- switch (aor->type) {
- case IPAddressOrRange_addressPrefix:
- addr_expand(min, aor->u.addressPrefix, length, 0x00);
- addr_expand(max, aor->u.addressPrefix, length, 0xFF);
- return;
- case IPAddressOrRange_addressRange:
- addr_expand(min, aor->u.addressRange->min, length, 0x00);
- addr_expand(max, aor->u.addressRange->max, length, 0xFF);
- return;
- }
-}
-
-/*
- * Public wrapper for extract_min_max().
- */
-int v3_addr_get_range(IPAddressOrRange *aor,
- const unsigned afi,
- unsigned char *min,
- unsigned char *max,
- const int length)
-{
- int afi_length = length_from_afi(afi);
- if (aor == NULL || min == NULL || max == NULL ||
- afi_length == 0 || length < afi_length ||
- (aor->type != IPAddressOrRange_addressPrefix &&
- aor->type != IPAddressOrRange_addressRange))
- return 0;
- extract_min_max(aor, min, max, afi_length);
- return afi_length;
-}
-
-/*
- * Sort comparision function for a sequence of IPAddressFamily.
- *
- * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
- * the ordering: I can read it as meaning that IPv6 without a SAFI
- * comes before IPv4 with a SAFI, which seems pretty weird. The
- * examples in appendix B suggest that the author intended the
- * null-SAFI rule to apply only within a single AFI, which is what I
- * would have expected and is what the following code implements.
- */
-static int IPAddressFamily_cmp(const IPAddressFamily * const *a_,
- const IPAddressFamily * const *b_)
-{
- const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
- const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
- int len = ((a->length <= b->length) ? a->length : b->length);
- int cmp = memcmp(a->data, b->data, len);
- return cmp ? cmp : a->length - b->length;
-}
-
-/*
- * Check whether an IPAddrBLocks is in canonical form.
- */
-int v3_addr_is_canonical(IPAddrBlocks *addr)
-{
- unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
- unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
- IPAddressOrRanges *aors;
- int i, j, k;
-
- /*
- * Empty extension is cannonical.
- */
- if (addr == NULL)
- return 1;
-
- /*
- * Check whether the top-level list is in order.
- */
- for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
- const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
- const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
- if (IPAddressFamily_cmp(&a, &b) >= 0)
- return 0;
- }
-
- /*
- * Top level's ok, now check each address family.
- */
- for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
- IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
- int length = length_from_afi(v3_addr_get_afi(f));
-
- /*
- * Inheritance is canonical. Anything other than inheritance or
- * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.
- */
- if (f == NULL || f->ipAddressChoice == NULL)
- return 0;
- switch (f->ipAddressChoice->type) {
- case IPAddressChoice_inherit:
- continue;
- case IPAddressChoice_addressesOrRanges:
- break;
- default:
- return 0;
- }
-
- /*
- * It's an IPAddressOrRanges sequence, check it.
- */
- aors = f->ipAddressChoice->u.addressesOrRanges;
- if (sk_IPAddressOrRange_num(aors) == 0)
- return 0;
- for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
- IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
- IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
-
- extract_min_max(a, a_min, a_max, length);
- extract_min_max(b, b_min, b_max, length);
-
- /*
- * Punt misordered list, overlapping start, or inverted range.
- */
- if (memcmp(a_min, b_min, length) >= 0 ||
- memcmp(a_min, a_max, length) > 0 ||
- memcmp(b_min, b_max, length) > 0)
- return 0;
-
- /*
- * Punt if adjacent or overlapping. Check for adjacency by
- * subtracting one from b_min first.
- */
- for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--)
- ;
- if (memcmp(a_max, b_min, length) >= 0)
- return 0;
-
- /*
- * Check for range that should be expressed as a prefix.
- */
- if (a->type == IPAddressOrRange_addressRange &&
- range_should_be_prefix(a_min, a_max, length) >= 0)
- return 0;
- }
-
- /*
- * Check final range to see if it should be a prefix.
- */
- j = sk_IPAddressOrRange_num(aors) - 1;
- {
- IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
- if (a->type == IPAddressOrRange_addressRange) {
- extract_min_max(a, a_min, a_max, length);
- if (range_should_be_prefix(a_min, a_max, length) >= 0)
- return 0;
- }
- }
- }
-
- /*
- * If we made it through all that, we're happy.
- */
- return 1;
-}
-
-/*
- * Whack an IPAddressOrRanges into canonical form.
- */
-static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
- const unsigned afi)
-{
- int i, j, length = length_from_afi(afi);
-
- /*
- * Sort the IPAddressOrRanges sequence.
- */
- sk_IPAddressOrRange_sort(aors);
-
- /*
- * Clean up representation issues, punt on duplicates or overlaps.
- */
- for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
- IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);
- IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);
- unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
- unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
-
- extract_min_max(a, a_min, a_max, length);
- extract_min_max(b, b_min, b_max, length);
-
- /*
- * Punt overlaps.
- */
- if (memcmp(a_max, b_min, length) >= 0)
- return 0;
-
- /*
- * Merge if a and b are adjacent. We check for
- * adjacency by subtracting one from b_min first.
- */
- for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--)
- ;
- if (memcmp(a_max, b_min, length) == 0) {
- IPAddressOrRange *merged;
- if (!make_addressRange(&merged, a_min, b_max, length))
- return 0;
- sk_IPAddressOrRange_set(aors, i, merged);
- sk_IPAddressOrRange_delete(aors, i + 1);
- IPAddressOrRange_free(a);
- IPAddressOrRange_free(b);
- --i;
- continue;
- }
- }
-
- return 1;
-}
-
-/*
- * Whack an IPAddrBlocks extension into canonical form.
- */
-int v3_addr_canonize(IPAddrBlocks *addr)
-{
- int i;
- for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
- IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
- if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
- !IPAddressOrRanges_canonize(f->ipAddressChoice->u.addressesOrRanges,
- v3_addr_get_afi(f)))
- return 0;
- }
- sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
- sk_IPAddressFamily_sort(addr);
- OPENSSL_assert(v3_addr_is_canonical(addr));
- return 1;
-}
-
-/*
- * v2i handler for the IPAddrBlocks extension.
- */
-static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
- struct v3_ext_ctx *ctx,
- STACK_OF(CONF_VALUE) *values)
-{
- static const char v4addr_chars[] = "0123456789.";
- static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
- IPAddrBlocks *addr = NULL;
- char *s = NULL, *t;
- int i;
-
- if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
- CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
- unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
- unsigned afi, *safi = NULL, safi_;
- const char *addr_chars;
- int prefixlen, i1, i2, delim, length;
-
- if ( !name_cmp(val->name, "IPv4")) {
- afi = IANA_AFI_IPV4;
- } else if (!name_cmp(val->name, "IPv6")) {
- afi = IANA_AFI_IPV6;
- } else if (!name_cmp(val->name, "IPv4-SAFI")) {
- afi = IANA_AFI_IPV4;
- safi = &safi_;
- } else if (!name_cmp(val->name, "IPv6-SAFI")) {
- afi = IANA_AFI_IPV6;
- safi = &safi_;
- } else {
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_NAME_ERROR);
- X509V3_conf_err(val);
- goto err;
- }
-
- switch (afi) {
- case IANA_AFI_IPV4:
- addr_chars = v4addr_chars;
- break;
- case IANA_AFI_IPV6:
- addr_chars = v6addr_chars;
- break;
- }
-
- length = length_from_afi(afi);
-
- /*
- * Handle SAFI, if any, and BUF_strdup() so we can null-terminate
- * the other input values.
- */
- if (safi != NULL) {
- *safi = strtoul(val->value, &t, 0);
- t += strspn(t, " \t");
- if (*safi > 0xFF || *t++ != ':') {
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI);
- X509V3_conf_err(val);
- goto err;
- }
- t += strspn(t, " \t");
- s = BUF_strdup(t);
- } else {
- s = BUF_strdup(val->value);
- }
- if (s == NULL) {
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- /*
- * Check for inheritance. Not worth additional complexity to
- * optimize this (seldom-used) case.
- */
- if (!strcmp(s, "inherit")) {
- if (!v3_addr_add_inherit(addr, afi, safi)) {
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_INHERITANCE);
- X509V3_conf_err(val);
- goto err;
- }
- OPENSSL_free(s);
- s = NULL;
- continue;
- }
-
- i1 = strspn(s, addr_chars);
- i2 = i1 + strspn(s + i1, " \t");
- delim = s[i2++];
- s[i1] = '\0';
-
- if (a2i_ipadd(min, s) != length) {
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
- X509V3_conf_err(val);
- goto err;
- }
-
- switch (delim) {
- case '/':
- prefixlen = (int) strtoul(s + i2, &t, 10);
- if (t == s + i2 || *t != '\0') {
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
- X509V3_conf_err(val);
- goto err;
- }
- if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) {
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- break;
- case '-':
- i1 = i2 + strspn(s + i2, " \t");
- i2 = i1 + strspn(s + i1, addr_chars);
- if (i1 == i2 || s[i2] != '\0') {
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
- X509V3_conf_err(val);
- goto err;
- }
- if (a2i_ipadd(max, s + i1) != length) {
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
- X509V3_conf_err(val);
- goto err;
- }
- if (!v3_addr_add_range(addr, afi, safi, min, max)) {
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- break;
- case '\0':
- if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) {
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- break;
- default:
- X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
- X509V3_conf_err(val);
- goto err;
- }
-
- OPENSSL_free(s);
- s = NULL;
- }
-
- /*
- * Canonize the result, then we're done.
- */
- if (!v3_addr_canonize(addr))
- goto err;
- return addr;
-
- err:
- OPENSSL_free(s);
- sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
- return NULL;
-}
-
-/*
- * OpenSSL dispatch
- */
-const X509V3_EXT_METHOD v3_addr = {
- NID_sbgp_ipAddrBlock, /* nid */
- 0, /* flags */
- ASN1_ITEM_ref(IPAddrBlocks), /* template */
- 0, 0, 0, 0, /* old functions, ignored */
- 0, /* i2s */
- 0, /* s2i */
- 0, /* i2v */
- v2i_IPAddrBlocks, /* v2i */
- i2r_IPAddrBlocks, /* i2r */
- 0, /* r2i */
- NULL /* extension-specific data */
-};
-
-/*
- * Figure out whether extension sues inheritance.
- */
-int v3_addr_inherits(IPAddrBlocks *addr)
-{
- int i;
- if (addr == NULL)
- return 0;
- for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
- IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
- if (f->ipAddressChoice->type == IPAddressChoice_inherit)
- return 1;
- }
- return 0;
-}
-
-/*
- * Figure out whether parent contains child.
- */
-static int addr_contains(IPAddressOrRanges *parent,
- IPAddressOrRanges *child,
- int length)
-{
- unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN];
- unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN];
- int p, c;
-
- if (child == NULL || parent == child)
- return 1;
- if (parent == NULL)
- return 0;
-
- p = 0;
- for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
- extract_min_max(sk_IPAddressOrRange_value(child, c),
- c_min, c_max, length);
- for (;; p++) {
- if (p >= sk_IPAddressOrRange_num(parent))
- return 0;
- extract_min_max(sk_IPAddressOrRange_value(parent, p),
- p_min, p_max, length);
- if (memcmp(p_max, c_max, length) < 0)
- continue;
- if (memcmp(p_min, c_min, length) > 0)
- return 0;
- break;
- }
- }
-
- return 1;
-}
-
-/*
- * Test whether a is a subset of b.
- */
-int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
-{
- int i;
- if (a == NULL || a == b)
- return 1;
- if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b))
- return 0;
- sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
- for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
- IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
- int j = sk_IPAddressFamily_find(b, fa);
- IPAddressFamily *fb;
- fb = sk_IPAddressFamily_value(b, j);
- if (fb == NULL)
- return 0;
- if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges,
- fa->ipAddressChoice->u.addressesOrRanges,
- length_from_afi(v3_addr_get_afi(fb))))
- return 0;
- }
- return 1;
-}
-
-/*
- * Validation error handling via callback.
- */
-#define validation_err(_err_) \
- do { \
- if (ctx != NULL) { \
- ctx->error = _err_; \
- ctx->error_depth = i; \
- ctx->current_cert = x; \
- ret = ctx->verify_cb(0, ctx); \
- } else { \
- ret = 0; \
- } \
- if (!ret) \
- goto done; \
- } while (0)
-
-/*
- * Core code for RFC 3779 2.3 path validation.
- */
-static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
- STACK_OF(X509) *chain,
- IPAddrBlocks *ext)
-{
- IPAddrBlocks *child = NULL;
- int i, j, ret = 1;
- X509 *x;
-
- OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
- OPENSSL_assert(ctx != NULL || ext != NULL);
- OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
-
- /*
- * Figure out where to start. If we don't have an extension to
- * check, we're done. Otherwise, check canonical form and
- * set up for walking up the chain.
- */
- if (ext != NULL) {
- i = -1;
- x = NULL;
- } else {
- i = 0;
- x = sk_X509_value(chain, i);
- OPENSSL_assert(x != NULL);
- if ((ext = x->rfc3779_addr) == NULL)
- goto done;
- }
- if (!v3_addr_is_canonical(ext))
- validation_err(X509_V_ERR_INVALID_EXTENSION);
- sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
- if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
- X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE);
- ret = 0;
- goto done;
- }
-
- /*
- * Now walk up the chain. No cert may list resources that its
- * parent doesn't list.
- */
- for (i++; i < sk_X509_num(chain); i++) {
- x = sk_X509_value(chain, i);
- OPENSSL_assert(x != NULL);
- if (!v3_addr_is_canonical(x->rfc3779_addr))
- validation_err(X509_V_ERR_INVALID_EXTENSION);
- if (x->rfc3779_addr == NULL) {
- for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
- IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
- if (fc->ipAddressChoice->type != IPAddressChoice_inherit) {
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- break;
- }
- }
- continue;
- }
- sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
- for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
- IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
- int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
- IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, k);
- if (fp == NULL) {
- if (fc->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- break;
- }
- continue;
- }
- if (fp->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
- if (fc->ipAddressChoice->type == IPAddressChoice_inherit ||
- addr_contains(fp->ipAddressChoice->u.addressesOrRanges,
- fc->ipAddressChoice->u.addressesOrRanges,
- length_from_afi(v3_addr_get_afi(fc))))
- sk_IPAddressFamily_set(child, j, fp);
- else
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- }
- }
- }
-
- /*
- * Trust anchor can't inherit.
- */
- OPENSSL_assert(x != NULL);
- if (x->rfc3779_addr != NULL) {
- for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) {
- IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j);
- if (fp->ipAddressChoice->type == IPAddressChoice_inherit &&
- sk_IPAddressFamily_find(child, fp) >= 0)
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- }
- }
-
- done:
- sk_IPAddressFamily_free(child);
- return ret;
-}
-
-#undef validation_err
-
-/*
- * RFC 3779 2.3 path validation -- called from X509_verify_cert().
- */
-int v3_addr_validate_path(X509_STORE_CTX *ctx)
-{
- return v3_addr_validate_path_internal(ctx, ctx->chain, NULL);
-}
-
-/*
- * RFC 3779 2.3 path validation of an extension.
- * Test whether chain covers extension.
- */
-int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
- IPAddrBlocks *ext,
- int allow_inheritance)
-{
- if (ext == NULL)
- return 1;
- if (chain == NULL || sk_X509_num(chain) == 0)
- return 0;
- if (!allow_inheritance && v3_addr_inherits(ext))
- return 0;
- return v3_addr_validate_path_internal(NULL, chain, ext);
-}
-
-#endif /* OPENSSL_NO_RFC3779 */
+/*
+ * Contributed to the OpenSSL Project by the American Registry for
+ * Internet Numbers ("ARIN").
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ */
+
+/*
+ * Implementation of RFC 3779 section 2.2.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/buffer.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_NO_RFC3779
+
+/*
+ * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
+ */
+
+ASN1_SEQUENCE(IPAddressRange) = {
+ ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),
+ ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(IPAddressRange)
+
+ASN1_CHOICE(IPAddressOrRange) = {
+ ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),
+ ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange)
+} ASN1_CHOICE_END(IPAddressOrRange)
+
+ASN1_CHOICE(IPAddressChoice) = {
+ ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL),
+ ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)
+} ASN1_CHOICE_END(IPAddressChoice)
+
+ASN1_SEQUENCE(IPAddressFamily) = {
+ ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING),
+ ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)
+} ASN1_SEQUENCE_END(IPAddressFamily)
+
+ASN1_ITEM_TEMPLATE(IPAddrBlocks) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
+ IPAddrBlocks, IPAddressFamily)
+ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)
+
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)
+
+/*
+ * How much buffer space do we need for a raw address?
+ */
+#define ADDR_RAW_BUF_LEN 16
+
+/*
+ * What's the address length associated with this AFI?
+ */
+static int length_from_afi(const unsigned afi)
+{
+ switch (afi) {
+ case IANA_AFI_IPV4:
+ return 4;
+ case IANA_AFI_IPV6:
+ return 16;
+ default:
+ return 0;
+ }
+}
+
+/*
+ * Extract the AFI from an IPAddressFamily.
+ */
+unsigned int v3_addr_get_afi(const IPAddressFamily *f)
+{
+ return ((f != NULL &&
+ f->addressFamily != NULL &&
+ f->addressFamily->data != NULL)
+ ? ((f->addressFamily->data[0] << 8) |
+ (f->addressFamily->data[1]))
+ : 0);
+}
+
+/*
+ * Expand the bitstring form of an address into a raw byte array.
+ * At the moment this is coded for simplicity, not speed.
+ */
+static void addr_expand(unsigned char *addr,
+ const ASN1_BIT_STRING *bs,
+ const int length,
+ const unsigned char fill)
+{
+ OPENSSL_assert(bs->length >= 0 && bs->length <= length);
+ if (bs->length > 0) {
+ memcpy(addr, bs->data, bs->length);
+ if ((bs->flags & 7) != 0) {
+ unsigned char mask = 0xFF >> (8 - (bs->flags & 7));
+ if (fill == 0)
+ addr[bs->length - 1] &= ~mask;
+ else
+ addr[bs->length - 1] |= mask;
+ }
+ }
+ memset(addr + bs->length, fill, length - bs->length);
+}
+
+/*
+ * Extract the prefix length from a bitstring.
+ */
+#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))
+
+/*
+ * i2r handler for one address bitstring.
+ */
+static int i2r_address(BIO *out,
+ const unsigned afi,
+ const unsigned char fill,
+ const ASN1_BIT_STRING *bs)
+{
+ unsigned char addr[ADDR_RAW_BUF_LEN];
+ int i, n;
+
+ if (bs->length < 0)
+ return 0;
+ switch (afi) {
+ case IANA_AFI_IPV4:
+ if (bs->length > 4)
+ return 0;
+ addr_expand(addr, bs, 4, fill);
+ BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
+ break;
+ case IANA_AFI_IPV6:
+ if (bs->length > 16)
+ return 0;
+ addr_expand(addr, bs, 16, fill);
+ for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
+ ;
+ for (i = 0; i < n; i += 2)
+ BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i+1], (i < 14 ? ":" : ""));
+ if (i < 16)
+ BIO_puts(out, ":");
+ if (i == 0)
+ BIO_puts(out, ":");
+ break;
+ default:
+ for (i = 0; i < bs->length; i++)
+ BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);
+ BIO_printf(out, "[%d]", (int) (bs->flags & 7));
+ break;
+ }
+ return 1;
+}
+
+/*
+ * i2r handler for a sequence of addresses and ranges.
+ */
+static int i2r_IPAddressOrRanges(BIO *out,
+ const int indent,
+ const IPAddressOrRanges *aors,
+ const unsigned afi)
+{
+ int i;
+ for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
+ const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);
+ BIO_printf(out, "%*s", indent, "");
+ switch (aor->type) {
+ case IPAddressOrRange_addressPrefix:
+ if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))
+ return 0;
+ BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));
+ continue;
+ case IPAddressOrRange_addressRange:
+ if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))
+ return 0;
+ BIO_puts(out, "-");
+ if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))
+ return 0;
+ BIO_puts(out, "\n");
+ continue;
+ }
+ }
+ return 1;
+}
+
+/*
+ * i2r handler for an IPAddrBlocks extension.
+ */
+static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method,
+ void *ext,
+ BIO *out,
+ int indent)
+{
+ const IPAddrBlocks *addr = ext;
+ int i;
+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+ const unsigned int afi = v3_addr_get_afi(f);
+ switch (afi) {
+ case IANA_AFI_IPV4:
+ BIO_printf(out, "%*sIPv4", indent, "");
+ break;
+ case IANA_AFI_IPV6:
+ BIO_printf(out, "%*sIPv6", indent, "");
+ break;
+ default:
+ BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
+ break;
+ }
+ if (f->addressFamily->length > 2) {
+ switch (f->addressFamily->data[2]) {
+ case 1:
+ BIO_puts(out, " (Unicast)");
+ break;
+ case 2:
+ BIO_puts(out, " (Multicast)");
+ break;
+ case 3:
+ BIO_puts(out, " (Unicast/Multicast)");
+ break;
+ case 4:
+ BIO_puts(out, " (MPLS)");
+ break;
+ case 64:
+ BIO_puts(out, " (Tunnel)");
+ break;
+ case 65:
+ BIO_puts(out, " (VPLS)");
+ break;
+ case 66:
+ BIO_puts(out, " (BGP MDT)");
+ break;
+ case 128:
+ BIO_puts(out, " (MPLS-labeled VPN)");
+ break;
+ default:
+ BIO_printf(out, " (Unknown SAFI %u)",
+ (unsigned) f->addressFamily->data[2]);
+ break;
+ }
+ }
+ switch (f->ipAddressChoice->type) {
+ case IPAddressChoice_inherit:
+ BIO_puts(out, ": inherit\n");
+ break;
+ case IPAddressChoice_addressesOrRanges:
+ BIO_puts(out, ":\n");
+ if (!i2r_IPAddressOrRanges(out,
+ indent + 2,
+ f->ipAddressChoice->u.addressesOrRanges,
+ afi))
+ return 0;
+ break;
+ }
+ }
+ return 1;
+}
+
+/*
+ * Sort comparison function for a sequence of IPAddressOrRange
+ * elements.
+ */
+static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
+ const IPAddressOrRange *b,
+ const int length)
+{
+ unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
+ int prefixlen_a = 0, prefixlen_b = 0;
+ int r;
+
+ switch (a->type) {
+ case IPAddressOrRange_addressPrefix:
+ addr_expand(addr_a, a->u.addressPrefix, length, 0x00);
+ prefixlen_a = addr_prefixlen(a->u.addressPrefix);
+ break;
+ case IPAddressOrRange_addressRange:
+ addr_expand(addr_a, a->u.addressRange->min, length, 0x00);
+ prefixlen_a = length * 8;
+ break;
+ }
+
+ switch (b->type) {
+ case IPAddressOrRange_addressPrefix:
+ addr_expand(addr_b, b->u.addressPrefix, length, 0x00);
+ prefixlen_b = addr_prefixlen(b->u.addressPrefix);
+ break;
+ case IPAddressOrRange_addressRange:
+ addr_expand(addr_b, b->u.addressRange->min, length, 0x00);
+ prefixlen_b = length * 8;
+ break;
+ }
+
+ if ((r = memcmp(addr_a, addr_b, length)) != 0)
+ return r;
+ else
+ return prefixlen_a - prefixlen_b;
+}
+
+/*
+ * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
+ * comparision routines are only allowed two arguments.
+ */
+static int v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
+ const IPAddressOrRange * const *b)
+{
+ return IPAddressOrRange_cmp(*a, *b, 4);
+}
+
+/*
+ * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
+ * comparision routines are only allowed two arguments.
+ */
+static int v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a,
+ const IPAddressOrRange * const *b)
+{
+ return IPAddressOrRange_cmp(*a, *b, 16);
+}
+
+/*
+ * Calculate whether a range collapses to a prefix.
+ * See last paragraph of RFC 3779 2.2.3.7.
+ */
+static int range_should_be_prefix(const unsigned char *min,
+ const unsigned char *max,
+ const int length)
+{
+ unsigned char mask;
+ int i, j;
+
+ for (i = 0; i < length && min[i] == max[i]; i++)
+ ;
+ for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--)
+ ;
+ if (i < j)
+ return -1;
+ if (i > j)
+ return i * 8;
+ mask = min[i] ^ max[i];
+ switch (mask) {
+ case 0x01: j = 7; break;
+ case 0x03: j = 6; break;
+ case 0x07: j = 5; break;
+ case 0x0F: j = 4; break;
+ case 0x1F: j = 3; break;
+ case 0x3F: j = 2; break;
+ case 0x7F: j = 1; break;
+ default: return -1;
+ }
+ if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
+ return -1;
+ else
+ return i * 8 + j;
+}
+
+/*
+ * Construct a prefix.
+ */
+static int make_addressPrefix(IPAddressOrRange **result,
+ unsigned char *addr,
+ const int prefixlen)
+{
+ int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
+ IPAddressOrRange *aor = IPAddressOrRange_new();
+
+ if (aor == NULL)
+ return 0;
+ aor->type = IPAddressOrRange_addressPrefix;
+ if (aor->u.addressPrefix == NULL &&
+ (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
+ goto err;
+ if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
+ goto err;
+ aor->u.addressPrefix->flags &= ~7;
+ aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ if (bitlen > 0) {
+ aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);
+ aor->u.addressPrefix->flags |= 8 - bitlen;
+ }
+
+ *result = aor;
+ return 1;
+
+ err:
+ IPAddressOrRange_free(aor);
+ return 0;
+}
+
+/*
+ * Construct a range. If it can be expressed as a prefix,
+ * return a prefix instead. Doing this here simplifies
+ * the rest of the code considerably.
+ */
+static int make_addressRange(IPAddressOrRange **result,
+ unsigned char *min,
+ unsigned char *max,
+ const int length)
+{
+ IPAddressOrRange *aor;
+ int i, prefixlen;
+
+ if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
+ return make_addressPrefix(result, min, prefixlen);
+
+ if ((aor = IPAddressOrRange_new()) == NULL)
+ return 0;
+ aor->type = IPAddressOrRange_addressRange;
+ OPENSSL_assert(aor->u.addressRange == NULL);
+ if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
+ goto err;
+ if (aor->u.addressRange->min == NULL &&
+ (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)
+ goto err;
+ if (aor->u.addressRange->max == NULL &&
+ (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)
+ goto err;
+
+ for (i = length; i > 0 && min[i - 1] == 0x00; --i)
+ ;
+ if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))
+ goto err;
+ aor->u.addressRange->min->flags &= ~7;
+ aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ if (i > 0) {
+ unsigned char b = min[i - 1];
+ int j = 1;
+ while ((b & (0xFFU >> j)) != 0)
+ ++j;
+ aor->u.addressRange->min->flags |= 8 - j;
+ }
+
+ for (i = length; i > 0 && max[i - 1] == 0xFF; --i)
+ ;
+ if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))
+ goto err;
+ aor->u.addressRange->max->flags &= ~7;
+ aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ if (i > 0) {
+ unsigned char b = max[i - 1];
+ int j = 1;
+ while ((b & (0xFFU >> j)) != (0xFFU >> j))
+ ++j;
+ aor->u.addressRange->max->flags |= 8 - j;
+ }
+
+ *result = aor;
+ return 1;
+
+ err:
+ IPAddressOrRange_free(aor);
+ return 0;
+}
+
+/*
+ * Construct a new address family or find an existing one.
+ */
+static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
+ const unsigned afi,
+ const unsigned *safi)
+{
+ IPAddressFamily *f;
+ unsigned char key[3];
+ unsigned keylen;
+ int i;
+
+ key[0] = (afi >> 8) & 0xFF;
+ key[1] = afi & 0xFF;
+ if (safi != NULL) {
+ key[2] = *safi & 0xFF;
+ keylen = 3;
+ } else {
+ keylen = 2;
+ }
+
+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+ f = sk_IPAddressFamily_value(addr, i);
+ OPENSSL_assert(f->addressFamily->data != NULL);
+ if (f->addressFamily->length == keylen &&
+ !memcmp(f->addressFamily->data, key, keylen))
+ return f;
+ }
+
+ if ((f = IPAddressFamily_new()) == NULL)
+ goto err;
+ if (f->ipAddressChoice == NULL &&
+ (f->ipAddressChoice = IPAddressChoice_new()) == NULL)
+ goto err;
+ if (f->addressFamily == NULL &&
+ (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)
+ goto err;
+ if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))
+ goto err;
+ if (!sk_IPAddressFamily_push(addr, f))
+ goto err;
+
+ return f;
+
+ err:
+ IPAddressFamily_free(f);
+ return NULL;
+}
+
+/*
+ * Add an inheritance element.
+ */
+int v3_addr_add_inherit(IPAddrBlocks *addr,
+ const unsigned afi,
+ const unsigned *safi)
+{
+ IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
+ if (f == NULL ||
+ f->ipAddressChoice == NULL ||
+ (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
+ f->ipAddressChoice->u.addressesOrRanges != NULL))
+ return 0;
+ if (f->ipAddressChoice->type == IPAddressChoice_inherit &&
+ f->ipAddressChoice->u.inherit != NULL)
+ return 1;
+ if (f->ipAddressChoice->u.inherit == NULL &&
+ (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
+ return 0;
+ f->ipAddressChoice->type = IPAddressChoice_inherit;
+ return 1;
+}
+
+/*
+ * Construct an IPAddressOrRange sequence, or return an existing one.
+ */
+static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
+ const unsigned afi,
+ const unsigned *safi)
+{
+ IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
+ IPAddressOrRanges *aors = NULL;
+
+ if (f == NULL ||
+ f->ipAddressChoice == NULL ||
+ (f->ipAddressChoice->type == IPAddressChoice_inherit &&
+ f->ipAddressChoice->u.inherit != NULL))
+ return NULL;
+ if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)
+ aors = f->ipAddressChoice->u.addressesOrRanges;
+ if (aors != NULL)
+ return aors;
+ if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
+ return NULL;
+ switch (afi) {
+ case IANA_AFI_IPV4:
+ sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
+ break;
+ case IANA_AFI_IPV6:
+ sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
+ break;
+ }
+ f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
+ f->ipAddressChoice->u.addressesOrRanges = aors;
+ return aors;
+}
+
+/*
+ * Add a prefix.
+ */
+int v3_addr_add_prefix(IPAddrBlocks *addr,
+ const unsigned afi,
+ const unsigned *safi,
+ unsigned char *a,
+ const int prefixlen)
+{
+ IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
+ IPAddressOrRange *aor;
+ if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
+ return 0;
+ if (sk_IPAddressOrRange_push(aors, aor))
+ return 1;
+ IPAddressOrRange_free(aor);
+ return 0;
+}
+
+/*
+ * Add a range.
+ */
+int v3_addr_add_range(IPAddrBlocks *addr,
+ const unsigned afi,
+ const unsigned *safi,
+ unsigned char *min,
+ unsigned char *max)
+{
+ IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
+ IPAddressOrRange *aor;
+ int length = length_from_afi(afi);
+ if (aors == NULL)
+ return 0;
+ if (!make_addressRange(&aor, min, max, length))
+ return 0;
+ if (sk_IPAddressOrRange_push(aors, aor))
+ return 1;
+ IPAddressOrRange_free(aor);
+ return 0;
+}
+
+/*
+ * Extract min and max values from an IPAddressOrRange.
+ */
+static void extract_min_max(IPAddressOrRange *aor,
+ unsigned char *min,
+ unsigned char *max,
+ int length)
+{
+ OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
+ switch (aor->type) {
+ case IPAddressOrRange_addressPrefix:
+ addr_expand(min, aor->u.addressPrefix, length, 0x00);
+ addr_expand(max, aor->u.addressPrefix, length, 0xFF);
+ return;
+ case IPAddressOrRange_addressRange:
+ addr_expand(min, aor->u.addressRange->min, length, 0x00);
+ addr_expand(max, aor->u.addressRange->max, length, 0xFF);
+ return;
+ }
+}
+
+/*
+ * Public wrapper for extract_min_max().
+ */
+int v3_addr_get_range(IPAddressOrRange *aor,
+ const unsigned afi,
+ unsigned char *min,
+ unsigned char *max,
+ const int length)
+{
+ int afi_length = length_from_afi(afi);
+ if (aor == NULL || min == NULL || max == NULL ||
+ afi_length == 0 || length < afi_length ||
+ (aor->type != IPAddressOrRange_addressPrefix &&
+ aor->type != IPAddressOrRange_addressRange))
+ return 0;
+ extract_min_max(aor, min, max, afi_length);
+ return afi_length;
+}
+
+/*
+ * Sort comparision function for a sequence of IPAddressFamily.
+ *
+ * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
+ * the ordering: I can read it as meaning that IPv6 without a SAFI
+ * comes before IPv4 with a SAFI, which seems pretty weird. The
+ * examples in appendix B suggest that the author intended the
+ * null-SAFI rule to apply only within a single AFI, which is what I
+ * would have expected and is what the following code implements.
+ */
+static int IPAddressFamily_cmp(const IPAddressFamily * const *a_,
+ const IPAddressFamily * const *b_)
+{
+ const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
+ const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
+ int len = ((a->length <= b->length) ? a->length : b->length);
+ int cmp = memcmp(a->data, b->data, len);
+ return cmp ? cmp : a->length - b->length;
+}
+
+/*
+ * Check whether an IPAddrBLocks is in canonical form.
+ */
+int v3_addr_is_canonical(IPAddrBlocks *addr)
+{
+ unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+ unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
+ IPAddressOrRanges *aors;
+ int i, j, k;
+
+ /*
+ * Empty extension is cannonical.
+ */
+ if (addr == NULL)
+ return 1;
+
+ /*
+ * Check whether the top-level list is in order.
+ */
+ for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
+ const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
+ const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
+ if (IPAddressFamily_cmp(&a, &b) >= 0)
+ return 0;
+ }
+
+ /*
+ * Top level's ok, now check each address family.
+ */
+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+ int length = length_from_afi(v3_addr_get_afi(f));
+
+ /*
+ * Inheritance is canonical. Anything other than inheritance or
+ * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.
+ */
+ if (f == NULL || f->ipAddressChoice == NULL)
+ return 0;
+ switch (f->ipAddressChoice->type) {
+ case IPAddressChoice_inherit:
+ continue;
+ case IPAddressChoice_addressesOrRanges:
+ break;
+ default:
+ return 0;
+ }
+
+ /*
+ * It's an IPAddressOrRanges sequence, check it.
+ */
+ aors = f->ipAddressChoice->u.addressesOrRanges;
+ if (sk_IPAddressOrRange_num(aors) == 0)
+ return 0;
+ for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+ IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
+
+ extract_min_max(a, a_min, a_max, length);
+ extract_min_max(b, b_min, b_max, length);
+
+ /*
+ * Punt misordered list, overlapping start, or inverted range.
+ */
+ if (memcmp(a_min, b_min, length) >= 0 ||
+ memcmp(a_min, a_max, length) > 0 ||
+ memcmp(b_min, b_max, length) > 0)
+ return 0;
+
+ /*
+ * Punt if adjacent or overlapping. Check for adjacency by
+ * subtracting one from b_min first.
+ */
+ for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--)
+ ;
+ if (memcmp(a_max, b_min, length) >= 0)
+ return 0;
+
+ /*
+ * Check for range that should be expressed as a prefix.
+ */
+ if (a->type == IPAddressOrRange_addressRange &&
+ range_should_be_prefix(a_min, a_max, length) >= 0)
+ return 0;
+ }
+
+ /*
+ * Check final range to see if it should be a prefix.
+ */
+ j = sk_IPAddressOrRange_num(aors) - 1;
+ {
+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+ if (a->type == IPAddressOrRange_addressRange) {
+ extract_min_max(a, a_min, a_max, length);
+ if (range_should_be_prefix(a_min, a_max, length) >= 0)
+ return 0;
+ }
+ }
+ }
+
+ /*
+ * If we made it through all that, we're happy.
+ */
+ return 1;
+}
+
+/*
+ * Whack an IPAddressOrRanges into canonical form.
+ */
+static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
+ const unsigned afi)
+{
+ int i, j, length = length_from_afi(afi);
+
+ /*
+ * Sort the IPAddressOrRanges sequence.
+ */
+ sk_IPAddressOrRange_sort(aors);
+
+ /*
+ * Clean up representation issues, punt on duplicates or overlaps.
+ */
+ for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);
+ IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);
+ unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+ unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
+
+ extract_min_max(a, a_min, a_max, length);
+ extract_min_max(b, b_min, b_max, length);
+
+ /*
+ * Punt overlaps.
+ */
+ if (memcmp(a_max, b_min, length) >= 0)
+ return 0;
+
+ /*
+ * Merge if a and b are adjacent. We check for
+ * adjacency by subtracting one from b_min first.
+ */
+ for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--)
+ ;
+ if (memcmp(a_max, b_min, length) == 0) {
+ IPAddressOrRange *merged;
+ if (!make_addressRange(&merged, a_min, b_max, length))
+ return 0;
+ sk_IPAddressOrRange_set(aors, i, merged);
+ sk_IPAddressOrRange_delete(aors, i + 1);
+ IPAddressOrRange_free(a);
+ IPAddressOrRange_free(b);
+ --i;
+ continue;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Whack an IPAddrBlocks extension into canonical form.
+ */
+int v3_addr_canonize(IPAddrBlocks *addr)
+{
+ int i;
+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+ if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
+ !IPAddressOrRanges_canonize(f->ipAddressChoice->u.addressesOrRanges,
+ v3_addr_get_afi(f)))
+ return 0;
+ }
+ sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
+ sk_IPAddressFamily_sort(addr);
+ OPENSSL_assert(v3_addr_is_canonical(addr));
+ return 1;
+}
+
+/*
+ * v2i handler for the IPAddrBlocks extension.
+ */
+static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
+ struct v3_ext_ctx *ctx,
+ STACK_OF(CONF_VALUE) *values)
+{
+ static const char v4addr_chars[] = "0123456789.";
+ static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
+ IPAddrBlocks *addr = NULL;
+ char *s = NULL, *t;
+ int i;
+
+ if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+ CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
+ unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
+ unsigned afi, *safi = NULL, safi_;
+ const char *addr_chars;
+ int prefixlen, i1, i2, delim, length;
+
+ if ( !name_cmp(val->name, "IPv4")) {
+ afi = IANA_AFI_IPV4;
+ } else if (!name_cmp(val->name, "IPv6")) {
+ afi = IANA_AFI_IPV6;
+ } else if (!name_cmp(val->name, "IPv4-SAFI")) {
+ afi = IANA_AFI_IPV4;
+ safi = &safi_;
+ } else if (!name_cmp(val->name, "IPv6-SAFI")) {
+ afi = IANA_AFI_IPV6;
+ safi = &safi_;
+ } else {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_NAME_ERROR);
+ X509V3_conf_err(val);
+ goto err;
+ }
+
+ switch (afi) {
+ case IANA_AFI_IPV4:
+ addr_chars = v4addr_chars;
+ break;
+ case IANA_AFI_IPV6:
+ addr_chars = v6addr_chars;
+ break;
+ }
+
+ length = length_from_afi(afi);
+
+ /*
+ * Handle SAFI, if any, and BUF_strdup() so we can null-terminate
+ * the other input values.
+ */
+ if (safi != NULL) {
+ *safi = strtoul(val->value, &t, 0);
+ t += strspn(t, " \t");
+ if (*safi > 0xFF || *t++ != ':') {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ t += strspn(t, " \t");
+ s = BUF_strdup(t);
+ } else {
+ s = BUF_strdup(val->value);
+ }
+ if (s == NULL) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /*
+ * Check for inheritance. Not worth additional complexity to
+ * optimize this (seldom-used) case.
+ */
+ if (!strcmp(s, "inherit")) {
+ if (!v3_addr_add_inherit(addr, afi, safi)) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_INHERITANCE);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ OPENSSL_free(s);
+ s = NULL;
+ continue;
+ }
+
+ i1 = strspn(s, addr_chars);
+ i2 = i1 + strspn(s + i1, " \t");
+ delim = s[i2++];
+ s[i1] = '\0';
+
+ if (a2i_ipadd(min, s) != length) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
+ X509V3_conf_err(val);
+ goto err;
+ }
+
+ switch (delim) {
+ case '/':
+ prefixlen = (int) strtoul(s + i2, &t, 10);
+ if (t == s + i2 || *t != '\0') {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ break;
+ case '-':
+ i1 = i2 + strspn(s + i2, " \t");
+ i2 = i1 + strspn(s + i1, addr_chars);
+ if (i1 == i2 || s[i2] != '\0') {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ if (a2i_ipadd(max, s + i1) != length) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ if (!v3_addr_add_range(addr, afi, safi, min, max)) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ break;
+ case '\0':
+ if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) {
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ break;
+ default:
+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR);
+ X509V3_conf_err(val);
+ goto err;
+ }
+
+ OPENSSL_free(s);
+ s = NULL;
+ }
+
+ /*
+ * Canonize the result, then we're done.
+ */
+ if (!v3_addr_canonize(addr))
+ goto err;
+ return addr;
+
+ err:
+ OPENSSL_free(s);
+ sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
+ return NULL;
+}
+
+/*
+ * OpenSSL dispatch
+ */
+const X509V3_EXT_METHOD v3_addr = {
+ NID_sbgp_ipAddrBlock, /* nid */
+ 0, /* flags */
+ ASN1_ITEM_ref(IPAddrBlocks), /* template */
+ 0, 0, 0, 0, /* old functions, ignored */
+ 0, /* i2s */
+ 0, /* s2i */
+ 0, /* i2v */
+ v2i_IPAddrBlocks, /* v2i */
+ i2r_IPAddrBlocks, /* i2r */
+ 0, /* r2i */
+ NULL /* extension-specific data */
+};
+
+/*
+ * Figure out whether extension sues inheritance.
+ */
+int v3_addr_inherits(IPAddrBlocks *addr)
+{
+ int i;
+ if (addr == NULL)
+ return 0;
+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+ if (f->ipAddressChoice->type == IPAddressChoice_inherit)
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Figure out whether parent contains child.
+ */
+static int addr_contains(IPAddressOrRanges *parent,
+ IPAddressOrRanges *child,
+ int length)
+{
+ unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN];
+ unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN];
+ int p, c;
+
+ if (child == NULL || parent == child)
+ return 1;
+ if (parent == NULL)
+ return 0;
+
+ p = 0;
+ for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
+ extract_min_max(sk_IPAddressOrRange_value(child, c),
+ c_min, c_max, length);
+ for (;; p++) {
+ if (p >= sk_IPAddressOrRange_num(parent))
+ return 0;
+ extract_min_max(sk_IPAddressOrRange_value(parent, p),
+ p_min, p_max, length);
+ if (memcmp(p_max, c_max, length) < 0)
+ continue;
+ if (memcmp(p_min, c_min, length) > 0)
+ return 0;
+ break;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Test whether a is a subset of b.
+ */
+int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
+{
+ int i;
+ if (a == NULL || a == b)
+ return 1;
+ if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b))
+ return 0;
+ sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
+ for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
+ IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
+ int j = sk_IPAddressFamily_find(b, fa);
+ IPAddressFamily *fb;
+ fb = sk_IPAddressFamily_value(b, j);
+ if (fb == NULL)
+ return 0;
+ if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges,
+ fa->ipAddressChoice->u.addressesOrRanges,
+ length_from_afi(v3_addr_get_afi(fb))))
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Validation error handling via callback.
+ */
+#define validation_err(_err_) \
+ do { \
+ if (ctx != NULL) { \
+ ctx->error = _err_; \
+ ctx->error_depth = i; \
+ ctx->current_cert = x; \
+ ret = ctx->verify_cb(0, ctx); \
+ } else { \
+ ret = 0; \
+ } \
+ if (!ret) \
+ goto done; \
+ } while (0)
+
+/*
+ * Core code for RFC 3779 2.3 path validation.
+ */
+static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
+ STACK_OF(X509) *chain,
+ IPAddrBlocks *ext)
+{
+ IPAddrBlocks *child = NULL;
+ int i, j, ret = 1;
+ X509 *x;
+
+ OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
+ OPENSSL_assert(ctx != NULL || ext != NULL);
+ OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
+
+ /*
+ * Figure out where to start. If we don't have an extension to
+ * check, we're done. Otherwise, check canonical form and
+ * set up for walking up the chain.
+ */
+ if (ext != NULL) {
+ i = -1;
+ x = NULL;
+ } else {
+ i = 0;
+ x = sk_X509_value(chain, i);
+ OPENSSL_assert(x != NULL);
+ if ((ext = x->rfc3779_addr) == NULL)
+ goto done;
+ }
+ if (!v3_addr_is_canonical(ext))
+ validation_err(X509_V_ERR_INVALID_EXTENSION);
+ sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
+ if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
+ X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE);
+ ret = 0;
+ goto done;
+ }
+
+ /*
+ * Now walk up the chain. No cert may list resources that its
+ * parent doesn't list.
+ */
+ for (i++; i < sk_X509_num(chain); i++) {
+ x = sk_X509_value(chain, i);
+ OPENSSL_assert(x != NULL);
+ if (!v3_addr_is_canonical(x->rfc3779_addr))
+ validation_err(X509_V_ERR_INVALID_EXTENSION);
+ if (x->rfc3779_addr == NULL) {
+ for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
+ IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
+ if (fc->ipAddressChoice->type != IPAddressChoice_inherit) {
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ break;
+ }
+ }
+ continue;
+ }
+ sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
+ for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
+ IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
+ int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
+ IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, k);
+ if (fp == NULL) {
+ if (fc->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ break;
+ }
+ continue;
+ }
+ if (fp->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) {
+ if (fc->ipAddressChoice->type == IPAddressChoice_inherit ||
+ addr_contains(fp->ipAddressChoice->u.addressesOrRanges,
+ fc->ipAddressChoice->u.addressesOrRanges,
+ length_from_afi(v3_addr_get_afi(fc))))
+ sk_IPAddressFamily_set(child, j, fp);
+ else
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ }
+ }
+ }
+
+ /*
+ * Trust anchor can't inherit.
+ */
+ OPENSSL_assert(x != NULL);
+ if (x->rfc3779_addr != NULL) {
+ for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) {
+ IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j);
+ if (fp->ipAddressChoice->type == IPAddressChoice_inherit &&
+ sk_IPAddressFamily_find(child, fp) >= 0)
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ }
+ }
+
+ done:
+ sk_IPAddressFamily_free(child);
+ return ret;
+}
+
+#undef validation_err
+
+/*
+ * RFC 3779 2.3 path validation -- called from X509_verify_cert().
+ */
+int v3_addr_validate_path(X509_STORE_CTX *ctx)
+{
+ return v3_addr_validate_path_internal(ctx, ctx->chain, NULL);
+}
+
+/*
+ * RFC 3779 2.3 path validation of an extension.
+ * Test whether chain covers extension.
+ */
+int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
+ IPAddrBlocks *ext,
+ int allow_inheritance)
+{
+ if (ext == NULL)
+ return 1;
+ if (chain == NULL || sk_X509_num(chain) == 0)
+ return 0;
+ if (!allow_inheritance && v3_addr_inherits(ext))
+ return 0;
+ return v3_addr_validate_path_internal(NULL, chain, ext);
+}
+
+#endif /* OPENSSL_NO_RFC3779 */
diff --git a/openssl/crypto/x509v3/v3_asid.c b/openssl/crypto/x509v3/v3_asid.c
index fb7bc147c..3f434c060 100644
--- a/openssl/crypto/x509v3/v3_asid.c
+++ b/openssl/crypto/x509v3/v3_asid.c
@@ -1,843 +1,843 @@
-/*
- * Contributed to the OpenSSL Project by the American Registry for
- * Internet Numbers ("ARIN").
- */
-/* ====================================================================
- * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- */
-
-/*
- * Implementation of RFC 3779 section 3.2.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "cryptlib.h"
-#include <openssl/conf.h>
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
-#include <openssl/x509v3.h>
-#include <openssl/x509.h>
-#include <openssl/bn.h>
-
-#ifndef OPENSSL_NO_RFC3779
-
-/*
- * OpenSSL ASN.1 template translation of RFC 3779 3.2.3.
- */
-
-ASN1_SEQUENCE(ASRange) = {
- ASN1_SIMPLE(ASRange, min, ASN1_INTEGER),
- ASN1_SIMPLE(ASRange, max, ASN1_INTEGER)
-} ASN1_SEQUENCE_END(ASRange)
-
-ASN1_CHOICE(ASIdOrRange) = {
- ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER),
- ASN1_SIMPLE(ASIdOrRange, u.range, ASRange)
-} ASN1_CHOICE_END(ASIdOrRange)
-
-ASN1_CHOICE(ASIdentifierChoice) = {
- ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL),
- ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange)
-} ASN1_CHOICE_END(ASIdentifierChoice)
-
-ASN1_SEQUENCE(ASIdentifiers) = {
- ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0),
- ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1)
-} ASN1_SEQUENCE_END(ASIdentifiers)
-
-IMPLEMENT_ASN1_FUNCTIONS(ASRange)
-IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange)
-IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice)
-IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers)
-
-/*
- * i2r method for an ASIdentifierChoice.
- */
-static int i2r_ASIdentifierChoice(BIO *out,
- ASIdentifierChoice *choice,
- int indent,
- const char *msg)
-{
- int i;
- char *s;
- if (choice == NULL)
- return 1;
- BIO_printf(out, "%*s%s:\n", indent, "", msg);
- switch (choice->type) {
- case ASIdentifierChoice_inherit:
- BIO_printf(out, "%*sinherit\n", indent + 2, "");
- break;
- case ASIdentifierChoice_asIdsOrRanges:
- for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) {
- ASIdOrRange *aor = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
- switch (aor->type) {
- case ASIdOrRange_id:
- if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL)
- return 0;
- BIO_printf(out, "%*s%s\n", indent + 2, "", s);
- OPENSSL_free(s);
- break;
- case ASIdOrRange_range:
- if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL)
- return 0;
- BIO_printf(out, "%*s%s-", indent + 2, "", s);
- OPENSSL_free(s);
- if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL)
- return 0;
- BIO_printf(out, "%s\n", s);
- OPENSSL_free(s);
- break;
- default:
- return 0;
- }
- }
- break;
- default:
- return 0;
- }
- return 1;
-}
-
-/*
- * i2r method for an ASIdentifier extension.
- */
-static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method,
- void *ext,
- BIO *out,
- int indent)
-{
- ASIdentifiers *asid = ext;
- return (i2r_ASIdentifierChoice(out, asid->asnum, indent,
- "Autonomous System Numbers") &&
- i2r_ASIdentifierChoice(out, asid->rdi, indent,
- "Routing Domain Identifiers"));
-}
-
-/*
- * Sort comparision function for a sequence of ASIdOrRange elements.
- */
-static int ASIdOrRange_cmp(const ASIdOrRange * const *a_,
- const ASIdOrRange * const *b_)
-{
- const ASIdOrRange *a = *a_, *b = *b_;
-
- OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) ||
- (a->type == ASIdOrRange_range && a->u.range != NULL &&
- a->u.range->min != NULL && a->u.range->max != NULL));
-
- OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) ||
- (b->type == ASIdOrRange_range && b->u.range != NULL &&
- b->u.range->min != NULL && b->u.range->max != NULL));
-
- if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id)
- return ASN1_INTEGER_cmp(a->u.id, b->u.id);
-
- if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) {
- int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min);
- return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, b->u.range->max);
- }
-
- if (a->type == ASIdOrRange_id)
- return ASN1_INTEGER_cmp(a->u.id, b->u.range->min);
- else
- return ASN1_INTEGER_cmp(a->u.range->min, b->u.id);
-}
-
-/*
- * Add an inherit element.
- */
-int v3_asid_add_inherit(ASIdentifiers *asid, int which)
-{
- ASIdentifierChoice **choice;
- if (asid == NULL)
- return 0;
- switch (which) {
- case V3_ASID_ASNUM:
- choice = &asid->asnum;
- break;
- case V3_ASID_RDI:
- choice = &asid->rdi;
- break;
- default:
- return 0;
- }
- if (*choice == NULL) {
- if ((*choice = ASIdentifierChoice_new()) == NULL)
- return 0;
- OPENSSL_assert((*choice)->u.inherit == NULL);
- if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL)
- return 0;
- (*choice)->type = ASIdentifierChoice_inherit;
- }
- return (*choice)->type == ASIdentifierChoice_inherit;
-}
-
-/*
- * Add an ID or range to an ASIdentifierChoice.
- */
-int v3_asid_add_id_or_range(ASIdentifiers *asid,
- int which,
- ASN1_INTEGER *min,
- ASN1_INTEGER *max)
-{
- ASIdentifierChoice **choice;
- ASIdOrRange *aor;
- if (asid == NULL)
- return 0;
- switch (which) {
- case V3_ASID_ASNUM:
- choice = &asid->asnum;
- break;
- case V3_ASID_RDI:
- choice = &asid->rdi;
- break;
- default:
- return 0;
- }
- if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit)
- return 0;
- if (*choice == NULL) {
- if ((*choice = ASIdentifierChoice_new()) == NULL)
- return 0;
- OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL);
- (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp);
- if ((*choice)->u.asIdsOrRanges == NULL)
- return 0;
- (*choice)->type = ASIdentifierChoice_asIdsOrRanges;
- }
- if ((aor = ASIdOrRange_new()) == NULL)
- return 0;
- if (max == NULL) {
- aor->type = ASIdOrRange_id;
- aor->u.id = min;
- } else {
- aor->type = ASIdOrRange_range;
- if ((aor->u.range = ASRange_new()) == NULL)
- goto err;
- ASN1_INTEGER_free(aor->u.range->min);
- aor->u.range->min = min;
- ASN1_INTEGER_free(aor->u.range->max);
- aor->u.range->max = max;
- }
- if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor)))
- goto err;
- return 1;
-
- err:
- ASIdOrRange_free(aor);
- return 0;
-}
-
-/*
- * Extract min and max values from an ASIdOrRange.
- */
-static void extract_min_max(ASIdOrRange *aor,
- ASN1_INTEGER **min,
- ASN1_INTEGER **max)
-{
- OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
- switch (aor->type) {
- case ASIdOrRange_id:
- *min = aor->u.id;
- *max = aor->u.id;
- return;
- case ASIdOrRange_range:
- *min = aor->u.range->min;
- *max = aor->u.range->max;
- return;
- }
-}
-
-/*
- * Check whether an ASIdentifierChoice is in canonical form.
- */
-static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
-{
- ASN1_INTEGER *a_max_plus_one = NULL;
- BIGNUM *bn = NULL;
- int i, ret = 0;
-
- /*
- * Empty element or inheritance is canonical.
- */
- if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
- return 1;
-
- /*
- * If not a list, or if empty list, it's broken.
- */
- if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
- sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0)
- return 0;
-
- /*
- * It's a list, check it.
- */
- for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
- ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
- ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
- ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
-
- extract_min_max(a, &a_min, &a_max);
- extract_min_max(b, &b_min, &b_max);
-
- /*
- * Punt misordered list, overlapping start, or inverted range.
- */
- if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 ||
- ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
- ASN1_INTEGER_cmp(b_min, b_max) > 0)
- goto done;
-
- /*
- * Calculate a_max + 1 to check for adjacency.
- */
- if ((bn == NULL && (bn = BN_new()) == NULL) ||
- ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
- !BN_add_word(bn, 1) ||
- (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
- X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL,
- ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- /*
- * Punt if adjacent or overlapping.
- */
- if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0)
- goto done;
- }
-
- ret = 1;
-
- done:
- ASN1_INTEGER_free(a_max_plus_one);
- BN_free(bn);
- return ret;
-}
-
-/*
- * Check whether an ASIdentifier extension is in canonical form.
- */
-int v3_asid_is_canonical(ASIdentifiers *asid)
-{
- return (asid == NULL ||
- (ASIdentifierChoice_is_canonical(asid->asnum) &&
- ASIdentifierChoice_is_canonical(asid->rdi)));
-}
-
-/*
- * Whack an ASIdentifierChoice into canonical form.
- */
-static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
-{
- ASN1_INTEGER *a_max_plus_one = NULL;
- BIGNUM *bn = NULL;
- int i, ret = 0;
-
- /*
- * Nothing to do for empty element or inheritance.
- */
- if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
- return 1;
-
- /*
- * We have a list. Sort it.
- */
- OPENSSL_assert(choice->type == ASIdentifierChoice_asIdsOrRanges);
- sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
-
- /*
- * Now check for errors and suboptimal encoding, rejecting the
- * former and fixing the latter.
- */
- for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
- ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
- ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
- ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
-
- extract_min_max(a, &a_min, &a_max);
- extract_min_max(b, &b_min, &b_max);
-
- /*
- * Make sure we're properly sorted (paranoia).
- */
- OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);
-
- /*
- * Check for overlaps.
- */
- if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
- X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
- X509V3_R_EXTENSION_VALUE_ERROR);
- goto done;
- }
-
- /*
- * Calculate a_max + 1 to check for adjacency.
- */
- if ((bn == NULL && (bn = BN_new()) == NULL) ||
- ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
- !BN_add_word(bn, 1) ||
- (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
- X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- /*
- * If a and b are adjacent, merge them.
- */
- if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) {
- ASRange *r;
- switch (a->type) {
- case ASIdOrRange_id:
- if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) {
- X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
- ERR_R_MALLOC_FAILURE);
- goto done;
- }
- r->min = a_min;
- r->max = b_max;
- a->type = ASIdOrRange_range;
- a->u.range = r;
- break;
- case ASIdOrRange_range:
- ASN1_INTEGER_free(a->u.range->max);
- a->u.range->max = b_max;
- break;
- }
- switch (b->type) {
- case ASIdOrRange_id:
- b->u.id = NULL;
- break;
- case ASIdOrRange_range:
- b->u.range->max = NULL;
- break;
- }
- ASIdOrRange_free(b);
- sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
- i--;
- continue;
- }
- }
-
- OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */
-
- ret = 1;
-
- done:
- ASN1_INTEGER_free(a_max_plus_one);
- BN_free(bn);
- return ret;
-}
-
-/*
- * Whack an ASIdentifier extension into canonical form.
- */
-int v3_asid_canonize(ASIdentifiers *asid)
-{
- return (asid == NULL ||
- (ASIdentifierChoice_canonize(asid->asnum) &&
- ASIdentifierChoice_canonize(asid->rdi)));
-}
-
-/*
- * v2i method for an ASIdentifier extension.
- */
-static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
- struct v3_ext_ctx *ctx,
- STACK_OF(CONF_VALUE) *values)
-{
- ASIdentifiers *asid = NULL;
- int i;
-
- if ((asid = ASIdentifiers_new()) == NULL) {
- X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
- CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
- ASN1_INTEGER *min = NULL, *max = NULL;
- int i1, i2, i3, is_range, which;
-
- /*
- * Figure out whether this is an AS or an RDI.
- */
- if ( !name_cmp(val->name, "AS")) {
- which = V3_ASID_ASNUM;
- } else if (!name_cmp(val->name, "RDI")) {
- which = V3_ASID_RDI;
- } else {
- X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_NAME_ERROR);
- X509V3_conf_err(val);
- goto err;
- }
-
- /*
- * Handle inheritance.
- */
- if (!strcmp(val->value, "inherit")) {
- if (v3_asid_add_inherit(asid, which))
- continue;
- X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_INHERITANCE);
- X509V3_conf_err(val);
- goto err;
- }
-
- /*
- * Number, range, or mistake, pick it apart and figure out which.
- */
- i1 = strspn(val->value, "0123456789");
- if (val->value[i1] == '\0') {
- is_range = 0;
- } else {
- is_range = 1;
- i2 = i1 + strspn(val->value + i1, " \t");
- if (val->value[i2] != '-') {
- X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASNUMBER);
- X509V3_conf_err(val);
- goto err;
- }
- i2++;
- i2 = i2 + strspn(val->value + i2, " \t");
- i3 = i2 + strspn(val->value + i2, "0123456789");
- if (val->value[i3] != '\0') {
- X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASRANGE);
- X509V3_conf_err(val);
- goto err;
- }
- }
-
- /*
- * Syntax is ok, read and add it.
- */
- if (!is_range) {
- if (!X509V3_get_value_int(val, &min)) {
- X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- } else {
- char *s = BUF_strdup(val->value);
- if (s == NULL) {
- X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- s[i1] = '\0';
- min = s2i_ASN1_INTEGER(NULL, s);
- max = s2i_ASN1_INTEGER(NULL, s + i2);
- OPENSSL_free(s);
- if (min == NULL || max == NULL) {
- ASN1_INTEGER_free(min);
- ASN1_INTEGER_free(max);
- X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- if (!v3_asid_add_id_or_range(asid, which, min, max)) {
- ASN1_INTEGER_free(min);
- ASN1_INTEGER_free(max);
- X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
-
- /*
- * Canonize the result, then we're done.
- */
- if (!v3_asid_canonize(asid))
- goto err;
- return asid;
-
- err:
- ASIdentifiers_free(asid);
- return NULL;
-}
-
-/*
- * OpenSSL dispatch.
- */
-const X509V3_EXT_METHOD v3_asid = {
- NID_sbgp_autonomousSysNum, /* nid */
- 0, /* flags */
- ASN1_ITEM_ref(ASIdentifiers), /* template */
- 0, 0, 0, 0, /* old functions, ignored */
- 0, /* i2s */
- 0, /* s2i */
- 0, /* i2v */
- v2i_ASIdentifiers, /* v2i */
- i2r_ASIdentifiers, /* i2r */
- 0, /* r2i */
- NULL /* extension-specific data */
-};
-
-/*
- * Figure out whether extension uses inheritance.
- */
-int v3_asid_inherits(ASIdentifiers *asid)
-{
- return (asid != NULL &&
- ((asid->asnum != NULL &&
- asid->asnum->type == ASIdentifierChoice_inherit) ||
- (asid->rdi != NULL &&
- asid->rdi->type == ASIdentifierChoice_inherit)));
-}
-
-/*
- * Figure out whether parent contains child.
- */
-static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child)
-{
- ASN1_INTEGER *p_min, *p_max, *c_min, *c_max;
- int p, c;
-
- if (child == NULL || parent == child)
- return 1;
- if (parent == NULL)
- return 0;
-
- p = 0;
- for (c = 0; c < sk_ASIdOrRange_num(child); c++) {
- extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max);
- for (;; p++) {
- if (p >= sk_ASIdOrRange_num(parent))
- return 0;
- extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max);
- if (ASN1_INTEGER_cmp(p_max, c_max) < 0)
- continue;
- if (ASN1_INTEGER_cmp(p_min, c_min) > 0)
- return 0;
- break;
- }
- }
-
- return 1;
-}
-
-/*
- * Test whether a is a subet of b.
- */
-int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b)
-{
- return (a == NULL ||
- a == b ||
- (b != NULL &&
- !v3_asid_inherits(a) &&
- !v3_asid_inherits(b) &&
- asid_contains(b->asnum->u.asIdsOrRanges,
- a->asnum->u.asIdsOrRanges) &&
- asid_contains(b->rdi->u.asIdsOrRanges,
- a->rdi->u.asIdsOrRanges)));
-}
-
-/*
- * Validation error handling via callback.
- */
-#define validation_err(_err_) \
- do { \
- if (ctx != NULL) { \
- ctx->error = _err_; \
- ctx->error_depth = i; \
- ctx->current_cert = x; \
- ret = ctx->verify_cb(0, ctx); \
- } else { \
- ret = 0; \
- } \
- if (!ret) \
- goto done; \
- } while (0)
-
-/*
- * Core code for RFC 3779 3.3 path validation.
- */
-static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx,
- STACK_OF(X509) *chain,
- ASIdentifiers *ext)
-{
- ASIdOrRanges *child_as = NULL, *child_rdi = NULL;
- int i, ret = 1, inherit_as = 0, inherit_rdi = 0;
- X509 *x;
-
- OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
- OPENSSL_assert(ctx != NULL || ext != NULL);
- OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
-
- /*
- * Figure out where to start. If we don't have an extension to
- * check, we're done. Otherwise, check canonical form and
- * set up for walking up the chain.
- */
- if (ext != NULL) {
- i = -1;
- x = NULL;
- } else {
- i = 0;
- x = sk_X509_value(chain, i);
- OPENSSL_assert(x != NULL);
- if ((ext = x->rfc3779_asid) == NULL)
- goto done;
- }
- if (!v3_asid_is_canonical(ext))
- validation_err(X509_V_ERR_INVALID_EXTENSION);
- if (ext->asnum != NULL) {
- switch (ext->asnum->type) {
- case ASIdentifierChoice_inherit:
- inherit_as = 1;
- break;
- case ASIdentifierChoice_asIdsOrRanges:
- child_as = ext->asnum->u.asIdsOrRanges;
- break;
- }
- }
- if (ext->rdi != NULL) {
- switch (ext->rdi->type) {
- case ASIdentifierChoice_inherit:
- inherit_rdi = 1;
- break;
- case ASIdentifierChoice_asIdsOrRanges:
- child_rdi = ext->rdi->u.asIdsOrRanges;
- break;
- }
- }
-
- /*
- * Now walk up the chain. Extensions must be in canonical form, no
- * cert may list resources that its parent doesn't list.
- */
- for (i++; i < sk_X509_num(chain); i++) {
- x = sk_X509_value(chain, i);
- OPENSSL_assert(x != NULL);
- if (x->rfc3779_asid == NULL) {
- if (child_as != NULL || child_rdi != NULL)
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- continue;
- }
- if (!v3_asid_is_canonical(x->rfc3779_asid))
- validation_err(X509_V_ERR_INVALID_EXTENSION);
- if (x->rfc3779_asid->asnum == NULL && child_as != NULL) {
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- child_as = NULL;
- inherit_as = 0;
- }
- if (x->rfc3779_asid->asnum != NULL &&
- x->rfc3779_asid->asnum->type == ASIdentifierChoice_asIdsOrRanges) {
- if (inherit_as ||
- asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, child_as)) {
- child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges;
- inherit_as = 0;
- } else {
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- }
- }
- if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) {
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- child_rdi = NULL;
- inherit_rdi = 0;
- }
- if (x->rfc3779_asid->rdi != NULL &&
- x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) {
- if (inherit_rdi ||
- asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, child_rdi)) {
- child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges;
- inherit_rdi = 0;
- } else {
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- }
- }
- }
-
- /*
- * Trust anchor can't inherit.
- */
- OPENSSL_assert(x != NULL);
- if (x->rfc3779_asid != NULL) {
- if (x->rfc3779_asid->asnum != NULL &&
- x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit)
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- if (x->rfc3779_asid->rdi != NULL &&
- x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit)
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- }
-
- done:
- return ret;
-}
-
-#undef validation_err
-
-/*
- * RFC 3779 3.3 path validation -- called from X509_verify_cert().
- */
-int v3_asid_validate_path(X509_STORE_CTX *ctx)
-{
- return v3_asid_validate_path_internal(ctx, ctx->chain, NULL);
-}
-
-/*
- * RFC 3779 3.3 path validation of an extension.
- * Test whether chain covers extension.
- */
-int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
- ASIdentifiers *ext,
- int allow_inheritance)
-{
- if (ext == NULL)
- return 1;
- if (chain == NULL || sk_X509_num(chain) == 0)
- return 0;
- if (!allow_inheritance && v3_asid_inherits(ext))
- return 0;
- return v3_asid_validate_path_internal(NULL, chain, ext);
-}
-
-#endif /* OPENSSL_NO_RFC3779 */
+/*
+ * Contributed to the OpenSSL Project by the American Registry for
+ * Internet Numbers ("ARIN").
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ */
+
+/*
+ * Implementation of RFC 3779 section 3.2.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+#include <openssl/x509.h>
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_RFC3779
+
+/*
+ * OpenSSL ASN.1 template translation of RFC 3779 3.2.3.
+ */
+
+ASN1_SEQUENCE(ASRange) = {
+ ASN1_SIMPLE(ASRange, min, ASN1_INTEGER),
+ ASN1_SIMPLE(ASRange, max, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(ASRange)
+
+ASN1_CHOICE(ASIdOrRange) = {
+ ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER),
+ ASN1_SIMPLE(ASIdOrRange, u.range, ASRange)
+} ASN1_CHOICE_END(ASIdOrRange)
+
+ASN1_CHOICE(ASIdentifierChoice) = {
+ ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL),
+ ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange)
+} ASN1_CHOICE_END(ASIdentifierChoice)
+
+ASN1_SEQUENCE(ASIdentifiers) = {
+ ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0),
+ ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1)
+} ASN1_SEQUENCE_END(ASIdentifiers)
+
+IMPLEMENT_ASN1_FUNCTIONS(ASRange)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers)
+
+/*
+ * i2r method for an ASIdentifierChoice.
+ */
+static int i2r_ASIdentifierChoice(BIO *out,
+ ASIdentifierChoice *choice,
+ int indent,
+ const char *msg)
+{
+ int i;
+ char *s;
+ if (choice == NULL)
+ return 1;
+ BIO_printf(out, "%*s%s:\n", indent, "", msg);
+ switch (choice->type) {
+ case ASIdentifierChoice_inherit:
+ BIO_printf(out, "%*sinherit\n", indent + 2, "");
+ break;
+ case ASIdentifierChoice_asIdsOrRanges:
+ for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) {
+ ASIdOrRange *aor = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+ switch (aor->type) {
+ case ASIdOrRange_id:
+ if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL)
+ return 0;
+ BIO_printf(out, "%*s%s\n", indent + 2, "", s);
+ OPENSSL_free(s);
+ break;
+ case ASIdOrRange_range:
+ if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL)
+ return 0;
+ BIO_printf(out, "%*s%s-", indent + 2, "", s);
+ OPENSSL_free(s);
+ if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL)
+ return 0;
+ BIO_printf(out, "%s\n", s);
+ OPENSSL_free(s);
+ break;
+ default:
+ return 0;
+ }
+ }
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * i2r method for an ASIdentifier extension.
+ */
+static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method,
+ void *ext,
+ BIO *out,
+ int indent)
+{
+ ASIdentifiers *asid = ext;
+ return (i2r_ASIdentifierChoice(out, asid->asnum, indent,
+ "Autonomous System Numbers") &&
+ i2r_ASIdentifierChoice(out, asid->rdi, indent,
+ "Routing Domain Identifiers"));
+}
+
+/*
+ * Sort comparision function for a sequence of ASIdOrRange elements.
+ */
+static int ASIdOrRange_cmp(const ASIdOrRange * const *a_,
+ const ASIdOrRange * const *b_)
+{
+ const ASIdOrRange *a = *a_, *b = *b_;
+
+ OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) ||
+ (a->type == ASIdOrRange_range && a->u.range != NULL &&
+ a->u.range->min != NULL && a->u.range->max != NULL));
+
+ OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) ||
+ (b->type == ASIdOrRange_range && b->u.range != NULL &&
+ b->u.range->min != NULL && b->u.range->max != NULL));
+
+ if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id)
+ return ASN1_INTEGER_cmp(a->u.id, b->u.id);
+
+ if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) {
+ int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min);
+ return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, b->u.range->max);
+ }
+
+ if (a->type == ASIdOrRange_id)
+ return ASN1_INTEGER_cmp(a->u.id, b->u.range->min);
+ else
+ return ASN1_INTEGER_cmp(a->u.range->min, b->u.id);
+}
+
+/*
+ * Add an inherit element.
+ */
+int v3_asid_add_inherit(ASIdentifiers *asid, int which)
+{
+ ASIdentifierChoice **choice;
+ if (asid == NULL)
+ return 0;
+ switch (which) {
+ case V3_ASID_ASNUM:
+ choice = &asid->asnum;
+ break;
+ case V3_ASID_RDI:
+ choice = &asid->rdi;
+ break;
+ default:
+ return 0;
+ }
+ if (*choice == NULL) {
+ if ((*choice = ASIdentifierChoice_new()) == NULL)
+ return 0;
+ OPENSSL_assert((*choice)->u.inherit == NULL);
+ if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL)
+ return 0;
+ (*choice)->type = ASIdentifierChoice_inherit;
+ }
+ return (*choice)->type == ASIdentifierChoice_inherit;
+}
+
+/*
+ * Add an ID or range to an ASIdentifierChoice.
+ */
+int v3_asid_add_id_or_range(ASIdentifiers *asid,
+ int which,
+ ASN1_INTEGER *min,
+ ASN1_INTEGER *max)
+{
+ ASIdentifierChoice **choice;
+ ASIdOrRange *aor;
+ if (asid == NULL)
+ return 0;
+ switch (which) {
+ case V3_ASID_ASNUM:
+ choice = &asid->asnum;
+ break;
+ case V3_ASID_RDI:
+ choice = &asid->rdi;
+ break;
+ default:
+ return 0;
+ }
+ if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit)
+ return 0;
+ if (*choice == NULL) {
+ if ((*choice = ASIdentifierChoice_new()) == NULL)
+ return 0;
+ OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL);
+ (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp);
+ if ((*choice)->u.asIdsOrRanges == NULL)
+ return 0;
+ (*choice)->type = ASIdentifierChoice_asIdsOrRanges;
+ }
+ if ((aor = ASIdOrRange_new()) == NULL)
+ return 0;
+ if (max == NULL) {
+ aor->type = ASIdOrRange_id;
+ aor->u.id = min;
+ } else {
+ aor->type = ASIdOrRange_range;
+ if ((aor->u.range = ASRange_new()) == NULL)
+ goto err;
+ ASN1_INTEGER_free(aor->u.range->min);
+ aor->u.range->min = min;
+ ASN1_INTEGER_free(aor->u.range->max);
+ aor->u.range->max = max;
+ }
+ if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor)))
+ goto err;
+ return 1;
+
+ err:
+ ASIdOrRange_free(aor);
+ return 0;
+}
+
+/*
+ * Extract min and max values from an ASIdOrRange.
+ */
+static void extract_min_max(ASIdOrRange *aor,
+ ASN1_INTEGER **min,
+ ASN1_INTEGER **max)
+{
+ OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
+ switch (aor->type) {
+ case ASIdOrRange_id:
+ *min = aor->u.id;
+ *max = aor->u.id;
+ return;
+ case ASIdOrRange_range:
+ *min = aor->u.range->min;
+ *max = aor->u.range->max;
+ return;
+ }
+}
+
+/*
+ * Check whether an ASIdentifierChoice is in canonical form.
+ */
+static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
+{
+ ASN1_INTEGER *a_max_plus_one = NULL;
+ BIGNUM *bn = NULL;
+ int i, ret = 0;
+
+ /*
+ * Empty element or inheritance is canonical.
+ */
+ if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
+ return 1;
+
+ /*
+ * If not a list, or if empty list, it's broken.
+ */
+ if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
+ sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0)
+ return 0;
+
+ /*
+ * It's a list, check it.
+ */
+ for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+ ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
+ ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
+
+ extract_min_max(a, &a_min, &a_max);
+ extract_min_max(b, &b_min, &b_max);
+
+ /*
+ * Punt misordered list, overlapping start, or inverted range.
+ */
+ if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 ||
+ ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
+ ASN1_INTEGER_cmp(b_min, b_max) > 0)
+ goto done;
+
+ /*
+ * Calculate a_max + 1 to check for adjacency.
+ */
+ if ((bn == NULL && (bn = BN_new()) == NULL) ||
+ ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
+ !BN_add_word(bn, 1) ||
+ (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL,
+ ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ /*
+ * Punt if adjacent or overlapping.
+ */
+ if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0)
+ goto done;
+ }
+
+ ret = 1;
+
+ done:
+ ASN1_INTEGER_free(a_max_plus_one);
+ BN_free(bn);
+ return ret;
+}
+
+/*
+ * Check whether an ASIdentifier extension is in canonical form.
+ */
+int v3_asid_is_canonical(ASIdentifiers *asid)
+{
+ return (asid == NULL ||
+ (ASIdentifierChoice_is_canonical(asid->asnum) &&
+ ASIdentifierChoice_is_canonical(asid->rdi)));
+}
+
+/*
+ * Whack an ASIdentifierChoice into canonical form.
+ */
+static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
+{
+ ASN1_INTEGER *a_max_plus_one = NULL;
+ BIGNUM *bn = NULL;
+ int i, ret = 0;
+
+ /*
+ * Nothing to do for empty element or inheritance.
+ */
+ if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
+ return 1;
+
+ /*
+ * We have a list. Sort it.
+ */
+ OPENSSL_assert(choice->type == ASIdentifierChoice_asIdsOrRanges);
+ sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
+
+ /*
+ * Now check for errors and suboptimal encoding, rejecting the
+ * former and fixing the latter.
+ */
+ for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+ ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
+ ASN1_INTEGER *a_min, *a_max, *b_min, *b_max;
+
+ extract_min_max(a, &a_min, &a_max);
+ extract_min_max(b, &b_min, &b_max);
+
+ /*
+ * Make sure we're properly sorted (paranoia).
+ */
+ OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);
+
+ /*
+ * Check for overlaps.
+ */
+ if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+ X509V3_R_EXTENSION_VALUE_ERROR);
+ goto done;
+ }
+
+ /*
+ * Calculate a_max + 1 to check for adjacency.
+ */
+ if ((bn == NULL && (bn = BN_new()) == NULL) ||
+ ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
+ !BN_add_word(bn, 1) ||
+ (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ /*
+ * If a and b are adjacent, merge them.
+ */
+ if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) {
+ ASRange *r;
+ switch (a->type) {
+ case ASIdOrRange_id:
+ if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) {
+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+ ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+ r->min = a_min;
+ r->max = b_max;
+ a->type = ASIdOrRange_range;
+ a->u.range = r;
+ break;
+ case ASIdOrRange_range:
+ ASN1_INTEGER_free(a->u.range->max);
+ a->u.range->max = b_max;
+ break;
+ }
+ switch (b->type) {
+ case ASIdOrRange_id:
+ b->u.id = NULL;
+ break;
+ case ASIdOrRange_range:
+ b->u.range->max = NULL;
+ break;
+ }
+ ASIdOrRange_free(b);
+ sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
+ i--;
+ continue;
+ }
+ }
+
+ OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */
+
+ ret = 1;
+
+ done:
+ ASN1_INTEGER_free(a_max_plus_one);
+ BN_free(bn);
+ return ret;
+}
+
+/*
+ * Whack an ASIdentifier extension into canonical form.
+ */
+int v3_asid_canonize(ASIdentifiers *asid)
+{
+ return (asid == NULL ||
+ (ASIdentifierChoice_canonize(asid->asnum) &&
+ ASIdentifierChoice_canonize(asid->rdi)));
+}
+
+/*
+ * v2i method for an ASIdentifier extension.
+ */
+static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
+ struct v3_ext_ctx *ctx,
+ STACK_OF(CONF_VALUE) *values)
+{
+ ASIdentifiers *asid = NULL;
+ int i;
+
+ if ((asid = ASIdentifiers_new()) == NULL) {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+ CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
+ ASN1_INTEGER *min = NULL, *max = NULL;
+ int i1, i2, i3, is_range, which;
+
+ /*
+ * Figure out whether this is an AS or an RDI.
+ */
+ if ( !name_cmp(val->name, "AS")) {
+ which = V3_ASID_ASNUM;
+ } else if (!name_cmp(val->name, "RDI")) {
+ which = V3_ASID_RDI;
+ } else {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_NAME_ERROR);
+ X509V3_conf_err(val);
+ goto err;
+ }
+
+ /*
+ * Handle inheritance.
+ */
+ if (!strcmp(val->value, "inherit")) {
+ if (v3_asid_add_inherit(asid, which))
+ continue;
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_INHERITANCE);
+ X509V3_conf_err(val);
+ goto err;
+ }
+
+ /*
+ * Number, range, or mistake, pick it apart and figure out which.
+ */
+ i1 = strspn(val->value, "0123456789");
+ if (val->value[i1] == '\0') {
+ is_range = 0;
+ } else {
+ is_range = 1;
+ i2 = i1 + strspn(val->value + i1, " \t");
+ if (val->value[i2] != '-') {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASNUMBER);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ i2++;
+ i2 = i2 + strspn(val->value + i2, " \t");
+ i3 = i2 + strspn(val->value + i2, "0123456789");
+ if (val->value[i3] != '\0') {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASRANGE);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ }
+
+ /*
+ * Syntax is ok, read and add it.
+ */
+ if (!is_range) {
+ if (!X509V3_get_value_int(val, &min)) {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ } else {
+ char *s = BUF_strdup(val->value);
+ if (s == NULL) {
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ s[i1] = '\0';
+ min = s2i_ASN1_INTEGER(NULL, s);
+ max = s2i_ASN1_INTEGER(NULL, s + i2);
+ OPENSSL_free(s);
+ if (min == NULL || max == NULL) {
+ ASN1_INTEGER_free(min);
+ ASN1_INTEGER_free(max);
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ if (!v3_asid_add_id_or_range(asid, which, min, max)) {
+ ASN1_INTEGER_free(min);
+ ASN1_INTEGER_free(max);
+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ /*
+ * Canonize the result, then we're done.
+ */
+ if (!v3_asid_canonize(asid))
+ goto err;
+ return asid;
+
+ err:
+ ASIdentifiers_free(asid);
+ return NULL;
+}
+
+/*
+ * OpenSSL dispatch.
+ */
+const X509V3_EXT_METHOD v3_asid = {
+ NID_sbgp_autonomousSysNum, /* nid */
+ 0, /* flags */
+ ASN1_ITEM_ref(ASIdentifiers), /* template */
+ 0, 0, 0, 0, /* old functions, ignored */
+ 0, /* i2s */
+ 0, /* s2i */
+ 0, /* i2v */
+ v2i_ASIdentifiers, /* v2i */
+ i2r_ASIdentifiers, /* i2r */
+ 0, /* r2i */
+ NULL /* extension-specific data */
+};
+
+/*
+ * Figure out whether extension uses inheritance.
+ */
+int v3_asid_inherits(ASIdentifiers *asid)
+{
+ return (asid != NULL &&
+ ((asid->asnum != NULL &&
+ asid->asnum->type == ASIdentifierChoice_inherit) ||
+ (asid->rdi != NULL &&
+ asid->rdi->type == ASIdentifierChoice_inherit)));
+}
+
+/*
+ * Figure out whether parent contains child.
+ */
+static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child)
+{
+ ASN1_INTEGER *p_min, *p_max, *c_min, *c_max;
+ int p, c;
+
+ if (child == NULL || parent == child)
+ return 1;
+ if (parent == NULL)
+ return 0;
+
+ p = 0;
+ for (c = 0; c < sk_ASIdOrRange_num(child); c++) {
+ extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max);
+ for (;; p++) {
+ if (p >= sk_ASIdOrRange_num(parent))
+ return 0;
+ extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max);
+ if (ASN1_INTEGER_cmp(p_max, c_max) < 0)
+ continue;
+ if (ASN1_INTEGER_cmp(p_min, c_min) > 0)
+ return 0;
+ break;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Test whether a is a subet of b.
+ */
+int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b)
+{
+ return (a == NULL ||
+ a == b ||
+ (b != NULL &&
+ !v3_asid_inherits(a) &&
+ !v3_asid_inherits(b) &&
+ asid_contains(b->asnum->u.asIdsOrRanges,
+ a->asnum->u.asIdsOrRanges) &&
+ asid_contains(b->rdi->u.asIdsOrRanges,
+ a->rdi->u.asIdsOrRanges)));
+}
+
+/*
+ * Validation error handling via callback.
+ */
+#define validation_err(_err_) \
+ do { \
+ if (ctx != NULL) { \
+ ctx->error = _err_; \
+ ctx->error_depth = i; \
+ ctx->current_cert = x; \
+ ret = ctx->verify_cb(0, ctx); \
+ } else { \
+ ret = 0; \
+ } \
+ if (!ret) \
+ goto done; \
+ } while (0)
+
+/*
+ * Core code for RFC 3779 3.3 path validation.
+ */
+static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx,
+ STACK_OF(X509) *chain,
+ ASIdentifiers *ext)
+{
+ ASIdOrRanges *child_as = NULL, *child_rdi = NULL;
+ int i, ret = 1, inherit_as = 0, inherit_rdi = 0;
+ X509 *x;
+
+ OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
+ OPENSSL_assert(ctx != NULL || ext != NULL);
+ OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
+
+ /*
+ * Figure out where to start. If we don't have an extension to
+ * check, we're done. Otherwise, check canonical form and
+ * set up for walking up the chain.
+ */
+ if (ext != NULL) {
+ i = -1;
+ x = NULL;
+ } else {
+ i = 0;
+ x = sk_X509_value(chain, i);
+ OPENSSL_assert(x != NULL);
+ if ((ext = x->rfc3779_asid) == NULL)
+ goto done;
+ }
+ if (!v3_asid_is_canonical(ext))
+ validation_err(X509_V_ERR_INVALID_EXTENSION);
+ if (ext->asnum != NULL) {
+ switch (ext->asnum->type) {
+ case ASIdentifierChoice_inherit:
+ inherit_as = 1;
+ break;
+ case ASIdentifierChoice_asIdsOrRanges:
+ child_as = ext->asnum->u.asIdsOrRanges;
+ break;
+ }
+ }
+ if (ext->rdi != NULL) {
+ switch (ext->rdi->type) {
+ case ASIdentifierChoice_inherit:
+ inherit_rdi = 1;
+ break;
+ case ASIdentifierChoice_asIdsOrRanges:
+ child_rdi = ext->rdi->u.asIdsOrRanges;
+ break;
+ }
+ }
+
+ /*
+ * Now walk up the chain. Extensions must be in canonical form, no
+ * cert may list resources that its parent doesn't list.
+ */
+ for (i++; i < sk_X509_num(chain); i++) {
+ x = sk_X509_value(chain, i);
+ OPENSSL_assert(x != NULL);
+ if (x->rfc3779_asid == NULL) {
+ if (child_as != NULL || child_rdi != NULL)
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ continue;
+ }
+ if (!v3_asid_is_canonical(x->rfc3779_asid))
+ validation_err(X509_V_ERR_INVALID_EXTENSION);
+ if (x->rfc3779_asid->asnum == NULL && child_as != NULL) {
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ child_as = NULL;
+ inherit_as = 0;
+ }
+ if (x->rfc3779_asid->asnum != NULL &&
+ x->rfc3779_asid->asnum->type == ASIdentifierChoice_asIdsOrRanges) {
+ if (inherit_as ||
+ asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, child_as)) {
+ child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges;
+ inherit_as = 0;
+ } else {
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ }
+ }
+ if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) {
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ child_rdi = NULL;
+ inherit_rdi = 0;
+ }
+ if (x->rfc3779_asid->rdi != NULL &&
+ x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) {
+ if (inherit_rdi ||
+ asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, child_rdi)) {
+ child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges;
+ inherit_rdi = 0;
+ } else {
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ }
+ }
+ }
+
+ /*
+ * Trust anchor can't inherit.
+ */
+ OPENSSL_assert(x != NULL);
+ if (x->rfc3779_asid != NULL) {
+ if (x->rfc3779_asid->asnum != NULL &&
+ x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit)
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ if (x->rfc3779_asid->rdi != NULL &&
+ x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit)
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ }
+
+ done:
+ return ret;
+}
+
+#undef validation_err
+
+/*
+ * RFC 3779 3.3 path validation -- called from X509_verify_cert().
+ */
+int v3_asid_validate_path(X509_STORE_CTX *ctx)
+{
+ return v3_asid_validate_path_internal(ctx, ctx->chain, NULL);
+}
+
+/*
+ * RFC 3779 3.3 path validation of an extension.
+ * Test whether chain covers extension.
+ */
+int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
+ ASIdentifiers *ext,
+ int allow_inheritance)
+{
+ if (ext == NULL)
+ return 1;
+ if (chain == NULL || sk_X509_num(chain) == 0)
+ return 0;
+ if (!allow_inheritance && v3_asid_inherits(ext))
+ return 0;
+ return v3_asid_validate_path_internal(NULL, chain, ext);
+}
+
+#endif /* OPENSSL_NO_RFC3779 */
diff --git a/openssl/engines/e_capi.c b/openssl/engines/e_capi.c
index 5c1fbeff3..24b620fc0 100644
--- a/openssl/engines/e_capi.c
+++ b/openssl/engines/e_capi.c
@@ -1,1824 +1,1824 @@
-/* engines/e_capi.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project.
- */
-/* ====================================================================
- * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- */
-
-
-#include <stdio.h>
-#include <string.h>
-#include <openssl/crypto.h>
-#include <openssl/buffer.h>
-#include <openssl/bn.h>
-
-#ifdef OPENSSL_SYS_WIN32
-#ifndef OPENSSL_NO_CAPIENG
-
-#include <openssl/rsa.h>
-
-#include <windows.h>
-
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0400
-#endif
-
-#include <wincrypt.h>
-
-/*
- * This module uses several "new" interfaces, among which is
- * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is
- * one of possible values you can pass to function in question. By
- * checking if it's defined we can see if wincrypt.h and accompanying
- * crypt32.lib are in shape. The native MingW32 headers up to and
- * including __W32API_VERSION 3.14 lack of struct DSSPUBKEY and the
- * defines CERT_STORE_PROV_SYSTEM_A and CERT_STORE_READONLY_FLAG,
- * so we check for these too and avoid compiling.
- * Yes, it's rather "weak" test and if compilation fails,
- * then re-configure with -DOPENSSL_NO_CAPIENG.
- */
-#if defined(CERT_KEY_PROV_INFO_PROP_ID) && \
- defined(CERT_STORE_PROV_SYSTEM_A) && \
- defined(CERT_STORE_READONLY_FLAG)
-# define __COMPILE_CAPIENG
-#endif /* CERT_KEY_PROV_INFO_PROP_ID */
-#endif /* OPENSSL_NO_CAPIENG */
-#endif /* OPENSSL_SYS_WIN32 */
-
-#ifdef __COMPILE_CAPIENG
-
-#undef X509_EXTENSIONS
-#undef X509_CERT_PAIR
-
-/* Definitions which may be missing from earlier version of headers */
-#ifndef CERT_STORE_OPEN_EXISTING_FLAG
-#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000
-#endif
-
-#ifndef CERT_STORE_CREATE_NEW_FLAG
-#define CERT_STORE_CREATE_NEW_FLAG 0x00002000
-#endif
-
-#ifndef CERT_SYSTEM_STORE_CURRENT_USER
-#define CERT_SYSTEM_STORE_CURRENT_USER 0x00010000
-#endif
-
-#include <openssl/engine.h>
-#include <openssl/pem.h>
-#include <openssl/x509v3.h>
-
-#include "e_capi_err.h"
-#include "e_capi_err.c"
-
-
-static const char *engine_capi_id = "capi";
-static const char *engine_capi_name = "CryptoAPI ENGINE";
-
-typedef struct CAPI_CTX_st CAPI_CTX;
-typedef struct CAPI_KEY_st CAPI_KEY;
-
-static void capi_addlasterror(void);
-static void capi_adderror(DWORD err);
-
-static void CAPI_trace(CAPI_CTX *ctx, char *format, ...);
-
-static int capi_list_providers(CAPI_CTX *ctx, BIO *out);
-static int capi_list_containers(CAPI_CTX *ctx, BIO *out);
-int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *storename);
-void capi_free_key(CAPI_KEY *key);
-
-static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore);
-
-CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id);
-
-static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
- UI_METHOD *ui_method, void *callback_data);
-static int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
- unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
-static int capi_rsa_priv_enc(int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa, int padding);
-static int capi_rsa_priv_dec(int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa, int padding);
-static int capi_rsa_free(RSA *rsa);
-
-static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
- DSA *dsa);
-static int capi_dsa_free(DSA *dsa);
-
-static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
- STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
- STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
-
-static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
-#ifdef OPENSSL_CAPIENG_DIALOG
-static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
-#endif
-
-typedef PCCERT_CONTEXT (WINAPI *CERTDLG)(HCERTSTORE, HWND, LPCWSTR,
- LPCWSTR, DWORD, DWORD,
- void *);
-typedef HWND (WINAPI *GETCONSWIN)(void);
-
-/* This structure contains CAPI ENGINE specific data:
- * it contains various global options and affects how
- * other functions behave.
- */
-
-#define CAPI_DBG_TRACE 2
-#define CAPI_DBG_ERROR 1
-
-struct CAPI_CTX_st {
- int debug_level;
- char *debug_file;
- /* Parameters to use for container lookup */
- DWORD keytype;
- LPSTR cspname;
- DWORD csptype;
- /* Certificate store name to use */
- LPSTR storename;
- LPSTR ssl_client_store;
- /* System store flags */
- DWORD store_flags;
-
-/* Lookup string meanings in load_private_key */
-/* Substring of subject: uses "storename" */
-#define CAPI_LU_SUBSTR 1
-/* Friendly name: uses storename */
-#define CAPI_LU_FNAME 2
-/* Container name: uses cspname, keytype */
-#define CAPI_LU_CONTNAME 3
- int lookup_method;
-/* Info to dump with dumpcerts option */
-/* Issuer and serial name strings */
-#define CAPI_DMP_SUMMARY 0x1
-/* Friendly name */
-#define CAPI_DMP_FNAME 0x2
-/* Full X509_print dump */
-#define CAPI_DMP_FULL 0x4
-/* Dump PEM format certificate */
-#define CAPI_DMP_PEM 0x8
-/* Dump pseudo key (if possible) */
-#define CAPI_DMP_PSKEY 0x10
-/* Dump key info (if possible) */
-#define CAPI_DMP_PKEYINFO 0x20
-
- DWORD dump_flags;
- int (*client_cert_select)(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
-
- CERTDLG certselectdlg;
- GETCONSWIN getconswindow;
-};
-
-
-static CAPI_CTX *capi_ctx_new();
-static void capi_ctx_free(CAPI_CTX *ctx);
-static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check);
-static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx);
-
-#define CAPI_CMD_LIST_CERTS ENGINE_CMD_BASE
-#define CAPI_CMD_LOOKUP_CERT (ENGINE_CMD_BASE + 1)
-#define CAPI_CMD_DEBUG_LEVEL (ENGINE_CMD_BASE + 2)
-#define CAPI_CMD_DEBUG_FILE (ENGINE_CMD_BASE + 3)
-#define CAPI_CMD_KEYTYPE (ENGINE_CMD_BASE + 4)
-#define CAPI_CMD_LIST_CSPS (ENGINE_CMD_BASE + 5)
-#define CAPI_CMD_SET_CSP_IDX (ENGINE_CMD_BASE + 6)
-#define CAPI_CMD_SET_CSP_NAME (ENGINE_CMD_BASE + 7)
-#define CAPI_CMD_SET_CSP_TYPE (ENGINE_CMD_BASE + 8)
-#define CAPI_CMD_LIST_CONTAINERS (ENGINE_CMD_BASE + 9)
-#define CAPI_CMD_LIST_OPTIONS (ENGINE_CMD_BASE + 10)
-#define CAPI_CMD_LOOKUP_METHOD (ENGINE_CMD_BASE + 11)
-#define CAPI_CMD_STORE_NAME (ENGINE_CMD_BASE + 12)
-#define CAPI_CMD_STORE_FLAGS (ENGINE_CMD_BASE + 13)
-
-static const ENGINE_CMD_DEFN capi_cmd_defns[] = {
- {CAPI_CMD_LIST_CERTS,
- "list_certs",
- "List all certificates in store",
- ENGINE_CMD_FLAG_NO_INPUT},
- {CAPI_CMD_LOOKUP_CERT,
- "lookup_cert",
- "Lookup and output certificates",
- ENGINE_CMD_FLAG_STRING},
- {CAPI_CMD_DEBUG_LEVEL,
- "debug_level",
- "debug level (1=errors, 2=trace)",
- ENGINE_CMD_FLAG_NUMERIC},
- {CAPI_CMD_DEBUG_FILE,
- "debug_file",
- "debugging filename)",
- ENGINE_CMD_FLAG_STRING},
- {CAPI_CMD_KEYTYPE,
- "key_type",
- "Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE",
- ENGINE_CMD_FLAG_NUMERIC},
- {CAPI_CMD_LIST_CSPS,
- "list_csps",
- "List all CSPs",
- ENGINE_CMD_FLAG_NO_INPUT},
- {CAPI_CMD_SET_CSP_IDX,
- "csp_idx",
- "Set CSP by index",
- ENGINE_CMD_FLAG_NUMERIC},
- {CAPI_CMD_SET_CSP_NAME,
- "csp_name",
- "Set CSP name, (default CSP used if not specified)",
- ENGINE_CMD_FLAG_STRING},
- {CAPI_CMD_SET_CSP_TYPE,
- "csp_type",
- "Set CSP type, (default RSA_PROV_FULL)",
- ENGINE_CMD_FLAG_NUMERIC},
- {CAPI_CMD_LIST_CONTAINERS,
- "list_containers",
- "list container names",
- ENGINE_CMD_FLAG_NO_INPUT},
- {CAPI_CMD_LIST_OPTIONS,
- "list_options",
- "Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, "
- "32=private key info)",
- ENGINE_CMD_FLAG_NUMERIC},
- {CAPI_CMD_LOOKUP_METHOD,
- "lookup_method",
- "Set key lookup method (1=substring, 2=friendlyname, 3=container name)",
- ENGINE_CMD_FLAG_NUMERIC},
- {CAPI_CMD_STORE_NAME,
- "store_name",
- "certificate store name, default \"MY\"",
- ENGINE_CMD_FLAG_STRING},
- {CAPI_CMD_STORE_FLAGS,
- "store_flags",
- "Certificate store flags: 1 = system store",
- ENGINE_CMD_FLAG_NUMERIC},
-
- {0, NULL, NULL, 0}
- };
-
-static int capi_idx = -1;
-static int rsa_capi_idx = -1;
-static int dsa_capi_idx = -1;
-static int cert_capi_idx = -1;
-
-static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
- {
- int ret = 1;
- CAPI_CTX *ctx;
- BIO *out;
- if (capi_idx == -1)
- {
- CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED);
- return 0;
- }
- ctx = ENGINE_get_ex_data(e, capi_idx);
- out = BIO_new_fp(stdout, BIO_NOCLOSE);
- switch (cmd)
- {
- case CAPI_CMD_LIST_CSPS:
- ret = capi_list_providers(ctx, out);
- break;
-
- case CAPI_CMD_LIST_CERTS:
- ret = capi_list_certs(ctx, out, NULL);
- break;
-
- case CAPI_CMD_LOOKUP_CERT:
- ret = capi_list_certs(ctx, out, p);
- break;
-
- case CAPI_CMD_LIST_CONTAINERS:
- ret = capi_list_containers(ctx, out);
- break;
-
- case CAPI_CMD_STORE_NAME:
- if (ctx->storename)
- OPENSSL_free(ctx->storename);
- ctx->storename = BUF_strdup(p);
- CAPI_trace(ctx, "Setting store name to %s\n", p);
- break;
-
- case CAPI_CMD_STORE_FLAGS:
- if (i & 1)
- {
- ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
- ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
- }
- else
- {
- ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER;
- ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE;
- }
- CAPI_trace(ctx, "Setting flags to %d\n", i);
- break;
-
- case CAPI_CMD_DEBUG_LEVEL:
- ctx->debug_level = (int)i;
- CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level);
- break;
-
- case CAPI_CMD_DEBUG_FILE:
- ctx->debug_file = BUF_strdup(p);
- CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file);
- break;
-
- case CAPI_CMD_KEYTYPE:
- ctx->keytype = i;
- CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype);
- break;
-
- case CAPI_CMD_SET_CSP_IDX:
- ret = capi_ctx_set_provname_idx(ctx, i);
- break;
-
- case CAPI_CMD_LIST_OPTIONS:
- ctx->dump_flags = i;
- break;
-
- case CAPI_CMD_LOOKUP_METHOD:
- if (i < 1 || i > 3)
- {
- CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD);
- return 0;
- }
- ctx->lookup_method = i;
- break;
-
- case CAPI_CMD_SET_CSP_NAME:
- ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1);
- break;
-
- case CAPI_CMD_SET_CSP_TYPE:
- ctx->csptype = i;
- break;
-
- default:
- CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND);
- ret = 0;
- }
-
- BIO_free(out);
- return ret;
-
- }
-
-static RSA_METHOD capi_rsa_method =
- {
- "CryptoAPI RSA method",
- 0, /* pub_enc */
- 0, /* pub_dec */
- capi_rsa_priv_enc, /* priv_enc */
- capi_rsa_priv_dec, /* priv_dec */
- 0, /* rsa_mod_exp */
- 0, /* bn_mod_exp */
- 0, /* init */
- capi_rsa_free, /* finish */
- RSA_FLAG_SIGN_VER, /* flags */
- NULL, /* app_data */
- capi_rsa_sign, /* rsa_sign */
- 0 /* rsa_verify */
- };
-
-static DSA_METHOD capi_dsa_method =
- {
- "CryptoAPI DSA method",
- capi_dsa_do_sign, /* dsa_do_sign */
- 0, /* dsa_sign_setup */
- 0, /* dsa_do_verify */
- 0, /* dsa_mod_exp */
- 0, /* bn_mod_exp */
- 0, /* init */
- capi_dsa_free, /* finish */
- 0, /* flags */
- NULL, /* app_data */
- 0, /* dsa_paramgen */
- 0 /* dsa_keygen */
- };
-
-static int capi_init(ENGINE *e)
- {
- CAPI_CTX *ctx;
- const RSA_METHOD *ossl_rsa_meth;
- const DSA_METHOD *ossl_dsa_meth;
- capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0);
- cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0);
-
- ctx = capi_ctx_new();
- if (!ctx || (capi_idx < 0))
- goto memerr;
-
- ENGINE_set_ex_data(e, capi_idx, ctx);
- /* Setup RSA_METHOD */
- rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
- ossl_rsa_meth = RSA_PKCS1_SSLeay();
- capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc;
- capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec;
- capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp;
- capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp;
-
- /* Setup DSA Method */
- dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
- ossl_dsa_meth = DSA_OpenSSL();
- capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify;
- capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp;
- capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp;
-
-#ifdef OPENSSL_CAPIENG_DIALOG
- {
- HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL"));
- HMODULE kernel = GetModuleHandle(TEXT("KERNEL32.DLL"));
- if (cryptui)
- ctx->certselectdlg = (CERTDLG)GetProcAddress(cryptui, "CryptUIDlgSelectCertificateFromStore");
- if (kernel)
- ctx->getconswindow = (GETCONSWIN)GetProcAddress(kernel, "GetConsoleWindow");
- if (cryptui && !OPENSSL_isservice())
- ctx->client_cert_select = cert_select_dialog;
- }
-#endif
-
-
- return 1;
-
- memerr:
- CAPIerr(CAPI_F_CAPI_INIT, ERR_R_MALLOC_FAILURE);
- return 0;
-
- return 1;
- }
-
-static int capi_destroy(ENGINE *e)
- {
- ERR_unload_CAPI_strings();
- return 1;
- }
-
-static int capi_finish(ENGINE *e)
- {
- CAPI_CTX *ctx;
- ctx = ENGINE_get_ex_data(e, capi_idx);
- capi_ctx_free(ctx);
- ENGINE_set_ex_data(e, capi_idx, NULL);
- return 1;
- }
-
-
-/* CryptoAPI key application data. This contains
- * a handle to the private key container (for sign operations)
- * and a handle to the key (for decrypt operations).
- */
-
-struct CAPI_KEY_st
- {
- /* Associated certificate context (if any) */
- PCCERT_CONTEXT pcert;
- HCRYPTPROV hprov;
- HCRYPTKEY key;
- DWORD keyspec;
- };
-
-static int bind_capi(ENGINE *e)
- {
- if (!ENGINE_set_id(e, engine_capi_id)
- || !ENGINE_set_name(e, engine_capi_name)
- || !ENGINE_set_init_function(e, capi_init)
- || !ENGINE_set_finish_function(e, capi_finish)
- || !ENGINE_set_destroy_function(e, capi_destroy)
- || !ENGINE_set_RSA(e, &capi_rsa_method)
- || !ENGINE_set_DSA(e, &capi_dsa_method)
- || !ENGINE_set_load_privkey_function(e, capi_load_privkey)
- || !ENGINE_set_load_ssl_client_cert_function(e,
- capi_load_ssl_client_cert)
- || !ENGINE_set_cmd_defns(e, capi_cmd_defns)
- || !ENGINE_set_ctrl_function(e, capi_ctrl))
- return 0;
- ERR_load_CAPI_strings();
-
- return 1;
-
- }
-
-#ifndef OPENSSL_NO_DYNAMIC_ENGINE
-static int bind_helper(ENGINE *e, const char *id)
- {
- if(id && (strcmp(id, engine_capi_id) != 0))
- return 0;
- if(!bind_capi(e))
- return 0;
- return 1;
- }
-IMPLEMENT_DYNAMIC_CHECK_FN()
-IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
-#else
-static ENGINE *engine_capi(void)
- {
- ENGINE *ret = ENGINE_new();
- if(!ret)
- return NULL;
- if(!bind_capi(ret))
- {
- ENGINE_free(ret);
- return NULL;
- }
- return ret;
- }
-
-void ENGINE_load_capi(void)
- {
- /* Copied from eng_[openssl|dyn].c */
- ENGINE *toadd = engine_capi();
- if(!toadd) return;
- ENGINE_add(toadd);
- ENGINE_free(toadd);
- ERR_clear_error();
- }
-#endif
-
-
-static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen)
- {
- int i;
- /* Reverse buffer in place: since this is a keyblob structure
- * that will be freed up after conversion anyway it doesn't
- * matter if we change it.
- */
- for(i = 0; i < binlen / 2; i++)
- {
- unsigned char c;
- c = bin[i];
- bin[i] = bin[binlen - i - 1];
- bin[binlen - i - 1] = c;
- }
-
- if (!BN_bin2bn(bin, binlen, bn))
- return 0;
- return 1;
- }
-
-/* Given a CAPI_KEY get an EVP_PKEY structure */
-
-static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY *key)
- {
- unsigned char *pubkey = NULL;
- DWORD len;
- BLOBHEADER *bh;
- RSA *rkey = NULL;
- DSA *dkey = NULL;
- EVP_PKEY *ret = NULL;
- if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len))
- {
- CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR);
- capi_addlasterror();
- return NULL;
- }
-
- pubkey = OPENSSL_malloc(len);
-
- if (!pubkey)
- goto memerr;
-
- if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len))
- {
- CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR);
- capi_addlasterror();
- goto err;
- }
-
- bh = (BLOBHEADER *)pubkey;
- if (bh->bType != PUBLICKEYBLOB)
- {
- CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB);
- goto err;
- }
- if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX)
- {
- RSAPUBKEY *rp;
- DWORD rsa_modlen;
- unsigned char *rsa_modulus;
- rp = (RSAPUBKEY *)(bh + 1);
- if (rp->magic != 0x31415352)
- {
- char magstr[10];
- BIO_snprintf(magstr, 10, "%lx", rp->magic);
- CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
- ERR_add_error_data(2, "magic=0x", magstr);
- goto err;
- }
- rsa_modulus = (unsigned char *)(rp + 1);
- rkey = RSA_new_method(eng);
- if (!rkey)
- goto memerr;
-
- rkey->e = BN_new();
- rkey->n = BN_new();
-
- if (!rkey->e || !rkey->n)
- goto memerr;
-
- if (!BN_set_word(rkey->e, rp->pubexp))
- goto memerr;
-
- rsa_modlen = rp->bitlen / 8;
- if (!lend_tobn(rkey->n, rsa_modulus, rsa_modlen))
- goto memerr;
-
- RSA_set_ex_data(rkey, rsa_capi_idx, key);
-
- if (!(ret = EVP_PKEY_new()))
- goto memerr;
-
- EVP_PKEY_assign_RSA(ret, rkey);
- rkey = NULL;
-
- }
- else if (bh->aiKeyAlg == CALG_DSS_SIGN)
- {
- DSSPUBKEY *dp;
- DWORD dsa_plen;
- unsigned char *btmp;
- dp = (DSSPUBKEY *)(bh + 1);
- if (dp->magic != 0x31535344)
- {
- char magstr[10];
- BIO_snprintf(magstr, 10, "%lx", dp->magic);
- CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
- ERR_add_error_data(2, "magic=0x", magstr);
- goto err;
- }
- dsa_plen = dp->bitlen / 8;
- btmp = (unsigned char *)(dp + 1);
- dkey = DSA_new_method(eng);
- if (!dkey)
- goto memerr;
- dkey->p = BN_new();
- dkey->q = BN_new();
- dkey->g = BN_new();
- dkey->pub_key = BN_new();
- if (!dkey->p || !dkey->q || !dkey->g || !dkey->pub_key)
- goto memerr;
- if (!lend_tobn(dkey->p, btmp, dsa_plen))
- goto memerr;
- btmp += dsa_plen;
- if (!lend_tobn(dkey->q, btmp, 20))
- goto memerr;
- btmp += 20;
- if (!lend_tobn(dkey->g, btmp, dsa_plen))
- goto memerr;
- btmp += dsa_plen;
- if (!lend_tobn(dkey->pub_key, btmp, dsa_plen))
- goto memerr;
- btmp += dsa_plen;
-
- DSA_set_ex_data(dkey, dsa_capi_idx, key);
-
- if (!(ret = EVP_PKEY_new()))
- goto memerr;
-
- EVP_PKEY_assign_DSA(ret, dkey);
- dkey = NULL;
- }
- else
- {
- char algstr[10];
- BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg);
- CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM);
- ERR_add_error_data(2, "aiKeyAlg=0x", algstr);
- goto err;
- }
-
-
- err:
- if (pubkey)
- OPENSSL_free(pubkey);
- if (!ret)
- {
- if (rkey)
- RSA_free(rkey);
- if (dkey)
- DSA_free(dkey);
- }
-
- return ret;
-
-memerr:
- CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE);
- goto err;
-
- }
-
-static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
- UI_METHOD *ui_method, void *callback_data)
- {
- CAPI_CTX *ctx;
- CAPI_KEY *key;
- EVP_PKEY *ret;
- ctx = ENGINE_get_ex_data(eng, capi_idx);
-
- if (!ctx)
- {
- CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT);
- return NULL;
- }
-
- key = capi_find_key(ctx, key_id);
-
- if (!key)
- return NULL;
-
- ret = capi_get_pkey(eng, key);
-
- if (!ret)
- capi_free_key(key);
- return ret;
-
- }
-
-/* CryptoAPI RSA operations */
-
-int capi_rsa_priv_enc(int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa, int padding)
- {
- CAPIerr(CAPI_F_CAPI_RSA_PRIV_ENC, CAPI_R_FUNCTION_NOT_SUPPORTED);
- return -1;
- }
-
-int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
- unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
- {
- ALG_ID alg;
- HCRYPTHASH hash;
- DWORD slen;
- unsigned int i;
- int ret = -1;
- CAPI_KEY *capi_key;
- CAPI_CTX *ctx;
-
- ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);
-
- CAPI_trace(ctx, "Called CAPI_rsa_sign()\n");
-
- capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
- if (!capi_key)
- {
- CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY);
- return -1;
- }
-/* Convert the signature type to a CryptoAPI algorithm ID */
- switch(dtype)
- {
- case NID_sha1:
- alg = CALG_SHA1;
- break;
-
- case NID_md5:
- alg = CALG_MD5;
- break;
-
- case NID_md5_sha1:
- alg = CALG_SSL3_SHAMD5;
- break;
- default:
- {
- char algstr[10];
- BIO_snprintf(algstr, 10, "%lx", dtype);
- CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID);
- ERR_add_error_data(2, "NID=0x", algstr);
- return -1;
- }
- }
-
-
-
-/* Create the hash object */
- if(!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash))
- {
- CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
- capi_addlasterror();
- return -1;
- }
-/* Set the hash value to the value passed */
-
- if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0))
- {
- CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
- capi_addlasterror();
- goto err;
- }
-
-
-/* Finally sign it */
- slen = RSA_size(rsa);
- if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, sigret, &slen))
- {
- CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH);
- capi_addlasterror();
- goto err;
- }
- else
- {
- ret = 1;
- /* Inplace byte reversal of signature */
- for(i = 0; i < slen / 2; i++)
- {
- unsigned char c;
- c = sigret[i];
- sigret[i] = sigret[slen - i - 1];
- sigret[slen - i - 1] = c;
- }
- *siglen = slen;
- }
-
- /* Now cleanup */
-
-err:
- CryptDestroyHash(hash);
-
- return ret;
- }
-
-int capi_rsa_priv_dec(int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa, int padding)
- {
- int i;
- unsigned char *tmpbuf;
- CAPI_KEY *capi_key;
- CAPI_CTX *ctx;
- ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);
-
- CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n");
-
-
- capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
- if (!capi_key)
- {
- CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY);
- return -1;
- }
-
- if(padding != RSA_PKCS1_PADDING)
- {
- char errstr[10];
- BIO_snprintf(errstr, 10, "%d", padding);
- CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING);
- ERR_add_error_data(2, "padding=", errstr);
- return -1;
- }
-
- /* Create temp reverse order version of input */
- if(!(tmpbuf = OPENSSL_malloc(flen)) )
- {
- CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- for(i = 0; i < flen; i++)
- tmpbuf[flen - i - 1] = from[i];
-
- /* Finally decrypt it */
- if(!CryptDecrypt(capi_key->key, 0, TRUE, 0, tmpbuf, &flen))
- {
- CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR);
- capi_addlasterror();
- OPENSSL_free(tmpbuf);
- return -1;
- }
- else memcpy(to, tmpbuf, flen);
-
- OPENSSL_free(tmpbuf);
-
- return flen;
- }
-
-static int capi_rsa_free(RSA *rsa)
- {
- CAPI_KEY *capi_key;
- capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
- capi_free_key(capi_key);
- RSA_set_ex_data(rsa, rsa_capi_idx, 0);
- return 1;
- }
-
-/* CryptoAPI DSA operations */
-
-static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
- DSA *dsa)
- {
- HCRYPTHASH hash;
- DWORD slen;
- DSA_SIG *ret = NULL;
- CAPI_KEY *capi_key;
- CAPI_CTX *ctx;
- unsigned char csigbuf[40];
-
- ctx = ENGINE_get_ex_data(dsa->engine, capi_idx);
-
- CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n");
-
- capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
-
- if (!capi_key)
- {
- CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY);
- return NULL;
- }
-
- if (dlen != 20)
- {
- CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH);
- return NULL;
- }
-
- /* Create the hash object */
- if(!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash))
- {
- CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
- capi_addlasterror();
- return NULL;
- }
-
- /* Set the hash value to the value passed */
- if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0))
- {
- CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
- capi_addlasterror();
- goto err;
- }
-
-
- /* Finally sign it */
- slen = sizeof(csigbuf);
- if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen))
- {
- CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH);
- capi_addlasterror();
- goto err;
- }
- else
- {
- ret = DSA_SIG_new();
- if (!ret)
- goto err;
- ret->r = BN_new();
- ret->s = BN_new();
- if (!ret->r || !ret->s)
- goto err;
- if (!lend_tobn(ret->r, csigbuf, 20)
- || !lend_tobn(ret->s, csigbuf + 20, 20))
- {
- DSA_SIG_free(ret);
- ret = NULL;
- goto err;
- }
- }
-
- /* Now cleanup */
-
-err:
- OPENSSL_cleanse(csigbuf, 40);
- CryptDestroyHash(hash);
- return ret;
- }
-
-static int capi_dsa_free(DSA *dsa)
- {
- CAPI_KEY *capi_key;
- capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
- capi_free_key(capi_key);
- DSA_set_ex_data(dsa, dsa_capi_idx, 0);
- return 1;
- }
-
-static void capi_vtrace(CAPI_CTX *ctx, int level, char *format, va_list argptr)
- {
- BIO *out;
-
- if (!ctx || (ctx->debug_level < level) || (!ctx->debug_file))
- return;
- out = BIO_new_file(ctx->debug_file, "a+");
- BIO_vprintf(out, format, argptr);
- BIO_free(out);
- }
-
-static void CAPI_trace(CAPI_CTX *ctx, char *format, ...)
- {
- va_list args;
- va_start(args, format);
- capi_vtrace(ctx, CAPI_DBG_TRACE, format, args);
- va_end(args);
- }
-
-static void capi_addlasterror(void)
- {
- capi_adderror(GetLastError());
- }
-
-static void capi_adderror(DWORD err)
- {
- char errstr[10];
- BIO_snprintf(errstr, 10, "%lX", err);
- ERR_add_error_data(2, "Error code= 0x", errstr);
- }
-
-static char *wide_to_asc(LPWSTR wstr)
- {
- char *str;
- int len_0,sz;
-
- if (!wstr)
- return NULL;
- len_0 = (int)wcslen(wstr)+1; /* WideCharToMultiByte expects int */
- sz = WideCharToMultiByte(CP_ACP,0,wstr,len_0,NULL,0,NULL,NULL);
- if (!sz)
- {
- CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
- return NULL;
- }
- str = OPENSSL_malloc(sz);
- if (!str)
- {
- CAPIerr(CAPI_F_WIDE_TO_ASC, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- if (!WideCharToMultiByte(CP_ACP,0,wstr,len_0,str,sz,NULL,NULL))
- {
- OPENSSL_free(str);
- CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
- return NULL;
- }
- return str;
- }
-
-static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD idx)
- {
- LPSTR name;
- DWORD len, err;
- CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx);
- if (!CryptEnumProvidersA(idx, NULL, 0, ptype, NULL, &len))
- {
- err = GetLastError();
- if (err == ERROR_NO_MORE_ITEMS)
- return 2;
- CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
- capi_adderror(err);
- return 0;
- }
- name = OPENSSL_malloc(len);
- if (!CryptEnumProvidersA(idx, NULL, 0, ptype, name, &len))
- {
- err = GetLastError();
- if (err == ERROR_NO_MORE_ITEMS)
- return 2;
- CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
- capi_adderror(err);
- return 0;
- }
- *pname = name;
- CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", name, *ptype);
-
- return 1;
- }
-
-static int capi_list_providers(CAPI_CTX *ctx, BIO *out)
- {
- DWORD idx, ptype;
- int ret;
- LPSTR provname = NULL;
- CAPI_trace(ctx, "capi_list_providers\n");
- BIO_printf(out, "Available CSPs:\n");
- for(idx = 0; ; idx++)
- {
- ret = capi_get_provname(ctx, &provname, &ptype, idx);
- if (ret == 2)
- break;
- if (ret == 0)
- break;
- BIO_printf(out, "%d. %s, type %d\n", idx, provname, ptype);
- OPENSSL_free(provname);
- }
- return 1;
- }
-
-static int capi_list_containers(CAPI_CTX *ctx, BIO *out)
- {
- int ret = 1;
- HCRYPTPROV hprov;
- DWORD err, idx, flags, buflen = 0, clen;
- LPSTR cname;
- CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, ctx->csptype);
- if (!CryptAcquireContextA(&hprov, NULL, ctx->cspname, ctx->csptype, CRYPT_VERIFYCONTEXT))
- {
- CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
- capi_addlasterror();
- return 0;
- }
- if (!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, NULL, &buflen, CRYPT_FIRST))
- {
- CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
- capi_addlasterror();
- return 0;
- }
- CAPI_trace(ctx, "Got max container len %d\n", buflen);
- if (buflen == 0)
- buflen = 1024;
- cname = OPENSSL_malloc(buflen);
- if (!cname)
- {
- CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- for (idx = 0;;idx++)
- {
- clen = buflen;
- cname[0] = 0;
-
- if (idx == 0)
- flags = CRYPT_FIRST;
- else
- flags = 0;
- if(!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, cname, &clen, flags))
- {
- err = GetLastError();
- if (err == ERROR_NO_MORE_ITEMS)
- goto done;
- CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
- capi_adderror(err);
- goto err;
- }
- CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n", cname, clen, idx, flags);
- if (!cname[0] && (clen == buflen))
- {
- CAPI_trace(ctx, "Enumerate bug: using workaround\n");
- goto done;
- }
- BIO_printf(out, "%d. %s\n", idx, cname);
- }
- err:
-
- ret = 0;
-
- done:
- if (cname)
- OPENSSL_free(cname);
- CryptReleaseContext(hprov, 0);
-
- return ret;
- }
-
-CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
- {
- DWORD len;
- CRYPT_KEY_PROV_INFO *pinfo;
-
- if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len))
- return NULL;
- pinfo = OPENSSL_malloc(len);
- if (!pinfo)
- {
- CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len))
- {
- CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO);
- capi_addlasterror();
- OPENSSL_free(pinfo);
- return NULL;
- }
- return pinfo;
- }
-
-static void capi_dump_prov_info(CAPI_CTX *ctx, BIO *out, CRYPT_KEY_PROV_INFO *pinfo)
- {
- char *provname = NULL, *contname = NULL;
- if (!pinfo)
- {
- BIO_printf(out, " No Private Key\n");
- return;
- }
- provname = wide_to_asc(pinfo->pwszProvName);
- contname = wide_to_asc(pinfo->pwszContainerName);
- if (!provname || !contname)
- goto err;
-
- BIO_printf(out, " Private Key Info:\n");
- BIO_printf(out, " Provider Name: %s, Provider Type %d\n", provname, pinfo->dwProvType);
- BIO_printf(out, " Container Name: %s, Key Type %d\n", contname, pinfo->dwKeySpec);
- err:
- if (provname)
- OPENSSL_free(provname);
- if (contname)
- OPENSSL_free(contname);
- }
-
-char * capi_cert_get_fname(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
- {
- LPWSTR wfname;
- DWORD dlen;
-
- CAPI_trace(ctx, "capi_cert_get_fname\n");
- if (!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen))
- return NULL;
- wfname = OPENSSL_malloc(dlen);
- if (CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen))
- {
- char *fname = wide_to_asc(wfname);
- OPENSSL_free(wfname);
- return fname;
- }
- CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME);
- capi_addlasterror();
-
- OPENSSL_free(wfname);
- return NULL;
- }
-
-
-void capi_dump_cert(CAPI_CTX *ctx, BIO *out, PCCERT_CONTEXT cert)
- {
- X509 *x;
- unsigned char *p;
- unsigned long flags = ctx->dump_flags;
- if (flags & CAPI_DMP_FNAME)
- {
- char *fname;
- fname = capi_cert_get_fname(ctx, cert);
- if (fname)
- {
- BIO_printf(out, " Friendly Name \"%s\"\n", fname);
- OPENSSL_free(fname);
- }
- else
- BIO_printf(out, " <No Friendly Name>\n");
- }
-
- p = cert->pbCertEncoded;
- x = d2i_X509(NULL, &p, cert->cbCertEncoded);
- if (!x)
- BIO_printf(out, " <Can't parse certificate>\n");
- if (flags & CAPI_DMP_SUMMARY)
- {
- BIO_printf(out, " Subject: ");
- X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
- BIO_printf(out, "\n Issuer: ");
- X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
- BIO_printf(out, "\n");
- }
- if (flags & CAPI_DMP_FULL)
- X509_print_ex(out, x, XN_FLAG_ONELINE,0);
-
- if (flags & CAPI_DMP_PKEYINFO)
- {
- CRYPT_KEY_PROV_INFO *pinfo;
- pinfo = capi_get_prov_info(ctx, cert);
- capi_dump_prov_info(ctx, out, pinfo);
- if (pinfo)
- OPENSSL_free(pinfo);
- }
-
- if (flags & CAPI_DMP_PEM)
- PEM_write_bio_X509(out, x);
- X509_free(x);
- }
-
-HCERTSTORE capi_open_store(CAPI_CTX *ctx, char *storename)
- {
- HCERTSTORE hstore;
-
- if (!storename)
- storename = ctx->storename;
- if (!storename)
- storename = "MY";
- CAPI_trace(ctx, "Opening certificate store %s\n", storename);
-
- hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0,
- ctx->store_flags, storename);
- if (!hstore)
- {
- CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE);
- capi_addlasterror();
- }
- return hstore;
- }
-
-int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *id)
- {
- char *storename;
- int idx;
- int ret = 1;
- HCERTSTORE hstore;
- PCCERT_CONTEXT cert = NULL;
-
- storename = ctx->storename;
- if (!storename)
- storename = "MY";
- CAPI_trace(ctx, "Listing certs for store %s\n", storename);
-
- hstore = capi_open_store(ctx, storename);
- if (!hstore)
- return 0;
- if (id)
- {
- cert = capi_find_cert(ctx, id, hstore);
- if (!cert)
- {
- ret = 0;
- goto err;
- }
- capi_dump_cert(ctx, out, cert);
- CertFreeCertificateContext(cert);
- }
- else
- {
- for(idx = 0;;idx++)
- {
- LPWSTR fname = NULL;
- cert = CertEnumCertificatesInStore(hstore, cert);
- if (!cert)
- break;
- BIO_printf(out, "Certificate %d\n", idx);
- capi_dump_cert(ctx, out, cert);
- }
- }
- err:
- CertCloseStore(hstore, 0);
- return ret;
- }
-
-static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore)
- {
- PCCERT_CONTEXT cert = NULL;
- char *fname = NULL;
- int match;
- switch(ctx->lookup_method)
- {
- case CAPI_LU_SUBSTR:
- return CertFindCertificateInStore(hstore,
- X509_ASN_ENCODING, 0,
- CERT_FIND_SUBJECT_STR_A, id, NULL);
- case CAPI_LU_FNAME:
- for(;;)
- {
- cert = CertEnumCertificatesInStore(hstore, cert);
- if (!cert)
- return NULL;
- fname = capi_cert_get_fname(ctx, cert);
- if (fname)
- {
- if (strcmp(fname, id))
- match = 0;
- else
- match = 1;
- OPENSSL_free(fname);
- if (match)
- return cert;
- }
- }
- default:
- return NULL;
- }
- }
-
-static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provname, DWORD ptype, DWORD keyspec)
- {
- CAPI_KEY *key;
- key = OPENSSL_malloc(sizeof(CAPI_KEY));
- CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n",
- contname, provname, ptype);
- if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, 0))
- {
- CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
- capi_addlasterror();
- goto err;
- }
- if (!CryptGetUserKey(key->hprov, keyspec, &key->key))
- {
- CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR);
- capi_addlasterror();
- CryptReleaseContext(key->hprov, 0);
- goto err;
- }
- key->keyspec = keyspec;
- key->pcert = NULL;
- return key;
-
- err:
- OPENSSL_free(key);
- return NULL;
- }
-
-static CAPI_KEY *capi_get_cert_key(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
- {
- CAPI_KEY *key = NULL;
- CRYPT_KEY_PROV_INFO *pinfo = NULL;
- char *provname = NULL, *contname = NULL;
- pinfo = capi_get_prov_info(ctx, cert);
- if (!pinfo)
- goto err;
- provname = wide_to_asc(pinfo->pwszProvName);
- contname = wide_to_asc(pinfo->pwszContainerName);
- if (!provname || !contname)
- goto err;
- key = capi_get_key(ctx, contname, provname,
- pinfo->dwProvType, pinfo->dwKeySpec);
-
- err:
- if (pinfo)
- OPENSSL_free(pinfo);
- if (provname)
- OPENSSL_free(provname);
- if (contname)
- OPENSSL_free(contname);
- return key;
- }
-
-CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id)
- {
- PCCERT_CONTEXT cert;
- HCERTSTORE hstore;
- CAPI_KEY *key = NULL;
- switch (ctx->lookup_method)
- {
- case CAPI_LU_SUBSTR:
- case CAPI_LU_FNAME:
- hstore = capi_open_store(ctx, NULL);
- if (!hstore)
- return NULL;
- cert = capi_find_cert(ctx, id, hstore);
- if (cert)
- {
- key = capi_get_cert_key(ctx, cert);
- CertFreeCertificateContext(cert);
- }
- CertCloseStore(hstore, 0);
- break;
-
- case CAPI_LU_CONTNAME:
- key = capi_get_key(ctx, id, ctx->cspname, ctx->csptype,
- ctx->keytype);
- break;
- }
-
- return key;
- }
-
-void capi_free_key(CAPI_KEY *key)
- {
- if (!key)
- return;
- CryptDestroyKey(key->key);
- CryptReleaseContext(key->hprov, 0);
- if (key->pcert)
- CertFreeCertificateContext(key->pcert);
- OPENSSL_free(key);
- }
-
-
-/* Initialize a CAPI_CTX structure */
-
-static CAPI_CTX *capi_ctx_new()
- {
- CAPI_CTX *ctx;
- ctx = OPENSSL_malloc(sizeof(CAPI_CTX));
- if (!ctx)
- {
- CAPIerr(CAPI_F_CAPI_CTX_NEW, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- ctx->cspname = NULL;
- ctx->csptype = PROV_RSA_FULL;
- ctx->dump_flags = CAPI_DMP_SUMMARY|CAPI_DMP_FNAME;
- ctx->keytype = AT_KEYEXCHANGE;
- ctx->storename = NULL;
- ctx->ssl_client_store = NULL;
- ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG |
- CERT_STORE_READONLY_FLAG |
- CERT_SYSTEM_STORE_CURRENT_USER;
- ctx->lookup_method = CAPI_LU_SUBSTR;
- ctx->debug_level = 0;
- ctx->debug_file = NULL;
- ctx->client_cert_select = cert_select_simple;
- return ctx;
- }
-
-static void capi_ctx_free(CAPI_CTX *ctx)
- {
- CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx);
- if (!ctx)
- return;
- if (ctx->cspname)
- OPENSSL_free(ctx->cspname);
- if (ctx->debug_file)
- OPENSSL_free(ctx->debug_file);
- if (ctx->storename)
- OPENSSL_free(ctx->storename);
- if (ctx->ssl_client_store)
- OPENSSL_free(ctx->ssl_client_store);
- OPENSSL_free(ctx);
- }
-
-static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check)
- {
- CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type);
- if (check)
- {
- HCRYPTPROV hprov;
- if (!CryptAcquireContextA(&hprov, NULL, pname, type,
- CRYPT_VERIFYCONTEXT))
- {
- CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
- capi_addlasterror();
- return 0;
- }
- CryptReleaseContext(hprov, 0);
- }
- ctx->cspname = BUF_strdup(pname);
- ctx->csptype = type;
- return 1;
- }
-
-static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx)
- {
- LPSTR pname;
- DWORD type;
- if (capi_get_provname(ctx, &pname, &type, idx) != 1)
- return 0;
- return capi_ctx_set_provname(ctx, pname, type, 0);
- }
-
-static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x)
- {
- int i;
- X509_NAME *nm;
- /* Special case: empty list: match anything */
- if (sk_X509_NAME_num(ca_dn) <= 0)
- return 1;
- for (i = 0; i < sk_X509_NAME_num(ca_dn); i++)
- {
- nm = sk_X509_NAME_value(ca_dn, i);
- if (!X509_NAME_cmp(nm, X509_get_issuer_name(x)))
- return 1;
- }
- return 0;
- }
-
-
-
-static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
- STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
- STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
- {
- STACK_OF(X509) *certs = NULL;
- X509 *x;
- char *storename;
- const char *p;
- int i, client_cert_idx;
- HCERTSTORE hstore;
- PCCERT_CONTEXT cert = NULL, excert = NULL;
- CAPI_CTX *ctx;
- CAPI_KEY *key;
- ctx = ENGINE_get_ex_data(e, capi_idx);
-
- *pcert = NULL;
- *pkey = NULL;
-
- storename = ctx->ssl_client_store;
- if (!storename)
- storename = "MY";
-
- hstore = capi_open_store(ctx, storename);
- if (!hstore)
- return 0;
- /* Enumerate all certificates collect any matches */
- for(i = 0;;i++)
- {
- cert = CertEnumCertificatesInStore(hstore, cert);
- if (!cert)
- break;
- p = cert->pbCertEncoded;
- x = d2i_X509(NULL, &p, cert->cbCertEncoded);
- if (!x)
- {
- CAPI_trace(ctx, "Can't Parse Certificate %d\n", i);
- continue;
- }
- if (cert_issuer_match(ca_dn, x)
- && X509_check_purpose(x, X509_PURPOSE_SSL_CLIENT, 0))
- {
- key = capi_get_cert_key(ctx, cert);
- if (!key)
- {
- X509_free(x);
- continue;
- }
- /* Match found: attach extra data to it so
- * we can retrieve the key later.
- */
- excert = CertDuplicateCertificateContext(cert);
- key->pcert = excert;
- X509_set_ex_data(x, cert_capi_idx, key);
-
- if (!certs)
- certs = sk_X509_new_null();
-
- sk_X509_push(certs, x);
- }
- else
- X509_free(x);
-
- }
-
- if (cert)
- CertFreeCertificateContext(cert);
- if (hstore)
- CertCloseStore(hstore, 0);
-
- if (!certs)
- return 0;
-
-
- /* Select the appropriate certificate */
-
- client_cert_idx = ctx->client_cert_select(e, ssl, certs);
-
- /* Set the selected certificate and free the rest */
-
- for(i = 0; i < sk_X509_num(certs); i++)
- {
- x = sk_X509_value(certs, i);
- if (i == client_cert_idx)
- *pcert = x;
- else
- {
- key = X509_get_ex_data(x, cert_capi_idx);
- capi_free_key(key);
- X509_free(x);
- }
- }
-
- sk_X509_free(certs);
-
- if (!*pcert)
- return 0;
-
- /* Setup key for selected certificate */
-
- key = X509_get_ex_data(*pcert, cert_capi_idx);
- *pkey = capi_get_pkey(e, key);
- X509_set_ex_data(*pcert, cert_capi_idx, NULL);
-
- return 1;
-
- }
-
-
-/* Simple client cert selection function: always select first */
-
-static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
- {
- return 0;
- }
-
-#ifdef OPENSSL_CAPIENG_DIALOG
-
-/* More complex cert selection function, using standard function
- * CryptUIDlgSelectCertificateFromStore() to produce a dialog box.
- */
-
-/* Definitions which are in cryptuiapi.h but this is not present in older
- * versions of headers.
- */
-
-#ifndef CRYPTUI_SELECT_LOCATION_COLUMN
-#define CRYPTUI_SELECT_LOCATION_COLUMN 0x000000010
-#define CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004
-#endif
-
-#define dlg_title L"OpenSSL Application SSL Client Certificate Selection"
-#define dlg_prompt L"Select a certificate to use for authentication"
-#define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \
- |CRYPTUI_SELECT_INTENDEDUSE_COLUMN
-
-static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
- {
- X509 *x;
- HCERTSTORE dstore;
- PCCERT_CONTEXT cert;
- CAPI_CTX *ctx;
- CAPI_KEY *key;
- HWND hwnd;
- int i, idx = -1;
- if (sk_X509_num(certs) == 1)
- return 0;
- ctx = ENGINE_get_ex_data(e, capi_idx);
- /* Create an in memory store of certificates */
- dstore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
- CERT_STORE_CREATE_NEW_FLAG, NULL);
- if (!dstore)
- {
- CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_CREATING_STORE);
- capi_addlasterror();
- goto err;
- }
- /* Add all certificates to store */
- for(i = 0; i < sk_X509_num(certs); i++)
- {
- x = sk_X509_value(certs, i);
- key = X509_get_ex_data(x, cert_capi_idx);
-
- if (!CertAddCertificateContextToStore(dstore, key->pcert,
- CERT_STORE_ADD_NEW, NULL))
- {
- CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_ADDING_CERT);
- capi_addlasterror();
- goto err;
- }
-
- }
- hwnd = GetForegroundWindow();
- if (!hwnd)
- hwnd = GetActiveWindow();
- if (!hwnd && ctx->getconswindow)
- hwnd = ctx->getconswindow();
- /* Call dialog to select one */
- cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt,
- dlg_columns, 0, NULL);
-
- /* Find matching cert from list */
- if (cert)
- {
- for(i = 0; i < sk_X509_num(certs); i++)
- {
- x = sk_X509_value(certs, i);
- key = X509_get_ex_data(x, cert_capi_idx);
- if (CertCompareCertificate(
- X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- cert->pCertInfo,
- key->pcert->pCertInfo))
- {
- idx = i;
- break;
- }
- }
- }
-
- err:
- if (dstore)
- CertCloseStore(dstore, 0);
- return idx;
-
- }
-#endif
-
-#else /* !__COMPILE_CAPIENG */
-#include <openssl/engine.h>
-#ifndef OPENSSL_NO_DYNAMIC_ENGINE
-OPENSSL_EXPORT
-int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
-OPENSSL_EXPORT
-int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
-IMPLEMENT_DYNAMIC_CHECK_FN()
-#else
-void ENGINE_load_capi(void){}
-#endif
-#endif
+/* engines/e_capi.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+
+#ifdef OPENSSL_SYS_WIN32
+#ifndef OPENSSL_NO_CAPIENG
+
+#include <openssl/rsa.h>
+
+#include <windows.h>
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400
+#endif
+
+#include <wincrypt.h>
+
+/*
+ * This module uses several "new" interfaces, among which is
+ * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is
+ * one of possible values you can pass to function in question. By
+ * checking if it's defined we can see if wincrypt.h and accompanying
+ * crypt32.lib are in shape. The native MingW32 headers up to and
+ * including __W32API_VERSION 3.14 lack of struct DSSPUBKEY and the
+ * defines CERT_STORE_PROV_SYSTEM_A and CERT_STORE_READONLY_FLAG,
+ * so we check for these too and avoid compiling.
+ * Yes, it's rather "weak" test and if compilation fails,
+ * then re-configure with -DOPENSSL_NO_CAPIENG.
+ */
+#if defined(CERT_KEY_PROV_INFO_PROP_ID) && \
+ defined(CERT_STORE_PROV_SYSTEM_A) && \
+ defined(CERT_STORE_READONLY_FLAG)
+# define __COMPILE_CAPIENG
+#endif /* CERT_KEY_PROV_INFO_PROP_ID */
+#endif /* OPENSSL_NO_CAPIENG */
+#endif /* OPENSSL_SYS_WIN32 */
+
+#ifdef __COMPILE_CAPIENG
+
+#undef X509_EXTENSIONS
+#undef X509_CERT_PAIR
+
+/* Definitions which may be missing from earlier version of headers */
+#ifndef CERT_STORE_OPEN_EXISTING_FLAG
+#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000
+#endif
+
+#ifndef CERT_STORE_CREATE_NEW_FLAG
+#define CERT_STORE_CREATE_NEW_FLAG 0x00002000
+#endif
+
+#ifndef CERT_SYSTEM_STORE_CURRENT_USER
+#define CERT_SYSTEM_STORE_CURRENT_USER 0x00010000
+#endif
+
+#include <openssl/engine.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+
+#include "e_capi_err.h"
+#include "e_capi_err.c"
+
+
+static const char *engine_capi_id = "capi";
+static const char *engine_capi_name = "CryptoAPI ENGINE";
+
+typedef struct CAPI_CTX_st CAPI_CTX;
+typedef struct CAPI_KEY_st CAPI_KEY;
+
+static void capi_addlasterror(void);
+static void capi_adderror(DWORD err);
+
+static void CAPI_trace(CAPI_CTX *ctx, char *format, ...);
+
+static int capi_list_providers(CAPI_CTX *ctx, BIO *out);
+static int capi_list_containers(CAPI_CTX *ctx, BIO *out);
+int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *storename);
+void capi_free_key(CAPI_KEY *key);
+
+static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore);
+
+CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id);
+
+static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data);
+static int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
+ unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
+static int capi_rsa_priv_enc(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding);
+static int capi_rsa_priv_dec(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding);
+static int capi_rsa_free(RSA *rsa);
+
+static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
+ DSA *dsa);
+static int capi_dsa_free(DSA *dsa);
+
+static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
+ STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
+ STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
+
+static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
+#ifdef OPENSSL_CAPIENG_DIALOG
+static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
+#endif
+
+typedef PCCERT_CONTEXT (WINAPI *CERTDLG)(HCERTSTORE, HWND, LPCWSTR,
+ LPCWSTR, DWORD, DWORD,
+ void *);
+typedef HWND (WINAPI *GETCONSWIN)(void);
+
+/* This structure contains CAPI ENGINE specific data:
+ * it contains various global options and affects how
+ * other functions behave.
+ */
+
+#define CAPI_DBG_TRACE 2
+#define CAPI_DBG_ERROR 1
+
+struct CAPI_CTX_st {
+ int debug_level;
+ char *debug_file;
+ /* Parameters to use for container lookup */
+ DWORD keytype;
+ LPSTR cspname;
+ DWORD csptype;
+ /* Certificate store name to use */
+ LPSTR storename;
+ LPSTR ssl_client_store;
+ /* System store flags */
+ DWORD store_flags;
+
+/* Lookup string meanings in load_private_key */
+/* Substring of subject: uses "storename" */
+#define CAPI_LU_SUBSTR 1
+/* Friendly name: uses storename */
+#define CAPI_LU_FNAME 2
+/* Container name: uses cspname, keytype */
+#define CAPI_LU_CONTNAME 3
+ int lookup_method;
+/* Info to dump with dumpcerts option */
+/* Issuer and serial name strings */
+#define CAPI_DMP_SUMMARY 0x1
+/* Friendly name */
+#define CAPI_DMP_FNAME 0x2
+/* Full X509_print dump */
+#define CAPI_DMP_FULL 0x4
+/* Dump PEM format certificate */
+#define CAPI_DMP_PEM 0x8
+/* Dump pseudo key (if possible) */
+#define CAPI_DMP_PSKEY 0x10
+/* Dump key info (if possible) */
+#define CAPI_DMP_PKEYINFO 0x20
+
+ DWORD dump_flags;
+ int (*client_cert_select)(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
+
+ CERTDLG certselectdlg;
+ GETCONSWIN getconswindow;
+};
+
+
+static CAPI_CTX *capi_ctx_new();
+static void capi_ctx_free(CAPI_CTX *ctx);
+static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check);
+static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx);
+
+#define CAPI_CMD_LIST_CERTS ENGINE_CMD_BASE
+#define CAPI_CMD_LOOKUP_CERT (ENGINE_CMD_BASE + 1)
+#define CAPI_CMD_DEBUG_LEVEL (ENGINE_CMD_BASE + 2)
+#define CAPI_CMD_DEBUG_FILE (ENGINE_CMD_BASE + 3)
+#define CAPI_CMD_KEYTYPE (ENGINE_CMD_BASE + 4)
+#define CAPI_CMD_LIST_CSPS (ENGINE_CMD_BASE + 5)
+#define CAPI_CMD_SET_CSP_IDX (ENGINE_CMD_BASE + 6)
+#define CAPI_CMD_SET_CSP_NAME (ENGINE_CMD_BASE + 7)
+#define CAPI_CMD_SET_CSP_TYPE (ENGINE_CMD_BASE + 8)
+#define CAPI_CMD_LIST_CONTAINERS (ENGINE_CMD_BASE + 9)
+#define CAPI_CMD_LIST_OPTIONS (ENGINE_CMD_BASE + 10)
+#define CAPI_CMD_LOOKUP_METHOD (ENGINE_CMD_BASE + 11)
+#define CAPI_CMD_STORE_NAME (ENGINE_CMD_BASE + 12)
+#define CAPI_CMD_STORE_FLAGS (ENGINE_CMD_BASE + 13)
+
+static const ENGINE_CMD_DEFN capi_cmd_defns[] = {
+ {CAPI_CMD_LIST_CERTS,
+ "list_certs",
+ "List all certificates in store",
+ ENGINE_CMD_FLAG_NO_INPUT},
+ {CAPI_CMD_LOOKUP_CERT,
+ "lookup_cert",
+ "Lookup and output certificates",
+ ENGINE_CMD_FLAG_STRING},
+ {CAPI_CMD_DEBUG_LEVEL,
+ "debug_level",
+ "debug level (1=errors, 2=trace)",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_DEBUG_FILE,
+ "debug_file",
+ "debugging filename)",
+ ENGINE_CMD_FLAG_STRING},
+ {CAPI_CMD_KEYTYPE,
+ "key_type",
+ "Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_LIST_CSPS,
+ "list_csps",
+ "List all CSPs",
+ ENGINE_CMD_FLAG_NO_INPUT},
+ {CAPI_CMD_SET_CSP_IDX,
+ "csp_idx",
+ "Set CSP by index",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_SET_CSP_NAME,
+ "csp_name",
+ "Set CSP name, (default CSP used if not specified)",
+ ENGINE_CMD_FLAG_STRING},
+ {CAPI_CMD_SET_CSP_TYPE,
+ "csp_type",
+ "Set CSP type, (default RSA_PROV_FULL)",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_LIST_CONTAINERS,
+ "list_containers",
+ "list container names",
+ ENGINE_CMD_FLAG_NO_INPUT},
+ {CAPI_CMD_LIST_OPTIONS,
+ "list_options",
+ "Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, "
+ "32=private key info)",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_LOOKUP_METHOD,
+ "lookup_method",
+ "Set key lookup method (1=substring, 2=friendlyname, 3=container name)",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_STORE_NAME,
+ "store_name",
+ "certificate store name, default \"MY\"",
+ ENGINE_CMD_FLAG_STRING},
+ {CAPI_CMD_STORE_FLAGS,
+ "store_flags",
+ "Certificate store flags: 1 = system store",
+ ENGINE_CMD_FLAG_NUMERIC},
+
+ {0, NULL, NULL, 0}
+ };
+
+static int capi_idx = -1;
+static int rsa_capi_idx = -1;
+static int dsa_capi_idx = -1;
+static int cert_capi_idx = -1;
+
+static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+ {
+ int ret = 1;
+ CAPI_CTX *ctx;
+ BIO *out;
+ if (capi_idx == -1)
+ {
+ CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED);
+ return 0;
+ }
+ ctx = ENGINE_get_ex_data(e, capi_idx);
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ switch (cmd)
+ {
+ case CAPI_CMD_LIST_CSPS:
+ ret = capi_list_providers(ctx, out);
+ break;
+
+ case CAPI_CMD_LIST_CERTS:
+ ret = capi_list_certs(ctx, out, NULL);
+ break;
+
+ case CAPI_CMD_LOOKUP_CERT:
+ ret = capi_list_certs(ctx, out, p);
+ break;
+
+ case CAPI_CMD_LIST_CONTAINERS:
+ ret = capi_list_containers(ctx, out);
+ break;
+
+ case CAPI_CMD_STORE_NAME:
+ if (ctx->storename)
+ OPENSSL_free(ctx->storename);
+ ctx->storename = BUF_strdup(p);
+ CAPI_trace(ctx, "Setting store name to %s\n", p);
+ break;
+
+ case CAPI_CMD_STORE_FLAGS:
+ if (i & 1)
+ {
+ ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
+ ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
+ }
+ else
+ {
+ ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER;
+ ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE;
+ }
+ CAPI_trace(ctx, "Setting flags to %d\n", i);
+ break;
+
+ case CAPI_CMD_DEBUG_LEVEL:
+ ctx->debug_level = (int)i;
+ CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level);
+ break;
+
+ case CAPI_CMD_DEBUG_FILE:
+ ctx->debug_file = BUF_strdup(p);
+ CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file);
+ break;
+
+ case CAPI_CMD_KEYTYPE:
+ ctx->keytype = i;
+ CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype);
+ break;
+
+ case CAPI_CMD_SET_CSP_IDX:
+ ret = capi_ctx_set_provname_idx(ctx, i);
+ break;
+
+ case CAPI_CMD_LIST_OPTIONS:
+ ctx->dump_flags = i;
+ break;
+
+ case CAPI_CMD_LOOKUP_METHOD:
+ if (i < 1 || i > 3)
+ {
+ CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD);
+ return 0;
+ }
+ ctx->lookup_method = i;
+ break;
+
+ case CAPI_CMD_SET_CSP_NAME:
+ ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1);
+ break;
+
+ case CAPI_CMD_SET_CSP_TYPE:
+ ctx->csptype = i;
+ break;
+
+ default:
+ CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND);
+ ret = 0;
+ }
+
+ BIO_free(out);
+ return ret;
+
+ }
+
+static RSA_METHOD capi_rsa_method =
+ {
+ "CryptoAPI RSA method",
+ 0, /* pub_enc */
+ 0, /* pub_dec */
+ capi_rsa_priv_enc, /* priv_enc */
+ capi_rsa_priv_dec, /* priv_dec */
+ 0, /* rsa_mod_exp */
+ 0, /* bn_mod_exp */
+ 0, /* init */
+ capi_rsa_free, /* finish */
+ RSA_FLAG_SIGN_VER, /* flags */
+ NULL, /* app_data */
+ capi_rsa_sign, /* rsa_sign */
+ 0 /* rsa_verify */
+ };
+
+static DSA_METHOD capi_dsa_method =
+ {
+ "CryptoAPI DSA method",
+ capi_dsa_do_sign, /* dsa_do_sign */
+ 0, /* dsa_sign_setup */
+ 0, /* dsa_do_verify */
+ 0, /* dsa_mod_exp */
+ 0, /* bn_mod_exp */
+ 0, /* init */
+ capi_dsa_free, /* finish */
+ 0, /* flags */
+ NULL, /* app_data */
+ 0, /* dsa_paramgen */
+ 0 /* dsa_keygen */
+ };
+
+static int capi_init(ENGINE *e)
+ {
+ CAPI_CTX *ctx;
+ const RSA_METHOD *ossl_rsa_meth;
+ const DSA_METHOD *ossl_dsa_meth;
+ capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0);
+
+ ctx = capi_ctx_new();
+ if (!ctx || (capi_idx < 0))
+ goto memerr;
+
+ ENGINE_set_ex_data(e, capi_idx, ctx);
+ /* Setup RSA_METHOD */
+ rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ ossl_rsa_meth = RSA_PKCS1_SSLeay();
+ capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc;
+ capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec;
+ capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp;
+ capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp;
+
+ /* Setup DSA Method */
+ dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ ossl_dsa_meth = DSA_OpenSSL();
+ capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify;
+ capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp;
+ capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp;
+
+#ifdef OPENSSL_CAPIENG_DIALOG
+ {
+ HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL"));
+ HMODULE kernel = GetModuleHandle(TEXT("KERNEL32.DLL"));
+ if (cryptui)
+ ctx->certselectdlg = (CERTDLG)GetProcAddress(cryptui, "CryptUIDlgSelectCertificateFromStore");
+ if (kernel)
+ ctx->getconswindow = (GETCONSWIN)GetProcAddress(kernel, "GetConsoleWindow");
+ if (cryptui && !OPENSSL_isservice())
+ ctx->client_cert_select = cert_select_dialog;
+ }
+#endif
+
+
+ return 1;
+
+ memerr:
+ CAPIerr(CAPI_F_CAPI_INIT, ERR_R_MALLOC_FAILURE);
+ return 0;
+
+ return 1;
+ }
+
+static int capi_destroy(ENGINE *e)
+ {
+ ERR_unload_CAPI_strings();
+ return 1;
+ }
+
+static int capi_finish(ENGINE *e)
+ {
+ CAPI_CTX *ctx;
+ ctx = ENGINE_get_ex_data(e, capi_idx);
+ capi_ctx_free(ctx);
+ ENGINE_set_ex_data(e, capi_idx, NULL);
+ return 1;
+ }
+
+
+/* CryptoAPI key application data. This contains
+ * a handle to the private key container (for sign operations)
+ * and a handle to the key (for decrypt operations).
+ */
+
+struct CAPI_KEY_st
+ {
+ /* Associated certificate context (if any) */
+ PCCERT_CONTEXT pcert;
+ HCRYPTPROV hprov;
+ HCRYPTKEY key;
+ DWORD keyspec;
+ };
+
+static int bind_capi(ENGINE *e)
+ {
+ if (!ENGINE_set_id(e, engine_capi_id)
+ || !ENGINE_set_name(e, engine_capi_name)
+ || !ENGINE_set_init_function(e, capi_init)
+ || !ENGINE_set_finish_function(e, capi_finish)
+ || !ENGINE_set_destroy_function(e, capi_destroy)
+ || !ENGINE_set_RSA(e, &capi_rsa_method)
+ || !ENGINE_set_DSA(e, &capi_dsa_method)
+ || !ENGINE_set_load_privkey_function(e, capi_load_privkey)
+ || !ENGINE_set_load_ssl_client_cert_function(e,
+ capi_load_ssl_client_cert)
+ || !ENGINE_set_cmd_defns(e, capi_cmd_defns)
+ || !ENGINE_set_ctrl_function(e, capi_ctrl))
+ return 0;
+ ERR_load_CAPI_strings();
+
+ return 1;
+
+ }
+
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_helper(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_capi_id) != 0))
+ return 0;
+ if(!bind_capi(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
+#else
+static ENGINE *engine_capi(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_capi(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_capi(void)
+ {
+ /* Copied from eng_[openssl|dyn].c */
+ ENGINE *toadd = engine_capi();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+#endif
+
+
+static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen)
+ {
+ int i;
+ /* Reverse buffer in place: since this is a keyblob structure
+ * that will be freed up after conversion anyway it doesn't
+ * matter if we change it.
+ */
+ for(i = 0; i < binlen / 2; i++)
+ {
+ unsigned char c;
+ c = bin[i];
+ bin[i] = bin[binlen - i - 1];
+ bin[binlen - i - 1] = c;
+ }
+
+ if (!BN_bin2bn(bin, binlen, bn))
+ return 0;
+ return 1;
+ }
+
+/* Given a CAPI_KEY get an EVP_PKEY structure */
+
+static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY *key)
+ {
+ unsigned char *pubkey = NULL;
+ DWORD len;
+ BLOBHEADER *bh;
+ RSA *rkey = NULL;
+ DSA *dkey = NULL;
+ EVP_PKEY *ret = NULL;
+ if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len))
+ {
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR);
+ capi_addlasterror();
+ return NULL;
+ }
+
+ pubkey = OPENSSL_malloc(len);
+
+ if (!pubkey)
+ goto memerr;
+
+ if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len))
+ {
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR);
+ capi_addlasterror();
+ goto err;
+ }
+
+ bh = (BLOBHEADER *)pubkey;
+ if (bh->bType != PUBLICKEYBLOB)
+ {
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB);
+ goto err;
+ }
+ if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX)
+ {
+ RSAPUBKEY *rp;
+ DWORD rsa_modlen;
+ unsigned char *rsa_modulus;
+ rp = (RSAPUBKEY *)(bh + 1);
+ if (rp->magic != 0x31415352)
+ {
+ char magstr[10];
+ BIO_snprintf(magstr, 10, "%lx", rp->magic);
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
+ ERR_add_error_data(2, "magic=0x", magstr);
+ goto err;
+ }
+ rsa_modulus = (unsigned char *)(rp + 1);
+ rkey = RSA_new_method(eng);
+ if (!rkey)
+ goto memerr;
+
+ rkey->e = BN_new();
+ rkey->n = BN_new();
+
+ if (!rkey->e || !rkey->n)
+ goto memerr;
+
+ if (!BN_set_word(rkey->e, rp->pubexp))
+ goto memerr;
+
+ rsa_modlen = rp->bitlen / 8;
+ if (!lend_tobn(rkey->n, rsa_modulus, rsa_modlen))
+ goto memerr;
+
+ RSA_set_ex_data(rkey, rsa_capi_idx, key);
+
+ if (!(ret = EVP_PKEY_new()))
+ goto memerr;
+
+ EVP_PKEY_assign_RSA(ret, rkey);
+ rkey = NULL;
+
+ }
+ else if (bh->aiKeyAlg == CALG_DSS_SIGN)
+ {
+ DSSPUBKEY *dp;
+ DWORD dsa_plen;
+ unsigned char *btmp;
+ dp = (DSSPUBKEY *)(bh + 1);
+ if (dp->magic != 0x31535344)
+ {
+ char magstr[10];
+ BIO_snprintf(magstr, 10, "%lx", dp->magic);
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
+ ERR_add_error_data(2, "magic=0x", magstr);
+ goto err;
+ }
+ dsa_plen = dp->bitlen / 8;
+ btmp = (unsigned char *)(dp + 1);
+ dkey = DSA_new_method(eng);
+ if (!dkey)
+ goto memerr;
+ dkey->p = BN_new();
+ dkey->q = BN_new();
+ dkey->g = BN_new();
+ dkey->pub_key = BN_new();
+ if (!dkey->p || !dkey->q || !dkey->g || !dkey->pub_key)
+ goto memerr;
+ if (!lend_tobn(dkey->p, btmp, dsa_plen))
+ goto memerr;
+ btmp += dsa_plen;
+ if (!lend_tobn(dkey->q, btmp, 20))
+ goto memerr;
+ btmp += 20;
+ if (!lend_tobn(dkey->g, btmp, dsa_plen))
+ goto memerr;
+ btmp += dsa_plen;
+ if (!lend_tobn(dkey->pub_key, btmp, dsa_plen))
+ goto memerr;
+ btmp += dsa_plen;
+
+ DSA_set_ex_data(dkey, dsa_capi_idx, key);
+
+ if (!(ret = EVP_PKEY_new()))
+ goto memerr;
+
+ EVP_PKEY_assign_DSA(ret, dkey);
+ dkey = NULL;
+ }
+ else
+ {
+ char algstr[10];
+ BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg);
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM);
+ ERR_add_error_data(2, "aiKeyAlg=0x", algstr);
+ goto err;
+ }
+
+
+ err:
+ if (pubkey)
+ OPENSSL_free(pubkey);
+ if (!ret)
+ {
+ if (rkey)
+ RSA_free(rkey);
+ if (dkey)
+ DSA_free(dkey);
+ }
+
+ return ret;
+
+memerr:
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE);
+ goto err;
+
+ }
+
+static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data)
+ {
+ CAPI_CTX *ctx;
+ CAPI_KEY *key;
+ EVP_PKEY *ret;
+ ctx = ENGINE_get_ex_data(eng, capi_idx);
+
+ if (!ctx)
+ {
+ CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT);
+ return NULL;
+ }
+
+ key = capi_find_key(ctx, key_id);
+
+ if (!key)
+ return NULL;
+
+ ret = capi_get_pkey(eng, key);
+
+ if (!ret)
+ capi_free_key(key);
+ return ret;
+
+ }
+
+/* CryptoAPI RSA operations */
+
+int capi_rsa_priv_enc(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_PRIV_ENC, CAPI_R_FUNCTION_NOT_SUPPORTED);
+ return -1;
+ }
+
+int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
+ unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
+ {
+ ALG_ID alg;
+ HCRYPTHASH hash;
+ DWORD slen;
+ unsigned int i;
+ int ret = -1;
+ CAPI_KEY *capi_key;
+ CAPI_CTX *ctx;
+
+ ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);
+
+ CAPI_trace(ctx, "Called CAPI_rsa_sign()\n");
+
+ capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
+ if (!capi_key)
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY);
+ return -1;
+ }
+/* Convert the signature type to a CryptoAPI algorithm ID */
+ switch(dtype)
+ {
+ case NID_sha1:
+ alg = CALG_SHA1;
+ break;
+
+ case NID_md5:
+ alg = CALG_MD5;
+ break;
+
+ case NID_md5_sha1:
+ alg = CALG_SSL3_SHAMD5;
+ break;
+ default:
+ {
+ char algstr[10];
+ BIO_snprintf(algstr, 10, "%lx", dtype);
+ CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID);
+ ERR_add_error_data(2, "NID=0x", algstr);
+ return -1;
+ }
+ }
+
+
+
+/* Create the hash object */
+ if(!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash))
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
+ capi_addlasterror();
+ return -1;
+ }
+/* Set the hash value to the value passed */
+
+ if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0))
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
+ capi_addlasterror();
+ goto err;
+ }
+
+
+/* Finally sign it */
+ slen = RSA_size(rsa);
+ if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, sigret, &slen))
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH);
+ capi_addlasterror();
+ goto err;
+ }
+ else
+ {
+ ret = 1;
+ /* Inplace byte reversal of signature */
+ for(i = 0; i < slen / 2; i++)
+ {
+ unsigned char c;
+ c = sigret[i];
+ sigret[i] = sigret[slen - i - 1];
+ sigret[slen - i - 1] = c;
+ }
+ *siglen = slen;
+ }
+
+ /* Now cleanup */
+
+err:
+ CryptDestroyHash(hash);
+
+ return ret;
+ }
+
+int capi_rsa_priv_dec(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+ {
+ int i;
+ unsigned char *tmpbuf;
+ CAPI_KEY *capi_key;
+ CAPI_CTX *ctx;
+ ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);
+
+ CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n");
+
+
+ capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
+ if (!capi_key)
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY);
+ return -1;
+ }
+
+ if(padding != RSA_PKCS1_PADDING)
+ {
+ char errstr[10];
+ BIO_snprintf(errstr, 10, "%d", padding);
+ CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING);
+ ERR_add_error_data(2, "padding=", errstr);
+ return -1;
+ }
+
+ /* Create temp reverse order version of input */
+ if(!(tmpbuf = OPENSSL_malloc(flen)) )
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ for(i = 0; i < flen; i++)
+ tmpbuf[flen - i - 1] = from[i];
+
+ /* Finally decrypt it */
+ if(!CryptDecrypt(capi_key->key, 0, TRUE, 0, tmpbuf, &flen))
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR);
+ capi_addlasterror();
+ OPENSSL_free(tmpbuf);
+ return -1;
+ }
+ else memcpy(to, tmpbuf, flen);
+
+ OPENSSL_free(tmpbuf);
+
+ return flen;
+ }
+
+static int capi_rsa_free(RSA *rsa)
+ {
+ CAPI_KEY *capi_key;
+ capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
+ capi_free_key(capi_key);
+ RSA_set_ex_data(rsa, rsa_capi_idx, 0);
+ return 1;
+ }
+
+/* CryptoAPI DSA operations */
+
+static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
+ DSA *dsa)
+ {
+ HCRYPTHASH hash;
+ DWORD slen;
+ DSA_SIG *ret = NULL;
+ CAPI_KEY *capi_key;
+ CAPI_CTX *ctx;
+ unsigned char csigbuf[40];
+
+ ctx = ENGINE_get_ex_data(dsa->engine, capi_idx);
+
+ CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n");
+
+ capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
+
+ if (!capi_key)
+ {
+ CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY);
+ return NULL;
+ }
+
+ if (dlen != 20)
+ {
+ CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH);
+ return NULL;
+ }
+
+ /* Create the hash object */
+ if(!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash))
+ {
+ CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
+ capi_addlasterror();
+ return NULL;
+ }
+
+ /* Set the hash value to the value passed */
+ if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0))
+ {
+ CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
+ capi_addlasterror();
+ goto err;
+ }
+
+
+ /* Finally sign it */
+ slen = sizeof(csigbuf);
+ if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen))
+ {
+ CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH);
+ capi_addlasterror();
+ goto err;
+ }
+ else
+ {
+ ret = DSA_SIG_new();
+ if (!ret)
+ goto err;
+ ret->r = BN_new();
+ ret->s = BN_new();
+ if (!ret->r || !ret->s)
+ goto err;
+ if (!lend_tobn(ret->r, csigbuf, 20)
+ || !lend_tobn(ret->s, csigbuf + 20, 20))
+ {
+ DSA_SIG_free(ret);
+ ret = NULL;
+ goto err;
+ }
+ }
+
+ /* Now cleanup */
+
+err:
+ OPENSSL_cleanse(csigbuf, 40);
+ CryptDestroyHash(hash);
+ return ret;
+ }
+
+static int capi_dsa_free(DSA *dsa)
+ {
+ CAPI_KEY *capi_key;
+ capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
+ capi_free_key(capi_key);
+ DSA_set_ex_data(dsa, dsa_capi_idx, 0);
+ return 1;
+ }
+
+static void capi_vtrace(CAPI_CTX *ctx, int level, char *format, va_list argptr)
+ {
+ BIO *out;
+
+ if (!ctx || (ctx->debug_level < level) || (!ctx->debug_file))
+ return;
+ out = BIO_new_file(ctx->debug_file, "a+");
+ BIO_vprintf(out, format, argptr);
+ BIO_free(out);
+ }
+
+static void CAPI_trace(CAPI_CTX *ctx, char *format, ...)
+ {
+ va_list args;
+ va_start(args, format);
+ capi_vtrace(ctx, CAPI_DBG_TRACE, format, args);
+ va_end(args);
+ }
+
+static void capi_addlasterror(void)
+ {
+ capi_adderror(GetLastError());
+ }
+
+static void capi_adderror(DWORD err)
+ {
+ char errstr[10];
+ BIO_snprintf(errstr, 10, "%lX", err);
+ ERR_add_error_data(2, "Error code= 0x", errstr);
+ }
+
+static char *wide_to_asc(LPWSTR wstr)
+ {
+ char *str;
+ int len_0,sz;
+
+ if (!wstr)
+ return NULL;
+ len_0 = (int)wcslen(wstr)+1; /* WideCharToMultiByte expects int */
+ sz = WideCharToMultiByte(CP_ACP,0,wstr,len_0,NULL,0,NULL,NULL);
+ if (!sz)
+ {
+ CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
+ return NULL;
+ }
+ str = OPENSSL_malloc(sz);
+ if (!str)
+ {
+ CAPIerr(CAPI_F_WIDE_TO_ASC, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ if (!WideCharToMultiByte(CP_ACP,0,wstr,len_0,str,sz,NULL,NULL))
+ {
+ OPENSSL_free(str);
+ CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
+ return NULL;
+ }
+ return str;
+ }
+
+static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD idx)
+ {
+ LPSTR name;
+ DWORD len, err;
+ CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx);
+ if (!CryptEnumProvidersA(idx, NULL, 0, ptype, NULL, &len))
+ {
+ err = GetLastError();
+ if (err == ERROR_NO_MORE_ITEMS)
+ return 2;
+ CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
+ capi_adderror(err);
+ return 0;
+ }
+ name = OPENSSL_malloc(len);
+ if (!CryptEnumProvidersA(idx, NULL, 0, ptype, name, &len))
+ {
+ err = GetLastError();
+ if (err == ERROR_NO_MORE_ITEMS)
+ return 2;
+ CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
+ capi_adderror(err);
+ return 0;
+ }
+ *pname = name;
+ CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", name, *ptype);
+
+ return 1;
+ }
+
+static int capi_list_providers(CAPI_CTX *ctx, BIO *out)
+ {
+ DWORD idx, ptype;
+ int ret;
+ LPSTR provname = NULL;
+ CAPI_trace(ctx, "capi_list_providers\n");
+ BIO_printf(out, "Available CSPs:\n");
+ for(idx = 0; ; idx++)
+ {
+ ret = capi_get_provname(ctx, &provname, &ptype, idx);
+ if (ret == 2)
+ break;
+ if (ret == 0)
+ break;
+ BIO_printf(out, "%d. %s, type %d\n", idx, provname, ptype);
+ OPENSSL_free(provname);
+ }
+ return 1;
+ }
+
+static int capi_list_containers(CAPI_CTX *ctx, BIO *out)
+ {
+ int ret = 1;
+ HCRYPTPROV hprov;
+ DWORD err, idx, flags, buflen = 0, clen;
+ LPSTR cname;
+ CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, ctx->csptype);
+ if (!CryptAcquireContextA(&hprov, NULL, ctx->cspname, ctx->csptype, CRYPT_VERIFYCONTEXT))
+ {
+ CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
+ capi_addlasterror();
+ return 0;
+ }
+ if (!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, NULL, &buflen, CRYPT_FIRST))
+ {
+ CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
+ capi_addlasterror();
+ return 0;
+ }
+ CAPI_trace(ctx, "Got max container len %d\n", buflen);
+ if (buflen == 0)
+ buflen = 1024;
+ cname = OPENSSL_malloc(buflen);
+ if (!cname)
+ {
+ CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ for (idx = 0;;idx++)
+ {
+ clen = buflen;
+ cname[0] = 0;
+
+ if (idx == 0)
+ flags = CRYPT_FIRST;
+ else
+ flags = 0;
+ if(!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, cname, &clen, flags))
+ {
+ err = GetLastError();
+ if (err == ERROR_NO_MORE_ITEMS)
+ goto done;
+ CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
+ capi_adderror(err);
+ goto err;
+ }
+ CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n", cname, clen, idx, flags);
+ if (!cname[0] && (clen == buflen))
+ {
+ CAPI_trace(ctx, "Enumerate bug: using workaround\n");
+ goto done;
+ }
+ BIO_printf(out, "%d. %s\n", idx, cname);
+ }
+ err:
+
+ ret = 0;
+
+ done:
+ if (cname)
+ OPENSSL_free(cname);
+ CryptReleaseContext(hprov, 0);
+
+ return ret;
+ }
+
+CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
+ {
+ DWORD len;
+ CRYPT_KEY_PROV_INFO *pinfo;
+
+ if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len))
+ return NULL;
+ pinfo = OPENSSL_malloc(len);
+ if (!pinfo)
+ {
+ CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len))
+ {
+ CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO);
+ capi_addlasterror();
+ OPENSSL_free(pinfo);
+ return NULL;
+ }
+ return pinfo;
+ }
+
+static void capi_dump_prov_info(CAPI_CTX *ctx, BIO *out, CRYPT_KEY_PROV_INFO *pinfo)
+ {
+ char *provname = NULL, *contname = NULL;
+ if (!pinfo)
+ {
+ BIO_printf(out, " No Private Key\n");
+ return;
+ }
+ provname = wide_to_asc(pinfo->pwszProvName);
+ contname = wide_to_asc(pinfo->pwszContainerName);
+ if (!provname || !contname)
+ goto err;
+
+ BIO_printf(out, " Private Key Info:\n");
+ BIO_printf(out, " Provider Name: %s, Provider Type %d\n", provname, pinfo->dwProvType);
+ BIO_printf(out, " Container Name: %s, Key Type %d\n", contname, pinfo->dwKeySpec);
+ err:
+ if (provname)
+ OPENSSL_free(provname);
+ if (contname)
+ OPENSSL_free(contname);
+ }
+
+char * capi_cert_get_fname(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
+ {
+ LPWSTR wfname;
+ DWORD dlen;
+
+ CAPI_trace(ctx, "capi_cert_get_fname\n");
+ if (!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen))
+ return NULL;
+ wfname = OPENSSL_malloc(dlen);
+ if (CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen))
+ {
+ char *fname = wide_to_asc(wfname);
+ OPENSSL_free(wfname);
+ return fname;
+ }
+ CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME);
+ capi_addlasterror();
+
+ OPENSSL_free(wfname);
+ return NULL;
+ }
+
+
+void capi_dump_cert(CAPI_CTX *ctx, BIO *out, PCCERT_CONTEXT cert)
+ {
+ X509 *x;
+ unsigned char *p;
+ unsigned long flags = ctx->dump_flags;
+ if (flags & CAPI_DMP_FNAME)
+ {
+ char *fname;
+ fname = capi_cert_get_fname(ctx, cert);
+ if (fname)
+ {
+ BIO_printf(out, " Friendly Name \"%s\"\n", fname);
+ OPENSSL_free(fname);
+ }
+ else
+ BIO_printf(out, " <No Friendly Name>\n");
+ }
+
+ p = cert->pbCertEncoded;
+ x = d2i_X509(NULL, &p, cert->cbCertEncoded);
+ if (!x)
+ BIO_printf(out, " <Can't parse certificate>\n");
+ if (flags & CAPI_DMP_SUMMARY)
+ {
+ BIO_printf(out, " Subject: ");
+ X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
+ BIO_printf(out, "\n Issuer: ");
+ X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
+ BIO_printf(out, "\n");
+ }
+ if (flags & CAPI_DMP_FULL)
+ X509_print_ex(out, x, XN_FLAG_ONELINE,0);
+
+ if (flags & CAPI_DMP_PKEYINFO)
+ {
+ CRYPT_KEY_PROV_INFO *pinfo;
+ pinfo = capi_get_prov_info(ctx, cert);
+ capi_dump_prov_info(ctx, out, pinfo);
+ if (pinfo)
+ OPENSSL_free(pinfo);
+ }
+
+ if (flags & CAPI_DMP_PEM)
+ PEM_write_bio_X509(out, x);
+ X509_free(x);
+ }
+
+HCERTSTORE capi_open_store(CAPI_CTX *ctx, char *storename)
+ {
+ HCERTSTORE hstore;
+
+ if (!storename)
+ storename = ctx->storename;
+ if (!storename)
+ storename = "MY";
+ CAPI_trace(ctx, "Opening certificate store %s\n", storename);
+
+ hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0,
+ ctx->store_flags, storename);
+ if (!hstore)
+ {
+ CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE);
+ capi_addlasterror();
+ }
+ return hstore;
+ }
+
+int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *id)
+ {
+ char *storename;
+ int idx;
+ int ret = 1;
+ HCERTSTORE hstore;
+ PCCERT_CONTEXT cert = NULL;
+
+ storename = ctx->storename;
+ if (!storename)
+ storename = "MY";
+ CAPI_trace(ctx, "Listing certs for store %s\n", storename);
+
+ hstore = capi_open_store(ctx, storename);
+ if (!hstore)
+ return 0;
+ if (id)
+ {
+ cert = capi_find_cert(ctx, id, hstore);
+ if (!cert)
+ {
+ ret = 0;
+ goto err;
+ }
+ capi_dump_cert(ctx, out, cert);
+ CertFreeCertificateContext(cert);
+ }
+ else
+ {
+ for(idx = 0;;idx++)
+ {
+ LPWSTR fname = NULL;
+ cert = CertEnumCertificatesInStore(hstore, cert);
+ if (!cert)
+ break;
+ BIO_printf(out, "Certificate %d\n", idx);
+ capi_dump_cert(ctx, out, cert);
+ }
+ }
+ err:
+ CertCloseStore(hstore, 0);
+ return ret;
+ }
+
+static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore)
+ {
+ PCCERT_CONTEXT cert = NULL;
+ char *fname = NULL;
+ int match;
+ switch(ctx->lookup_method)
+ {
+ case CAPI_LU_SUBSTR:
+ return CertFindCertificateInStore(hstore,
+ X509_ASN_ENCODING, 0,
+ CERT_FIND_SUBJECT_STR_A, id, NULL);
+ case CAPI_LU_FNAME:
+ for(;;)
+ {
+ cert = CertEnumCertificatesInStore(hstore, cert);
+ if (!cert)
+ return NULL;
+ fname = capi_cert_get_fname(ctx, cert);
+ if (fname)
+ {
+ if (strcmp(fname, id))
+ match = 0;
+ else
+ match = 1;
+ OPENSSL_free(fname);
+ if (match)
+ return cert;
+ }
+ }
+ default:
+ return NULL;
+ }
+ }
+
+static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provname, DWORD ptype, DWORD keyspec)
+ {
+ CAPI_KEY *key;
+ key = OPENSSL_malloc(sizeof(CAPI_KEY));
+ CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n",
+ contname, provname, ptype);
+ if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, 0))
+ {
+ CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
+ capi_addlasterror();
+ goto err;
+ }
+ if (!CryptGetUserKey(key->hprov, keyspec, &key->key))
+ {
+ CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR);
+ capi_addlasterror();
+ CryptReleaseContext(key->hprov, 0);
+ goto err;
+ }
+ key->keyspec = keyspec;
+ key->pcert = NULL;
+ return key;
+
+ err:
+ OPENSSL_free(key);
+ return NULL;
+ }
+
+static CAPI_KEY *capi_get_cert_key(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
+ {
+ CAPI_KEY *key = NULL;
+ CRYPT_KEY_PROV_INFO *pinfo = NULL;
+ char *provname = NULL, *contname = NULL;
+ pinfo = capi_get_prov_info(ctx, cert);
+ if (!pinfo)
+ goto err;
+ provname = wide_to_asc(pinfo->pwszProvName);
+ contname = wide_to_asc(pinfo->pwszContainerName);
+ if (!provname || !contname)
+ goto err;
+ key = capi_get_key(ctx, contname, provname,
+ pinfo->dwProvType, pinfo->dwKeySpec);
+
+ err:
+ if (pinfo)
+ OPENSSL_free(pinfo);
+ if (provname)
+ OPENSSL_free(provname);
+ if (contname)
+ OPENSSL_free(contname);
+ return key;
+ }
+
+CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id)
+ {
+ PCCERT_CONTEXT cert;
+ HCERTSTORE hstore;
+ CAPI_KEY *key = NULL;
+ switch (ctx->lookup_method)
+ {
+ case CAPI_LU_SUBSTR:
+ case CAPI_LU_FNAME:
+ hstore = capi_open_store(ctx, NULL);
+ if (!hstore)
+ return NULL;
+ cert = capi_find_cert(ctx, id, hstore);
+ if (cert)
+ {
+ key = capi_get_cert_key(ctx, cert);
+ CertFreeCertificateContext(cert);
+ }
+ CertCloseStore(hstore, 0);
+ break;
+
+ case CAPI_LU_CONTNAME:
+ key = capi_get_key(ctx, id, ctx->cspname, ctx->csptype,
+ ctx->keytype);
+ break;
+ }
+
+ return key;
+ }
+
+void capi_free_key(CAPI_KEY *key)
+ {
+ if (!key)
+ return;
+ CryptDestroyKey(key->key);
+ CryptReleaseContext(key->hprov, 0);
+ if (key->pcert)
+ CertFreeCertificateContext(key->pcert);
+ OPENSSL_free(key);
+ }
+
+
+/* Initialize a CAPI_CTX structure */
+
+static CAPI_CTX *capi_ctx_new()
+ {
+ CAPI_CTX *ctx;
+ ctx = OPENSSL_malloc(sizeof(CAPI_CTX));
+ if (!ctx)
+ {
+ CAPIerr(CAPI_F_CAPI_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ ctx->cspname = NULL;
+ ctx->csptype = PROV_RSA_FULL;
+ ctx->dump_flags = CAPI_DMP_SUMMARY|CAPI_DMP_FNAME;
+ ctx->keytype = AT_KEYEXCHANGE;
+ ctx->storename = NULL;
+ ctx->ssl_client_store = NULL;
+ ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG |
+ CERT_STORE_READONLY_FLAG |
+ CERT_SYSTEM_STORE_CURRENT_USER;
+ ctx->lookup_method = CAPI_LU_SUBSTR;
+ ctx->debug_level = 0;
+ ctx->debug_file = NULL;
+ ctx->client_cert_select = cert_select_simple;
+ return ctx;
+ }
+
+static void capi_ctx_free(CAPI_CTX *ctx)
+ {
+ CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx);
+ if (!ctx)
+ return;
+ if (ctx->cspname)
+ OPENSSL_free(ctx->cspname);
+ if (ctx->debug_file)
+ OPENSSL_free(ctx->debug_file);
+ if (ctx->storename)
+ OPENSSL_free(ctx->storename);
+ if (ctx->ssl_client_store)
+ OPENSSL_free(ctx->ssl_client_store);
+ OPENSSL_free(ctx);
+ }
+
+static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check)
+ {
+ CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type);
+ if (check)
+ {
+ HCRYPTPROV hprov;
+ if (!CryptAcquireContextA(&hprov, NULL, pname, type,
+ CRYPT_VERIFYCONTEXT))
+ {
+ CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
+ capi_addlasterror();
+ return 0;
+ }
+ CryptReleaseContext(hprov, 0);
+ }
+ ctx->cspname = BUF_strdup(pname);
+ ctx->csptype = type;
+ return 1;
+ }
+
+static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx)
+ {
+ LPSTR pname;
+ DWORD type;
+ if (capi_get_provname(ctx, &pname, &type, idx) != 1)
+ return 0;
+ return capi_ctx_set_provname(ctx, pname, type, 0);
+ }
+
+static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x)
+ {
+ int i;
+ X509_NAME *nm;
+ /* Special case: empty list: match anything */
+ if (sk_X509_NAME_num(ca_dn) <= 0)
+ return 1;
+ for (i = 0; i < sk_X509_NAME_num(ca_dn); i++)
+ {
+ nm = sk_X509_NAME_value(ca_dn, i);
+ if (!X509_NAME_cmp(nm, X509_get_issuer_name(x)))
+ return 1;
+ }
+ return 0;
+ }
+
+
+
+static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
+ STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
+ STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
+ {
+ STACK_OF(X509) *certs = NULL;
+ X509 *x;
+ char *storename;
+ const char *p;
+ int i, client_cert_idx;
+ HCERTSTORE hstore;
+ PCCERT_CONTEXT cert = NULL, excert = NULL;
+ CAPI_CTX *ctx;
+ CAPI_KEY *key;
+ ctx = ENGINE_get_ex_data(e, capi_idx);
+
+ *pcert = NULL;
+ *pkey = NULL;
+
+ storename = ctx->ssl_client_store;
+ if (!storename)
+ storename = "MY";
+
+ hstore = capi_open_store(ctx, storename);
+ if (!hstore)
+ return 0;
+ /* Enumerate all certificates collect any matches */
+ for(i = 0;;i++)
+ {
+ cert = CertEnumCertificatesInStore(hstore, cert);
+ if (!cert)
+ break;
+ p = cert->pbCertEncoded;
+ x = d2i_X509(NULL, &p, cert->cbCertEncoded);
+ if (!x)
+ {
+ CAPI_trace(ctx, "Can't Parse Certificate %d\n", i);
+ continue;
+ }
+ if (cert_issuer_match(ca_dn, x)
+ && X509_check_purpose(x, X509_PURPOSE_SSL_CLIENT, 0))
+ {
+ key = capi_get_cert_key(ctx, cert);
+ if (!key)
+ {
+ X509_free(x);
+ continue;
+ }
+ /* Match found: attach extra data to it so
+ * we can retrieve the key later.
+ */
+ excert = CertDuplicateCertificateContext(cert);
+ key->pcert = excert;
+ X509_set_ex_data(x, cert_capi_idx, key);
+
+ if (!certs)
+ certs = sk_X509_new_null();
+
+ sk_X509_push(certs, x);
+ }
+ else
+ X509_free(x);
+
+ }
+
+ if (cert)
+ CertFreeCertificateContext(cert);
+ if (hstore)
+ CertCloseStore(hstore, 0);
+
+ if (!certs)
+ return 0;
+
+
+ /* Select the appropriate certificate */
+
+ client_cert_idx = ctx->client_cert_select(e, ssl, certs);
+
+ /* Set the selected certificate and free the rest */
+
+ for(i = 0; i < sk_X509_num(certs); i++)
+ {
+ x = sk_X509_value(certs, i);
+ if (i == client_cert_idx)
+ *pcert = x;
+ else
+ {
+ key = X509_get_ex_data(x, cert_capi_idx);
+ capi_free_key(key);
+ X509_free(x);
+ }
+ }
+
+ sk_X509_free(certs);
+
+ if (!*pcert)
+ return 0;
+
+ /* Setup key for selected certificate */
+
+ key = X509_get_ex_data(*pcert, cert_capi_idx);
+ *pkey = capi_get_pkey(e, key);
+ X509_set_ex_data(*pcert, cert_capi_idx, NULL);
+
+ return 1;
+
+ }
+
+
+/* Simple client cert selection function: always select first */
+
+static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
+ {
+ return 0;
+ }
+
+#ifdef OPENSSL_CAPIENG_DIALOG
+
+/* More complex cert selection function, using standard function
+ * CryptUIDlgSelectCertificateFromStore() to produce a dialog box.
+ */
+
+/* Definitions which are in cryptuiapi.h but this is not present in older
+ * versions of headers.
+ */
+
+#ifndef CRYPTUI_SELECT_LOCATION_COLUMN
+#define CRYPTUI_SELECT_LOCATION_COLUMN 0x000000010
+#define CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004
+#endif
+
+#define dlg_title L"OpenSSL Application SSL Client Certificate Selection"
+#define dlg_prompt L"Select a certificate to use for authentication"
+#define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \
+ |CRYPTUI_SELECT_INTENDEDUSE_COLUMN
+
+static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
+ {
+ X509 *x;
+ HCERTSTORE dstore;
+ PCCERT_CONTEXT cert;
+ CAPI_CTX *ctx;
+ CAPI_KEY *key;
+ HWND hwnd;
+ int i, idx = -1;
+ if (sk_X509_num(certs) == 1)
+ return 0;
+ ctx = ENGINE_get_ex_data(e, capi_idx);
+ /* Create an in memory store of certificates */
+ dstore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
+ CERT_STORE_CREATE_NEW_FLAG, NULL);
+ if (!dstore)
+ {
+ CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_CREATING_STORE);
+ capi_addlasterror();
+ goto err;
+ }
+ /* Add all certificates to store */
+ for(i = 0; i < sk_X509_num(certs); i++)
+ {
+ x = sk_X509_value(certs, i);
+ key = X509_get_ex_data(x, cert_capi_idx);
+
+ if (!CertAddCertificateContextToStore(dstore, key->pcert,
+ CERT_STORE_ADD_NEW, NULL))
+ {
+ CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_ADDING_CERT);
+ capi_addlasterror();
+ goto err;
+ }
+
+ }
+ hwnd = GetForegroundWindow();
+ if (!hwnd)
+ hwnd = GetActiveWindow();
+ if (!hwnd && ctx->getconswindow)
+ hwnd = ctx->getconswindow();
+ /* Call dialog to select one */
+ cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt,
+ dlg_columns, 0, NULL);
+
+ /* Find matching cert from list */
+ if (cert)
+ {
+ for(i = 0; i < sk_X509_num(certs); i++)
+ {
+ x = sk_X509_value(certs, i);
+ key = X509_get_ex_data(x, cert_capi_idx);
+ if (CertCompareCertificate(
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ cert->pCertInfo,
+ key->pcert->pCertInfo))
+ {
+ idx = i;
+ break;
+ }
+ }
+ }
+
+ err:
+ if (dstore)
+ CertCloseStore(dstore, 0);
+ return idx;
+
+ }
+#endif
+
+#else /* !__COMPILE_CAPIENG */
+#include <openssl/engine.h>
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+#else
+void ENGINE_load_capi(void){}
+#endif
+#endif
diff --git a/openssl/engines/e_gmp.c b/openssl/engines/e_gmp.c
index 63d68b0c2..a3d47151e 100644
--- a/openssl/engines/e_gmp.c
+++ b/openssl/engines/e_gmp.c
@@ -1,480 +1,480 @@
-/* crypto/engine/e_gmp.c */
-/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
- * project 2003.
- */
-/* ====================================================================
- * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-/* This engine is not (currently) compiled in by default. Do enable it,
- * reconfigure OpenSSL with "enable-gmp -lgmp". The GMP libraries and
- * headers must reside in one of the paths searched by the compiler/linker,
- * otherwise paths must be specified - eg. try configuring with
- * "enable-gmp -I<includepath> -L<libpath> -lgmp". YMMV. */
-
-/* As for what this does - it's a largely unoptimised implementation of an
- * ENGINE that uses the GMP library to perform RSA private key operations. To
- * obtain more information about what "unoptimised" means, see my original mail
- * on the subject (though ignore the build instructions which have since
- * changed);
- *
- * http://www.mail-archive.com/openssl-dev@openssl.org/msg12227.html
- *
- * On my athlon system at least, it appears the builtin OpenSSL code is now
- * slightly faster, which is to say that the RSA-related MPI performance
- * between OpenSSL's BIGNUM and GMP's mpz implementations is probably pretty
- * balanced for this chip, and so the performance degradation in this ENGINE by
- * having to convert to/from GMP formats (and not being able to cache
- * montgomery forms) is probably the difference. However, if some unconfirmed
- * reports from users is anything to go by, the situation on some other
- * chipsets might be a good deal more favourable to the GMP version (eg. PPC).
- * Feedback welcome. */
-
-#include <stdio.h>
-#include <string.h>
-#include <openssl/crypto.h>
-#include <openssl/buffer.h>
-#include <openssl/engine.h>
-#ifndef OPENSSL_NO_RSA
-#include <openssl/rsa.h>
-#endif
-#include <openssl/bn.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_GMP
-
-#include <gmp.h>
-
-#define E_GMP_LIB_NAME "gmp engine"
-#include "e_gmp_err.c"
-
-static int e_gmp_destroy(ENGINE *e);
-static int e_gmp_init(ENGINE *e);
-static int e_gmp_finish(ENGINE *e);
-static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
-
-#ifndef OPENSSL_NO_RSA
-/* RSA stuff */
-static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
-static int e_gmp_rsa_finish(RSA *r);
-#endif
-
-/* The definitions for control commands specific to this engine */
-/* #define E_GMP_CMD_SO_PATH ENGINE_CMD_BASE */
-static const ENGINE_CMD_DEFN e_gmp_cmd_defns[] = {
-#if 0
- {E_GMP_CMD_SO_PATH,
- "SO_PATH",
- "Specifies the path to the 'e_gmp' shared library",
- ENGINE_CMD_FLAG_STRING},
-#endif
- {0, NULL, NULL, 0}
- };
-
-#ifndef OPENSSL_NO_RSA
-/* Our internal RSA_METHOD that we provide pointers to */
-static RSA_METHOD e_gmp_rsa =
- {
- "GMP RSA method",
- NULL,
- NULL,
- NULL,
- NULL,
- e_gmp_rsa_mod_exp,
- NULL,
- NULL,
- e_gmp_rsa_finish,
- /* These flags initialise montgomery crud that GMP ignores, however it
- * makes sure the public key ops (which are done in openssl) don't seem
- * *slower* than usual :-) */
- RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE,
- NULL,
- NULL,
- NULL
- };
-#endif
-
-/* Constants used when creating the ENGINE */
-static const char *engine_e_gmp_id = "gmp";
-static const char *engine_e_gmp_name = "GMP engine support";
-
-/* This internal function is used by ENGINE_gmp() and possibly by the
- * "dynamic" ENGINE support too */
-static int bind_helper(ENGINE *e)
- {
-#ifndef OPENSSL_NO_RSA
- const RSA_METHOD *meth1;
-#endif
- if(!ENGINE_set_id(e, engine_e_gmp_id) ||
- !ENGINE_set_name(e, engine_e_gmp_name) ||
-#ifndef OPENSSL_NO_RSA
- !ENGINE_set_RSA(e, &e_gmp_rsa) ||
-#endif
- !ENGINE_set_destroy_function(e, e_gmp_destroy) ||
- !ENGINE_set_init_function(e, e_gmp_init) ||
- !ENGINE_set_finish_function(e, e_gmp_finish) ||
- !ENGINE_set_ctrl_function(e, e_gmp_ctrl) ||
- !ENGINE_set_cmd_defns(e, e_gmp_cmd_defns))
- return 0;
-
-#ifndef OPENSSL_NO_RSA
- meth1 = RSA_PKCS1_SSLeay();
- e_gmp_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
- e_gmp_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
- e_gmp_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
- e_gmp_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
- e_gmp_rsa.bn_mod_exp = meth1->bn_mod_exp;
-#endif
-
- /* Ensure the e_gmp error handling is set up */
- ERR_load_GMP_strings();
- return 1;
- }
-
-static ENGINE *engine_gmp(void)
- {
- ENGINE *ret = ENGINE_new();
- if(!ret)
- return NULL;
- if(!bind_helper(ret))
- {
- ENGINE_free(ret);
- return NULL;
- }
- return ret;
- }
-
-void ENGINE_load_gmp(void)
- {
- /* Copied from eng_[openssl|dyn].c */
- ENGINE *toadd = engine_gmp();
- if(!toadd) return;
- ENGINE_add(toadd);
- ENGINE_free(toadd);
- ERR_clear_error();
- }
-
-#ifndef OPENSSL_NO_RSA
-/* Used to attach our own key-data to an RSA structure */
-static int hndidx_rsa = -1;
-#endif
-
-static int e_gmp_destroy(ENGINE *e)
- {
- ERR_unload_GMP_strings();
- return 1;
- }
-
-/* (de)initialisation functions. */
-static int e_gmp_init(ENGINE *e)
- {
-#ifndef OPENSSL_NO_RSA
- if (hndidx_rsa == -1)
- hndidx_rsa = RSA_get_ex_new_index(0,
- "GMP-based RSA key handle",
- NULL, NULL, NULL);
-#endif
- if (hndidx_rsa == -1)
- return 0;
- return 1;
- }
-
-static int e_gmp_finish(ENGINE *e)
- {
- return 1;
- }
-
-static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
- {
- int to_return = 1;
-
- switch(cmd)
- {
-#if 0
- case E_GMP_CMD_SO_PATH:
- /* ... */
-#endif
- /* The command isn't understood by this engine */
- default:
- GMPerr(GMP_F_E_GMP_CTRL,
- GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED);
- to_return = 0;
- break;
- }
-
- return to_return;
- }
-
-
-/* Most often limb sizes will be the same. If not, we use hex conversion
- * which is neat, but extremely inefficient. */
-static int bn2gmp(const BIGNUM *bn, mpz_t g)
- {
- bn_check_top(bn);
- if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) &&
- (BN_BITS2 == GMP_NUMB_BITS))
- {
- /* The common case */
- if(!_mpz_realloc (g, bn->top))
- return 0;
- memcpy(&g->_mp_d[0], &bn->d[0], bn->top * sizeof(bn->d[0]));
- g->_mp_size = bn->top;
- if(bn->neg)
- g->_mp_size = -g->_mp_size;
- return 1;
- }
- else
- {
- int toret;
- char *tmpchar = BN_bn2hex(bn);
- if(!tmpchar) return 0;
- toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0);
- OPENSSL_free(tmpchar);
- return toret;
- }
- }
-
-static int gmp2bn(mpz_t g, BIGNUM *bn)
- {
- if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) &&
- (BN_BITS2 == GMP_NUMB_BITS))
- {
- /* The common case */
- int s = (g->_mp_size >= 0) ? g->_mp_size : -g->_mp_size;
- BN_zero(bn);
- if(bn_expand2 (bn, s) == NULL)
- return 0;
- bn->top = s;
- memcpy(&bn->d[0], &g->_mp_d[0], s * sizeof(bn->d[0]));
- bn_correct_top(bn);
- bn->neg = g->_mp_size >= 0 ? 0 : 1;
- return 1;
- }
- else
- {
- int toret;
- char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10);
- if(!tmpchar) return 0;
- mpz_get_str(tmpchar, 16, g);
- toret = BN_hex2bn(&bn, tmpchar);
- OPENSSL_free(tmpchar);
- return toret;
- }
- }
-
-#ifndef OPENSSL_NO_RSA
-typedef struct st_e_gmp_rsa_ctx
- {
- int public_only;
- mpz_t n;
- mpz_t d;
- mpz_t e;
- mpz_t p;
- mpz_t q;
- mpz_t dmp1;
- mpz_t dmq1;
- mpz_t iqmp;
- mpz_t r0, r1, I0, m1;
- } E_GMP_RSA_CTX;
-
-static E_GMP_RSA_CTX *e_gmp_get_rsa(RSA *rsa)
- {
- E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa);
- if(hptr) return hptr;
- hptr = OPENSSL_malloc(sizeof(E_GMP_RSA_CTX));
- if(!hptr) return NULL;
- /* These inits could probably be replaced by more intelligent
- * mpz_init2() versions, to reduce malloc-thrashing. */
- mpz_init(hptr->n);
- mpz_init(hptr->d);
- mpz_init(hptr->e);
- mpz_init(hptr->p);
- mpz_init(hptr->q);
- mpz_init(hptr->dmp1);
- mpz_init(hptr->dmq1);
- mpz_init(hptr->iqmp);
- mpz_init(hptr->r0);
- mpz_init(hptr->r1);
- mpz_init(hptr->I0);
- mpz_init(hptr->m1);
- if(!bn2gmp(rsa->n, hptr->n) || !bn2gmp(rsa->e, hptr->e))
- goto err;
- if(!rsa->p || !rsa->q || !rsa->d || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
- {
- hptr->public_only = 1;
- return hptr;
- }
- if(!bn2gmp(rsa->d, hptr->d) || !bn2gmp(rsa->p, hptr->p) ||
- !bn2gmp(rsa->q, hptr->q) || !bn2gmp(rsa->dmp1, hptr->dmp1) ||
- !bn2gmp(rsa->dmq1, hptr->dmq1) || !bn2gmp(rsa->iqmp, hptr->iqmp))
- goto err;
- hptr->public_only = 0;
- RSA_set_ex_data(rsa, hndidx_rsa, hptr);
- return hptr;
-err:
- mpz_clear(hptr->n);
- mpz_clear(hptr->d);
- mpz_clear(hptr->e);
- mpz_clear(hptr->p);
- mpz_clear(hptr->q);
- mpz_clear(hptr->dmp1);
- mpz_clear(hptr->dmq1);
- mpz_clear(hptr->iqmp);
- mpz_clear(hptr->r0);
- mpz_clear(hptr->r1);
- mpz_clear(hptr->I0);
- mpz_clear(hptr->m1);
- OPENSSL_free(hptr);
- return NULL;
- }
-
-static int e_gmp_rsa_finish(RSA *rsa)
- {
- E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa);
- if(!hptr) return 0;
- mpz_clear(hptr->n);
- mpz_clear(hptr->d);
- mpz_clear(hptr->e);
- mpz_clear(hptr->p);
- mpz_clear(hptr->q);
- mpz_clear(hptr->dmp1);
- mpz_clear(hptr->dmq1);
- mpz_clear(hptr->iqmp);
- mpz_clear(hptr->r0);
- mpz_clear(hptr->r1);
- mpz_clear(hptr->I0);
- mpz_clear(hptr->m1);
- OPENSSL_free(hptr);
- RSA_set_ex_data(rsa, hndidx_rsa, NULL);
- return 1;
- }
-
-static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
- {
- E_GMP_RSA_CTX *hptr;
- int to_return = 0;
-
- hptr = e_gmp_get_rsa(rsa);
- if(!hptr)
- {
- GMPerr(GMP_F_E_GMP_RSA_MOD_EXP,
- GMP_R_KEY_CONTEXT_ERROR);
- return 0;
- }
- if(hptr->public_only)
- {
- GMPerr(GMP_F_E_GMP_RSA_MOD_EXP,
- GMP_R_MISSING_KEY_COMPONENTS);
- return 0;
- }
-
- /* ugh!!! */
- if(!bn2gmp(I, hptr->I0))
- return 0;
-
- /* This is basically the CRT logic in crypto/rsa/rsa_eay.c reworded into
- * GMP-speak. It may be that GMP's API facilitates cleaner formulations
- * of this stuff, eg. better handling of negatives, or functions that
- * combine operations. */
-
- mpz_mod(hptr->r1, hptr->I0, hptr->q);
- mpz_powm(hptr->m1, hptr->r1, hptr->dmq1, hptr->q);
-
- mpz_mod(hptr->r1, hptr->I0, hptr->p);
- mpz_powm(hptr->r0, hptr->r1, hptr->dmp1, hptr->p);
-
- mpz_sub(hptr->r0, hptr->r0, hptr->m1);
-
- if(mpz_sgn(hptr->r0) < 0)
- mpz_add(hptr->r0, hptr->r0, hptr->p);
- mpz_mul(hptr->r1, hptr->r0, hptr->iqmp);
- mpz_mod(hptr->r0, hptr->r1, hptr->p);
-
- if(mpz_sgn(hptr->r0) < 0)
- mpz_add(hptr->r0, hptr->r0, hptr->p);
- mpz_mul(hptr->r1, hptr->r0, hptr->q);
- mpz_add(hptr->r0, hptr->r1, hptr->m1);
-
- /* ugh!!! */
- if(gmp2bn(hptr->r0, r))
- to_return = 1;
-
- return 1;
- }
-#endif
-
-#endif /* !OPENSSL_NO_GMP */
-
-/* This stuff is needed if this ENGINE is being compiled into a self-contained
- * shared-library. */
-#ifndef OPENSSL_NO_DYNAMIC_ENGINE
-IMPLEMENT_DYNAMIC_CHECK_FN()
-#ifndef OPENSSL_NO_GMP
-static int bind_fn(ENGINE *e, const char *id)
- {
- if(id && (strcmp(id, engine_e_gmp_id) != 0))
- return 0;
- if(!bind_helper(e))
- return 0;
- return 1;
- }
-IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
-#else
-OPENSSL_EXPORT
-int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
-OPENSSL_EXPORT
-int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
-#endif
-#endif /* !OPENSSL_NO_DYNAMIC_ENGINE */
-
-#endif /* !OPENSSL_NO_HW */
+/* crypto/engine/e_gmp.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* This engine is not (currently) compiled in by default. Do enable it,
+ * reconfigure OpenSSL with "enable-gmp -lgmp". The GMP libraries and
+ * headers must reside in one of the paths searched by the compiler/linker,
+ * otherwise paths must be specified - eg. try configuring with
+ * "enable-gmp -I<includepath> -L<libpath> -lgmp". YMMV. */
+
+/* As for what this does - it's a largely unoptimised implementation of an
+ * ENGINE that uses the GMP library to perform RSA private key operations. To
+ * obtain more information about what "unoptimised" means, see my original mail
+ * on the subject (though ignore the build instructions which have since
+ * changed);
+ *
+ * http://www.mail-archive.com/openssl-dev@openssl.org/msg12227.html
+ *
+ * On my athlon system at least, it appears the builtin OpenSSL code is now
+ * slightly faster, which is to say that the RSA-related MPI performance
+ * between OpenSSL's BIGNUM and GMP's mpz implementations is probably pretty
+ * balanced for this chip, and so the performance degradation in this ENGINE by
+ * having to convert to/from GMP formats (and not being able to cache
+ * montgomery forms) is probably the difference. However, if some unconfirmed
+ * reports from users is anything to go by, the situation on some other
+ * chipsets might be a good deal more favourable to the GMP version (eg. PPC).
+ * Feedback welcome. */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/engine.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_GMP
+
+#include <gmp.h>
+
+#define E_GMP_LIB_NAME "gmp engine"
+#include "e_gmp_err.c"
+
+static int e_gmp_destroy(ENGINE *e);
+static int e_gmp_init(ENGINE *e);
+static int e_gmp_finish(ENGINE *e);
+static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+
+#ifndef OPENSSL_NO_RSA
+/* RSA stuff */
+static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+static int e_gmp_rsa_finish(RSA *r);
+#endif
+
+/* The definitions for control commands specific to this engine */
+/* #define E_GMP_CMD_SO_PATH ENGINE_CMD_BASE */
+static const ENGINE_CMD_DEFN e_gmp_cmd_defns[] = {
+#if 0
+ {E_GMP_CMD_SO_PATH,
+ "SO_PATH",
+ "Specifies the path to the 'e_gmp' shared library",
+ ENGINE_CMD_FLAG_STRING},
+#endif
+ {0, NULL, NULL, 0}
+ };
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD e_gmp_rsa =
+ {
+ "GMP RSA method",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ e_gmp_rsa_mod_exp,
+ NULL,
+ NULL,
+ e_gmp_rsa_finish,
+ /* These flags initialise montgomery crud that GMP ignores, however it
+ * makes sure the public key ops (which are done in openssl) don't seem
+ * *slower* than usual :-) */
+ RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE,
+ NULL,
+ NULL,
+ NULL
+ };
+#endif
+
+/* Constants used when creating the ENGINE */
+static const char *engine_e_gmp_id = "gmp";
+static const char *engine_e_gmp_name = "GMP engine support";
+
+/* This internal function is used by ENGINE_gmp() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+ {
+#ifndef OPENSSL_NO_RSA
+ const RSA_METHOD *meth1;
+#endif
+ if(!ENGINE_set_id(e, engine_e_gmp_id) ||
+ !ENGINE_set_name(e, engine_e_gmp_name) ||
+#ifndef OPENSSL_NO_RSA
+ !ENGINE_set_RSA(e, &e_gmp_rsa) ||
+#endif
+ !ENGINE_set_destroy_function(e, e_gmp_destroy) ||
+ !ENGINE_set_init_function(e, e_gmp_init) ||
+ !ENGINE_set_finish_function(e, e_gmp_finish) ||
+ !ENGINE_set_ctrl_function(e, e_gmp_ctrl) ||
+ !ENGINE_set_cmd_defns(e, e_gmp_cmd_defns))
+ return 0;
+
+#ifndef OPENSSL_NO_RSA
+ meth1 = RSA_PKCS1_SSLeay();
+ e_gmp_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+ e_gmp_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+ e_gmp_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+ e_gmp_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+ e_gmp_rsa.bn_mod_exp = meth1->bn_mod_exp;
+#endif
+
+ /* Ensure the e_gmp error handling is set up */
+ ERR_load_GMP_strings();
+ return 1;
+ }
+
+static ENGINE *engine_gmp(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_helper(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_gmp(void)
+ {
+ /* Copied from eng_[openssl|dyn].c */
+ ENGINE *toadd = engine_gmp();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+
+#ifndef OPENSSL_NO_RSA
+/* Used to attach our own key-data to an RSA structure */
+static int hndidx_rsa = -1;
+#endif
+
+static int e_gmp_destroy(ENGINE *e)
+ {
+ ERR_unload_GMP_strings();
+ return 1;
+ }
+
+/* (de)initialisation functions. */
+static int e_gmp_init(ENGINE *e)
+ {
+#ifndef OPENSSL_NO_RSA
+ if (hndidx_rsa == -1)
+ hndidx_rsa = RSA_get_ex_new_index(0,
+ "GMP-based RSA key handle",
+ NULL, NULL, NULL);
+#endif
+ if (hndidx_rsa == -1)
+ return 0;
+ return 1;
+ }
+
+static int e_gmp_finish(ENGINE *e)
+ {
+ return 1;
+ }
+
+static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+ {
+ int to_return = 1;
+
+ switch(cmd)
+ {
+#if 0
+ case E_GMP_CMD_SO_PATH:
+ /* ... */
+#endif
+ /* The command isn't understood by this engine */
+ default:
+ GMPerr(GMP_F_E_GMP_CTRL,
+ GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+ to_return = 0;
+ break;
+ }
+
+ return to_return;
+ }
+
+
+/* Most often limb sizes will be the same. If not, we use hex conversion
+ * which is neat, but extremely inefficient. */
+static int bn2gmp(const BIGNUM *bn, mpz_t g)
+ {
+ bn_check_top(bn);
+ if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) &&
+ (BN_BITS2 == GMP_NUMB_BITS))
+ {
+ /* The common case */
+ if(!_mpz_realloc (g, bn->top))
+ return 0;
+ memcpy(&g->_mp_d[0], &bn->d[0], bn->top * sizeof(bn->d[0]));
+ g->_mp_size = bn->top;
+ if(bn->neg)
+ g->_mp_size = -g->_mp_size;
+ return 1;
+ }
+ else
+ {
+ int toret;
+ char *tmpchar = BN_bn2hex(bn);
+ if(!tmpchar) return 0;
+ toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0);
+ OPENSSL_free(tmpchar);
+ return toret;
+ }
+ }
+
+static int gmp2bn(mpz_t g, BIGNUM *bn)
+ {
+ if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) &&
+ (BN_BITS2 == GMP_NUMB_BITS))
+ {
+ /* The common case */
+ int s = (g->_mp_size >= 0) ? g->_mp_size : -g->_mp_size;
+ BN_zero(bn);
+ if(bn_expand2 (bn, s) == NULL)
+ return 0;
+ bn->top = s;
+ memcpy(&bn->d[0], &g->_mp_d[0], s * sizeof(bn->d[0]));
+ bn_correct_top(bn);
+ bn->neg = g->_mp_size >= 0 ? 0 : 1;
+ return 1;
+ }
+ else
+ {
+ int toret;
+ char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10);
+ if(!tmpchar) return 0;
+ mpz_get_str(tmpchar, 16, g);
+ toret = BN_hex2bn(&bn, tmpchar);
+ OPENSSL_free(tmpchar);
+ return toret;
+ }
+ }
+
+#ifndef OPENSSL_NO_RSA
+typedef struct st_e_gmp_rsa_ctx
+ {
+ int public_only;
+ mpz_t n;
+ mpz_t d;
+ mpz_t e;
+ mpz_t p;
+ mpz_t q;
+ mpz_t dmp1;
+ mpz_t dmq1;
+ mpz_t iqmp;
+ mpz_t r0, r1, I0, m1;
+ } E_GMP_RSA_CTX;
+
+static E_GMP_RSA_CTX *e_gmp_get_rsa(RSA *rsa)
+ {
+ E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa);
+ if(hptr) return hptr;
+ hptr = OPENSSL_malloc(sizeof(E_GMP_RSA_CTX));
+ if(!hptr) return NULL;
+ /* These inits could probably be replaced by more intelligent
+ * mpz_init2() versions, to reduce malloc-thrashing. */
+ mpz_init(hptr->n);
+ mpz_init(hptr->d);
+ mpz_init(hptr->e);
+ mpz_init(hptr->p);
+ mpz_init(hptr->q);
+ mpz_init(hptr->dmp1);
+ mpz_init(hptr->dmq1);
+ mpz_init(hptr->iqmp);
+ mpz_init(hptr->r0);
+ mpz_init(hptr->r1);
+ mpz_init(hptr->I0);
+ mpz_init(hptr->m1);
+ if(!bn2gmp(rsa->n, hptr->n) || !bn2gmp(rsa->e, hptr->e))
+ goto err;
+ if(!rsa->p || !rsa->q || !rsa->d || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
+ {
+ hptr->public_only = 1;
+ return hptr;
+ }
+ if(!bn2gmp(rsa->d, hptr->d) || !bn2gmp(rsa->p, hptr->p) ||
+ !bn2gmp(rsa->q, hptr->q) || !bn2gmp(rsa->dmp1, hptr->dmp1) ||
+ !bn2gmp(rsa->dmq1, hptr->dmq1) || !bn2gmp(rsa->iqmp, hptr->iqmp))
+ goto err;
+ hptr->public_only = 0;
+ RSA_set_ex_data(rsa, hndidx_rsa, hptr);
+ return hptr;
+err:
+ mpz_clear(hptr->n);
+ mpz_clear(hptr->d);
+ mpz_clear(hptr->e);
+ mpz_clear(hptr->p);
+ mpz_clear(hptr->q);
+ mpz_clear(hptr->dmp1);
+ mpz_clear(hptr->dmq1);
+ mpz_clear(hptr->iqmp);
+ mpz_clear(hptr->r0);
+ mpz_clear(hptr->r1);
+ mpz_clear(hptr->I0);
+ mpz_clear(hptr->m1);
+ OPENSSL_free(hptr);
+ return NULL;
+ }
+
+static int e_gmp_rsa_finish(RSA *rsa)
+ {
+ E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa);
+ if(!hptr) return 0;
+ mpz_clear(hptr->n);
+ mpz_clear(hptr->d);
+ mpz_clear(hptr->e);
+ mpz_clear(hptr->p);
+ mpz_clear(hptr->q);
+ mpz_clear(hptr->dmp1);
+ mpz_clear(hptr->dmq1);
+ mpz_clear(hptr->iqmp);
+ mpz_clear(hptr->r0);
+ mpz_clear(hptr->r1);
+ mpz_clear(hptr->I0);
+ mpz_clear(hptr->m1);
+ OPENSSL_free(hptr);
+ RSA_set_ex_data(rsa, hndidx_rsa, NULL);
+ return 1;
+ }
+
+static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+ {
+ E_GMP_RSA_CTX *hptr;
+ int to_return = 0;
+
+ hptr = e_gmp_get_rsa(rsa);
+ if(!hptr)
+ {
+ GMPerr(GMP_F_E_GMP_RSA_MOD_EXP,
+ GMP_R_KEY_CONTEXT_ERROR);
+ return 0;
+ }
+ if(hptr->public_only)
+ {
+ GMPerr(GMP_F_E_GMP_RSA_MOD_EXP,
+ GMP_R_MISSING_KEY_COMPONENTS);
+ return 0;
+ }
+
+ /* ugh!!! */
+ if(!bn2gmp(I, hptr->I0))
+ return 0;
+
+ /* This is basically the CRT logic in crypto/rsa/rsa_eay.c reworded into
+ * GMP-speak. It may be that GMP's API facilitates cleaner formulations
+ * of this stuff, eg. better handling of negatives, or functions that
+ * combine operations. */
+
+ mpz_mod(hptr->r1, hptr->I0, hptr->q);
+ mpz_powm(hptr->m1, hptr->r1, hptr->dmq1, hptr->q);
+
+ mpz_mod(hptr->r1, hptr->I0, hptr->p);
+ mpz_powm(hptr->r0, hptr->r1, hptr->dmp1, hptr->p);
+
+ mpz_sub(hptr->r0, hptr->r0, hptr->m1);
+
+ if(mpz_sgn(hptr->r0) < 0)
+ mpz_add(hptr->r0, hptr->r0, hptr->p);
+ mpz_mul(hptr->r1, hptr->r0, hptr->iqmp);
+ mpz_mod(hptr->r0, hptr->r1, hptr->p);
+
+ if(mpz_sgn(hptr->r0) < 0)
+ mpz_add(hptr->r0, hptr->r0, hptr->p);
+ mpz_mul(hptr->r1, hptr->r0, hptr->q);
+ mpz_add(hptr->r0, hptr->r1, hptr->m1);
+
+ /* ugh!!! */
+ if(gmp2bn(hptr->r0, r))
+ to_return = 1;
+
+ return 1;
+ }
+#endif
+
+#endif /* !OPENSSL_NO_GMP */
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+IMPLEMENT_DYNAMIC_CHECK_FN()
+#ifndef OPENSSL_NO_GMP
+static int bind_fn(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_e_gmp_id) != 0))
+ return 0;
+ if(!bind_helper(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#else
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
+#endif
+#endif /* !OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_padlock.c b/openssl/engines/e_padlock.c
index dbeff3bb8..7d0941980 100644
--- a/openssl/engines/e_padlock.c
+++ b/openssl/engines/e_padlock.c
@@ -1,1233 +1,1233 @@
-/*
- * Support for VIA PadLock Advanced Cryptography Engine (ACE)
- * Written by Michal Ludvig <michal@logix.cz>
- * http://www.logix.cz/michal
- *
- * Big thanks to Andy Polyakov for a help with optimization,
- * assembler fixes, port to MS Windows and a lot of other
- * valuable work on this engine!
- */
-
-/* ====================================================================
- * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-
-#include <stdio.h>
-#include <string.h>
-
-#include <openssl/opensslconf.h>
-#include <openssl/crypto.h>
-#include <openssl/dso.h>
-#include <openssl/engine.h>
-#include <openssl/evp.h>
-#ifndef OPENSSL_NO_AES
-#include <openssl/aes.h>
-#endif
-#include <openssl/rand.h>
-#include <openssl/err.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_PADLOCK
-
-/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
-#if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
-# ifndef OPENSSL_NO_DYNAMIC_ENGINE
-# define DYNAMIC_ENGINE
-# endif
-#elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
-# ifdef ENGINE_DYNAMIC_SUPPORT
-# define DYNAMIC_ENGINE
-# endif
-#else
-# error "Only OpenSSL >= 0.9.7 is supported"
-#endif
-
-/* VIA PadLock AES is available *ONLY* on some x86 CPUs.
- Not only that it doesn't exist elsewhere, but it
- even can't be compiled on other platforms!
-
- In addition, because of the heavy use of inline assembler,
- compiler choice is limited to GCC and Microsoft C. */
-#undef COMPILE_HW_PADLOCK
-#if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
-# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
- (defined(_MSC_VER) && defined(_M_IX86))
-# define COMPILE_HW_PADLOCK
-static ENGINE *ENGINE_padlock (void);
-# endif
-#endif
-
-#ifdef OPENSSL_NO_DYNAMIC_ENGINE
-
-void ENGINE_load_padlock (void)
-{
-/* On non-x86 CPUs it just returns. */
-#ifdef COMPILE_HW_PADLOCK
- ENGINE *toadd = ENGINE_padlock ();
- if (!toadd) return;
- ENGINE_add (toadd);
- ENGINE_free (toadd);
- ERR_clear_error ();
-#endif
-}
-
-#endif
-
-#ifdef COMPILE_HW_PADLOCK
-/* We do these includes here to avoid header problems on platforms that
- do not have the VIA padlock anyway... */
-#include <stdlib.h>
-#ifdef _WIN32
-# include <malloc.h>
-# ifndef alloca
-# define alloca _alloca
-# endif
-#elif defined(__GNUC__)
-# ifndef alloca
-# define alloca(s) __builtin_alloca(s)
-# endif
-#endif
-
-/* Function for ENGINE detection and control */
-static int padlock_available(void);
-static int padlock_init(ENGINE *e);
-
-/* RNG Stuff */
-static RAND_METHOD padlock_rand;
-
-/* Cipher Stuff */
-#ifndef OPENSSL_NO_AES
-static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
-#endif
-
-/* Engine names */
-static const char *padlock_id = "padlock";
-static char padlock_name[100];
-
-/* Available features */
-static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
-static int padlock_use_rng = 0; /* Random Number Generator */
-#ifndef OPENSSL_NO_AES
-static int padlock_aes_align_required = 1;
-#endif
-
-/* ===== Engine "management" functions ===== */
-
-/* Prepare the ENGINE structure for registration */
-static int
-padlock_bind_helper(ENGINE *e)
-{
- /* Check available features */
- padlock_available();
-
-#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */
- padlock_use_rng=0;
-#endif
-
- /* Generate a nice engine name with available features */
- BIO_snprintf(padlock_name, sizeof(padlock_name),
- "VIA PadLock (%s, %s)",
- padlock_use_rng ? "RNG" : "no-RNG",
- padlock_use_ace ? "ACE" : "no-ACE");
-
- /* Register everything or return with an error */
- if (!ENGINE_set_id(e, padlock_id) ||
- !ENGINE_set_name(e, padlock_name) ||
-
- !ENGINE_set_init_function(e, padlock_init) ||
-#ifndef OPENSSL_NO_AES
- (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
-#endif
- (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
- return 0;
- }
-
- /* Everything looks good */
- return 1;
-}
-
-/* Constructor */
-static ENGINE *
-ENGINE_padlock(void)
-{
- ENGINE *eng = ENGINE_new();
-
- if (!eng) {
- return NULL;
- }
-
- if (!padlock_bind_helper(eng)) {
- ENGINE_free(eng);
- return NULL;
- }
-
- return eng;
-}
-
-/* Check availability of the engine */
-static int
-padlock_init(ENGINE *e)
-{
- return (padlock_use_rng || padlock_use_ace);
-}
-
-/* This stuff is needed if this ENGINE is being compiled into a self-contained
- * shared-library.
- */
-#ifdef DYNAMIC_ENGINE
-static int
-padlock_bind_fn(ENGINE *e, const char *id)
-{
- if (id && (strcmp(id, padlock_id) != 0)) {
- return 0;
- }
-
- if (!padlock_bind_helper(e)) {
- return 0;
- }
-
- return 1;
-}
-
-IMPLEMENT_DYNAMIC_CHECK_FN()
-IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn)
-#endif /* DYNAMIC_ENGINE */
-
-/* ===== Here comes the "real" engine ===== */
-
-#ifndef OPENSSL_NO_AES
-/* Some AES-related constants */
-#define AES_BLOCK_SIZE 16
-#define AES_KEY_SIZE_128 16
-#define AES_KEY_SIZE_192 24
-#define AES_KEY_SIZE_256 32
-
-/* Here we store the status information relevant to the
- current context. */
-/* BIG FAT WARNING:
- * Inline assembler in PADLOCK_XCRYPT_ASM()
- * depends on the order of items in this structure.
- * Don't blindly modify, reorder, etc!
- */
-struct padlock_cipher_data
-{
- unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */
- union { unsigned int pad[4];
- struct {
- int rounds:4;
- int dgst:1; /* n/a in C3 */
- int align:1; /* n/a in C3 */
- int ciphr:1; /* n/a in C3 */
- unsigned int keygen:1;
- int interm:1;
- unsigned int encdec:1;
- int ksize:2;
- } b;
- } cword; /* Control word */
- AES_KEY ks; /* Encryption key */
-};
-
-/*
- * Essentially this variable belongs in thread local storage.
- * Having this variable global on the other hand can only cause
- * few bogus key reloads [if any at all on single-CPU system],
- * so we accept the penatly...
- */
-static volatile struct padlock_cipher_data *padlock_saved_context;
-#endif
-
-/*
- * =======================================================
- * Inline assembler section(s).
- * =======================================================
- * Order of arguments is chosen to facilitate Windows port
- * using __fastcall calling convention. If you wish to add
- * more routines, keep in mind that first __fastcall
- * argument is passed in %ecx and second - in %edx.
- * =======================================================
- */
-#if defined(__GNUC__) && __GNUC__>=2
-/*
- * As for excessive "push %ebx"/"pop %ebx" found all over.
- * When generating position-independent code GCC won't let
- * us use "b" in assembler templates nor even respect "ebx"
- * in "clobber description." Therefore the trouble...
- */
-
-/* Helper function - check if a CPUID instruction
- is available on this CPU */
-static int
-padlock_insn_cpuid_available(void)
-{
- int result = -1;
-
- /* We're checking if the bit #21 of EFLAGS
- can be toggled. If yes = CPUID is available. */
- asm volatile (
- "pushf\n"
- "popl %%eax\n"
- "xorl $0x200000, %%eax\n"
- "movl %%eax, %%ecx\n"
- "andl $0x200000, %%ecx\n"
- "pushl %%eax\n"
- "popf\n"
- "pushf\n"
- "popl %%eax\n"
- "andl $0x200000, %%eax\n"
- "xorl %%eax, %%ecx\n"
- "movl %%ecx, %0\n"
- : "=r" (result) : : "eax", "ecx");
-
- return (result == 0);
-}
-
-/* Load supported features of the CPU to see if
- the PadLock is available. */
-static int
-padlock_available(void)
-{
- char vendor_string[16];
- unsigned int eax, edx;
-
- /* First check if the CPUID instruction is available at all... */
- if (! padlock_insn_cpuid_available())
- return 0;
-
- /* Are we running on the Centaur (VIA) CPU? */
- eax = 0x00000000;
- vendor_string[12] = 0;
- asm volatile (
- "pushl %%ebx\n"
- "cpuid\n"
- "movl %%ebx,(%%edi)\n"
- "movl %%edx,4(%%edi)\n"
- "movl %%ecx,8(%%edi)\n"
- "popl %%ebx"
- : "+a"(eax) : "D"(vendor_string) : "ecx", "edx");
- if (strcmp(vendor_string, "CentaurHauls") != 0)
- return 0;
-
- /* Check for Centaur Extended Feature Flags presence */
- eax = 0xC0000000;
- asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
- : "+a"(eax) : : "ecx", "edx");
- if (eax < 0xC0000001)
- return 0;
-
- /* Read the Centaur Extended Feature Flags */
- eax = 0xC0000001;
- asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
- : "+a"(eax), "=d"(edx) : : "ecx");
-
- /* Fill up some flags */
- padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
- padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
-
- return padlock_use_ace + padlock_use_rng;
-}
-
-#ifndef OPENSSL_NO_AES
-/* Our own htonl()/ntohl() */
-static inline void
-padlock_bswapl(AES_KEY *ks)
-{
- size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
- unsigned int *key = ks->rd_key;
-
- while (i--) {
- asm volatile ("bswapl %0" : "+r"(*key));
- key++;
- }
-}
-#endif
-
-/* Force key reload from memory to the CPU microcode.
- Loading EFLAGS from the stack clears EFLAGS[30]
- which does the trick. */
-static inline void
-padlock_reload_key(void)
-{
- asm volatile ("pushfl; popfl");
-}
-
-#ifndef OPENSSL_NO_AES
-/*
- * This is heuristic key context tracing. At first one
- * believes that one should use atomic swap instructions,
- * but it's not actually necessary. Point is that if
- * padlock_saved_context was changed by another thread
- * after we've read it and before we compare it with cdata,
- * our key *shall* be reloaded upon thread context switch
- * and we are therefore set in either case...
- */
-static inline void
-padlock_verify_context(struct padlock_cipher_data *cdata)
-{
- asm volatile (
- "pushfl\n"
-" btl $30,(%%esp)\n"
-" jnc 1f\n"
-" cmpl %2,%1\n"
-" je 1f\n"
-" popfl\n"
-" subl $4,%%esp\n"
-"1: addl $4,%%esp\n"
-" movl %2,%0"
- :"+m"(padlock_saved_context)
- : "r"(padlock_saved_context), "r"(cdata) : "cc");
-}
-
-/* Template for padlock_xcrypt_* modes */
-/* BIG FAT WARNING:
- * The offsets used with 'leal' instructions
- * describe items of the 'padlock_cipher_data'
- * structure.
- */
-#define PADLOCK_XCRYPT_ASM(name,rep_xcrypt) \
-static inline void *name(size_t cnt, \
- struct padlock_cipher_data *cdata, \
- void *out, const void *inp) \
-{ void *iv; \
- asm volatile ( "pushl %%ebx\n" \
- " leal 16(%0),%%edx\n" \
- " leal 32(%0),%%ebx\n" \
- rep_xcrypt "\n" \
- " popl %%ebx" \
- : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
- : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \
- : "edx", "cc", "memory"); \
- return iv; \
-}
-
-/* Generate all functions with appropriate opcodes */
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") /* rep xcryptecb */
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") /* rep xcryptcbc */
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") /* rep xcryptcfb */
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") /* rep xcryptofb */
-#endif
-
-/* The RNG call itself */
-static inline unsigned int
-padlock_xstore(void *addr, unsigned int edx_in)
-{
- unsigned int eax_out;
-
- asm volatile (".byte 0x0f,0xa7,0xc0" /* xstore */
- : "=a"(eax_out),"=m"(*(unsigned *)addr)
- : "D"(addr), "d" (edx_in)
- );
-
- return eax_out;
-}
-
-/* Why not inline 'rep movsd'? I failed to find information on what
- * value in Direction Flag one can expect and consequently have to
- * apply "better-safe-than-sorry" approach and assume "undefined."
- * I could explicitly clear it and restore the original value upon
- * return from padlock_aes_cipher, but it's presumably too much
- * trouble for too little gain...
- *
- * In case you wonder 'rep xcrypt*' instructions above are *not*
- * affected by the Direction Flag and pointers advance toward
- * larger addresses unconditionally.
- */
-static inline unsigned char *
-padlock_memcpy(void *dst,const void *src,size_t n)
-{
- long *d=dst;
- const long *s=src;
-
- n /= sizeof(*d);
- do { *d++ = *s++; } while (--n);
-
- return dst;
-}
-
-#elif defined(_MSC_VER)
-/*
- * Unlike GCC these are real functions. In order to minimize impact
- * on performance we adhere to __fastcall calling convention in
- * order to get two first arguments passed through %ecx and %edx.
- * Which kind of suits very well, as instructions in question use
- * both %ecx and %edx as input:-)
- */
-#define REP_XCRYPT(code) \
- _asm _emit 0xf3 \
- _asm _emit 0x0f _asm _emit 0xa7 \
- _asm _emit code
-
-/* BIG FAT WARNING:
- * The offsets used with 'lea' instructions
- * describe items of the 'padlock_cipher_data'
- * structure.
- */
-#define PADLOCK_XCRYPT_ASM(name,code) \
-static void * __fastcall \
- name (size_t cnt, void *cdata, \
- void *outp, const void *inp) \
-{ _asm mov eax,edx \
- _asm lea edx,[eax+16] \
- _asm lea ebx,[eax+32] \
- _asm mov edi,outp \
- _asm mov esi,inp \
- REP_XCRYPT(code) \
-}
-
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
-
-static int __fastcall
-padlock_xstore(void *outp,unsigned int code)
-{ _asm mov edi,ecx
- _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
-}
-
-static void __fastcall
-padlock_reload_key(void)
-{ _asm pushfd _asm popfd }
-
-static void __fastcall
-padlock_verify_context(void *cdata)
-{ _asm {
- pushfd
- bt DWORD PTR[esp],30
- jnc skip
- cmp ecx,padlock_saved_context
- je skip
- popfd
- sub esp,4
- skip: add esp,4
- mov padlock_saved_context,ecx
- }
-}
-
-static int
-padlock_available(void)
-{ _asm {
- pushfd
- pop eax
- mov ecx,eax
- xor eax,1<<21
- push eax
- popfd
- pushfd
- pop eax
- xor eax,ecx
- bt eax,21
- jnc noluck
- mov eax,0
- cpuid
- xor eax,eax
- cmp ebx,'tneC'
- jne noluck
- cmp edx,'Hrua'
- jne noluck
- cmp ecx,'slua'
- jne noluck
- mov eax,0xC0000000
- cpuid
- mov edx,eax
- xor eax,eax
- cmp edx,0xC0000001
- jb noluck
- mov eax,0xC0000001
- cpuid
- xor eax,eax
- bt edx,6
- jnc skip_a
- bt edx,7
- jnc skip_a
- mov padlock_use_ace,1
- inc eax
- skip_a: bt edx,2
- jnc skip_r
- bt edx,3
- jnc skip_r
- mov padlock_use_rng,1
- inc eax
- skip_r:
- noluck:
- }
-}
-
-static void __fastcall
-padlock_bswapl(void *key)
-{ _asm {
- pushfd
- cld
- mov esi,ecx
- mov edi,ecx
- mov ecx,60
- up: lodsd
- bswap eax
- stosd
- loop up
- popfd
- }
-}
-
-/* MS actually specifies status of Direction Flag and compiler even
- * manages to compile following as 'rep movsd' all by itself...
- */
-#define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
-#endif
-
-/* ===== AES encryption/decryption ===== */
-#ifndef OPENSSL_NO_AES
-
-#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
-#define NID_aes_128_cfb NID_aes_128_cfb128
-#endif
-
-#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
-#define NID_aes_128_ofb NID_aes_128_ofb128
-#endif
-
-#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
-#define NID_aes_192_cfb NID_aes_192_cfb128
-#endif
-
-#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
-#define NID_aes_192_ofb NID_aes_192_ofb128
-#endif
-
-#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
-#define NID_aes_256_cfb NID_aes_256_cfb128
-#endif
-
-#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
-#define NID_aes_256_ofb NID_aes_256_ofb128
-#endif
-
-/* List of supported ciphers. */
-static int padlock_cipher_nids[] = {
- NID_aes_128_ecb,
- NID_aes_128_cbc,
- NID_aes_128_cfb,
- NID_aes_128_ofb,
-
- NID_aes_192_ecb,
- NID_aes_192_cbc,
- NID_aes_192_cfb,
- NID_aes_192_ofb,
-
- NID_aes_256_ecb,
- NID_aes_256_cbc,
- NID_aes_256_cfb,
- NID_aes_256_ofb,
-};
-static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
- sizeof(padlock_cipher_nids[0]));
-
-/* Function prototypes ... */
-static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc);
-static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, size_t nbytes);
-
-#define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \
- ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) )
-#define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
- NEAREST_ALIGNED(ctx->cipher_data))
-
-#define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE
-#define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE
-#define EVP_CIPHER_block_size_OFB 1
-#define EVP_CIPHER_block_size_CFB 1
-
-/* Declaring so many ciphers by hand would be a pain.
- Instead introduce a bit of preprocessor magic :-) */
-#define DECLARE_AES_EVP(ksize,lmode,umode) \
-static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \
- NID_aes_##ksize##_##lmode, \
- EVP_CIPHER_block_size_##umode, \
- AES_KEY_SIZE_##ksize, \
- AES_BLOCK_SIZE, \
- 0 | EVP_CIPH_##umode##_MODE, \
- padlock_aes_init_key, \
- padlock_aes_cipher, \
- NULL, \
- sizeof(struct padlock_cipher_data) + 16, \
- EVP_CIPHER_set_asn1_iv, \
- EVP_CIPHER_get_asn1_iv, \
- NULL, \
- NULL \
-}
-
-DECLARE_AES_EVP(128,ecb,ECB);
-DECLARE_AES_EVP(128,cbc,CBC);
-DECLARE_AES_EVP(128,cfb,CFB);
-DECLARE_AES_EVP(128,ofb,OFB);
-
-DECLARE_AES_EVP(192,ecb,ECB);
-DECLARE_AES_EVP(192,cbc,CBC);
-DECLARE_AES_EVP(192,cfb,CFB);
-DECLARE_AES_EVP(192,ofb,OFB);
-
-DECLARE_AES_EVP(256,ecb,ECB);
-DECLARE_AES_EVP(256,cbc,CBC);
-DECLARE_AES_EVP(256,cfb,CFB);
-DECLARE_AES_EVP(256,ofb,OFB);
-
-static int
-padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
-{
- /* No specific cipher => return a list of supported nids ... */
- if (!cipher) {
- *nids = padlock_cipher_nids;
- return padlock_cipher_nids_num;
- }
-
- /* ... or the requested "cipher" otherwise */
- switch (nid) {
- case NID_aes_128_ecb:
- *cipher = &padlock_aes_128_ecb;
- break;
- case NID_aes_128_cbc:
- *cipher = &padlock_aes_128_cbc;
- break;
- case NID_aes_128_cfb:
- *cipher = &padlock_aes_128_cfb;
- break;
- case NID_aes_128_ofb:
- *cipher = &padlock_aes_128_ofb;
- break;
-
- case NID_aes_192_ecb:
- *cipher = &padlock_aes_192_ecb;
- break;
- case NID_aes_192_cbc:
- *cipher = &padlock_aes_192_cbc;
- break;
- case NID_aes_192_cfb:
- *cipher = &padlock_aes_192_cfb;
- break;
- case NID_aes_192_ofb:
- *cipher = &padlock_aes_192_ofb;
- break;
-
- case NID_aes_256_ecb:
- *cipher = &padlock_aes_256_ecb;
- break;
- case NID_aes_256_cbc:
- *cipher = &padlock_aes_256_cbc;
- break;
- case NID_aes_256_cfb:
- *cipher = &padlock_aes_256_cfb;
- break;
- case NID_aes_256_ofb:
- *cipher = &padlock_aes_256_ofb;
- break;
-
- default:
- /* Sorry, we don't support this NID */
- *cipher = NULL;
- return 0;
- }
-
- return 1;
-}
-
-/* Prepare the encryption key for PadLock usage */
-static int
-padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc)
-{
- struct padlock_cipher_data *cdata;
- int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
-
- if (key==NULL) return 0; /* ERROR */
-
- cdata = ALIGNED_CIPHER_DATA(ctx);
- memset(cdata, 0, sizeof(struct padlock_cipher_data));
-
- /* Prepare Control word. */
- if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
- cdata->cword.b.encdec = 0;
- else
- cdata->cword.b.encdec = (ctx->encrypt == 0);
- cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
- cdata->cword.b.ksize = (key_len - 128) / 64;
-
- switch(key_len) {
- case 128:
- /* PadLock can generate an extended key for
- AES128 in hardware */
- memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
- cdata->cword.b.keygen = 0;
- break;
-
- case 192:
- case 256:
- /* Generate an extended AES key in software.
- Needed for AES192/AES256 */
- /* Well, the above applies to Stepping 8 CPUs
- and is listed as hardware errata. They most
- likely will fix it at some point and then
- a check for stepping would be due here. */
- if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE ||
- EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE ||
- enc)
- AES_set_encrypt_key(key, key_len, &cdata->ks);
- else
- AES_set_decrypt_key(key, key_len, &cdata->ks);
-#ifndef AES_ASM
- /* OpenSSL C functions use byte-swapped extended key. */
- padlock_bswapl(&cdata->ks);
-#endif
- cdata->cword.b.keygen = 1;
- break;
-
- default:
- /* ERROR */
- return 0;
- }
-
- /*
- * This is done to cover for cases when user reuses the
- * context for new key. The catch is that if we don't do
- * this, padlock_eas_cipher might proceed with old key...
- */
- padlock_reload_key ();
-
- return 1;
-}
-
-/*
- * Simplified version of padlock_aes_cipher() used when
- * 1) both input and output buffers are at aligned addresses.
- * or when
- * 2) running on a newer CPU that doesn't require aligned buffers.
- */
-static int
-padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
- const unsigned char *in_arg, size_t nbytes)
-{
- struct padlock_cipher_data *cdata;
- void *iv;
-
- cdata = ALIGNED_CIPHER_DATA(ctx);
- padlock_verify_context(cdata);
-
- switch (EVP_CIPHER_CTX_mode(ctx)) {
- case EVP_CIPH_ECB_MODE:
- padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
- break;
-
- case EVP_CIPH_CBC_MODE:
- memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
- iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
- memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
- break;
-
- case EVP_CIPH_CFB_MODE:
- memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
- iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
- memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
- break;
-
- case EVP_CIPH_OFB_MODE:
- memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
- padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
- memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
- break;
-
- default:
- return 0;
- }
-
- memset(cdata->iv, 0, AES_BLOCK_SIZE);
-
- return 1;
-}
-
-#ifndef PADLOCK_CHUNK
-# define PADLOCK_CHUNK 512 /* Must be a power of 2 larger than 16 */
-#endif
-#if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
-# error "insane PADLOCK_CHUNK..."
-#endif
-
-/* Re-align the arguments to 16-Bytes boundaries and run the
- encryption function itself. This function is not AES-specific. */
-static int
-padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
- const unsigned char *in_arg, size_t nbytes)
-{
- struct padlock_cipher_data *cdata;
- const void *inp;
- unsigned char *out;
- void *iv;
- int inp_misaligned, out_misaligned, realign_in_loop;
- size_t chunk, allocated=0;
-
- /* ctx->num is maintained in byte-oriented modes,
- such as CFB and OFB... */
- if ((chunk = ctx->num)) { /* borrow chunk variable */
- unsigned char *ivp=ctx->iv;
-
- switch (EVP_CIPHER_CTX_mode(ctx)) {
- case EVP_CIPH_CFB_MODE:
- if (chunk >= AES_BLOCK_SIZE)
- return 0; /* bogus value */
-
- if (ctx->encrypt)
- while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
- ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
- chunk++, nbytes--;
- }
- else while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
- unsigned char c = *(in_arg++);
- *(out_arg++) = c ^ ivp[chunk];
- ivp[chunk++] = c, nbytes--;
- }
-
- ctx->num = chunk%AES_BLOCK_SIZE;
- break;
- case EVP_CIPH_OFB_MODE:
- if (chunk >= AES_BLOCK_SIZE)
- return 0; /* bogus value */
-
- while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
- *(out_arg++) = *(in_arg++) ^ ivp[chunk];
- chunk++, nbytes--;
- }
-
- ctx->num = chunk%AES_BLOCK_SIZE;
- break;
- }
- }
-
- if (nbytes == 0)
- return 1;
-#if 0
- if (nbytes % AES_BLOCK_SIZE)
- return 0; /* are we expected to do tail processing? */
-#else
- /* nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC
- modes and arbitrary value in byte-oriented modes, such as
- CFB and OFB... */
-#endif
-
- /* VIA promises CPUs that won't require alignment in the future.
- For now padlock_aes_align_required is initialized to 1 and
- the condition is never met... */
- /* C7 core is capable to manage unaligned input in non-ECB[!]
- mode, but performance penalties appear to be approximately
- same as for software alignment below or ~3x. They promise to
- improve it in the future, but for now we can just as well
- pretend that it can only handle aligned input... */
- if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0)
- return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
-
- inp_misaligned = (((size_t)in_arg) & 0x0F);
- out_misaligned = (((size_t)out_arg) & 0x0F);
-
- /* Note that even if output is aligned and input not,
- * I still prefer to loop instead of copy the whole
- * input and then encrypt in one stroke. This is done
- * in order to improve L1 cache utilization... */
- realign_in_loop = out_misaligned|inp_misaligned;
-
- if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0)
- return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
-
- /* this takes one "if" out of the loops */
- chunk = nbytes;
- chunk %= PADLOCK_CHUNK;
- if (chunk==0) chunk = PADLOCK_CHUNK;
-
- if (out_misaligned) {
- /* optmize for small input */
- allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);
- out = alloca(0x10 + allocated);
- out = NEAREST_ALIGNED(out);
- }
- else
- out = out_arg;
-
- cdata = ALIGNED_CIPHER_DATA(ctx);
- padlock_verify_context(cdata);
-
- switch (EVP_CIPHER_CTX_mode(ctx)) {
- case EVP_CIPH_ECB_MODE:
- do {
- if (inp_misaligned)
- inp = padlock_memcpy(out, in_arg, chunk);
- else
- inp = in_arg;
- in_arg += chunk;
-
- padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
-
- if (out_misaligned)
- out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
- else
- out = out_arg+=chunk;
-
- nbytes -= chunk;
- chunk = PADLOCK_CHUNK;
- } while (nbytes);
- break;
-
- case EVP_CIPH_CBC_MODE:
- memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
- goto cbc_shortcut;
- do {
- if (iv != cdata->iv)
- memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
- chunk = PADLOCK_CHUNK;
- cbc_shortcut: /* optimize for small input */
- if (inp_misaligned)
- inp = padlock_memcpy(out, in_arg, chunk);
- else
- inp = in_arg;
- in_arg += chunk;
-
- iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
-
- if (out_misaligned)
- out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
- else
- out = out_arg+=chunk;
-
- } while (nbytes -= chunk);
- memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
- break;
-
- case EVP_CIPH_CFB_MODE:
- memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE);
- chunk &= ~(AES_BLOCK_SIZE-1);
- if (chunk) goto cfb_shortcut;
- else goto cfb_skiploop;
- do {
- if (iv != cdata->iv)
- memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
- chunk = PADLOCK_CHUNK;
- cfb_shortcut: /* optimize for small input */
- if (inp_misaligned)
- inp = padlock_memcpy(out, in_arg, chunk);
- else
- inp = in_arg;
- in_arg += chunk;
-
- iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
-
- if (out_misaligned)
- out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
- else
- out = out_arg+=chunk;
-
- nbytes -= chunk;
- } while (nbytes >= AES_BLOCK_SIZE);
-
- cfb_skiploop:
- if (nbytes) {
- unsigned char *ivp = cdata->iv;
-
- if (iv != ivp) {
- memcpy(ivp, iv, AES_BLOCK_SIZE);
- iv = ivp;
- }
- ctx->num = nbytes;
- if (cdata->cword.b.encdec) {
- cdata->cword.b.encdec=0;
- padlock_reload_key();
- padlock_xcrypt_ecb(1,cdata,ivp,ivp);
- cdata->cword.b.encdec=1;
- padlock_reload_key();
- while(nbytes) {
- unsigned char c = *(in_arg++);
- *(out_arg++) = c ^ *ivp;
- *(ivp++) = c, nbytes--;
- }
- }
- else { padlock_reload_key();
- padlock_xcrypt_ecb(1,cdata,ivp,ivp);
- padlock_reload_key();
- while (nbytes) {
- *ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
- ivp++, nbytes--;
- }
- }
- }
-
- memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
- break;
-
- case EVP_CIPH_OFB_MODE:
- memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
- chunk &= ~(AES_BLOCK_SIZE-1);
- if (chunk) do {
- if (inp_misaligned)
- inp = padlock_memcpy(out, in_arg, chunk);
- else
- inp = in_arg;
- in_arg += chunk;
-
- padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
-
- if (out_misaligned)
- out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
- else
- out = out_arg+=chunk;
-
- nbytes -= chunk;
- chunk = PADLOCK_CHUNK;
- } while (nbytes >= AES_BLOCK_SIZE);
-
- if (nbytes) {
- unsigned char *ivp = cdata->iv;
-
- ctx->num = nbytes;
- padlock_reload_key(); /* empirically found */
- padlock_xcrypt_ecb(1,cdata,ivp,ivp);
- padlock_reload_key(); /* empirically found */
- while (nbytes) {
- *(out_arg++) = *(in_arg++) ^ *ivp;
- ivp++, nbytes--;
- }
- }
-
- memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
- break;
-
- default:
- return 0;
- }
-
- /* Clean the realign buffer if it was used */
- if (out_misaligned) {
- volatile unsigned long *p=(void *)out;
- size_t n = allocated/sizeof(*p);
- while (n--) *p++=0;
- }
-
- memset(cdata->iv, 0, AES_BLOCK_SIZE);
-
- return 1;
-}
-
-#endif /* OPENSSL_NO_AES */
-
-/* ===== Random Number Generator ===== */
-/*
- * This code is not engaged. The reason is that it does not comply
- * with recommendations for VIA RNG usage for secure applications
- * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
- * provide meaningful error control...
- */
-/* Wrapper that provides an interface between the API and
- the raw PadLock RNG */
-static int
-padlock_rand_bytes(unsigned char *output, int count)
-{
- unsigned int eax, buf;
-
- while (count >= 8) {
- eax = padlock_xstore(output, 0);
- if (!(eax&(1<<6))) return 0; /* RNG disabled */
- /* this ---vv--- covers DC bias, Raw Bits and String Filter */
- if (eax&(0x1F<<10)) return 0;
- if ((eax&0x1F)==0) continue; /* no data, retry... */
- if ((eax&0x1F)!=8) return 0; /* fatal failure... */
- output += 8;
- count -= 8;
- }
- while (count > 0) {
- eax = padlock_xstore(&buf, 3);
- if (!(eax&(1<<6))) return 0; /* RNG disabled */
- /* this ---vv--- covers DC bias, Raw Bits and String Filter */
- if (eax&(0x1F<<10)) return 0;
- if ((eax&0x1F)==0) continue; /* no data, retry... */
- if ((eax&0x1F)!=1) return 0; /* fatal failure... */
- *output++ = (unsigned char)buf;
- count--;
- }
- *(volatile unsigned int *)&buf=0;
-
- return 1;
-}
-
-/* Dummy but necessary function */
-static int
-padlock_rand_status(void)
-{
- return 1;
-}
-
-/* Prepare structure for registration */
-static RAND_METHOD padlock_rand = {
- NULL, /* seed */
- padlock_rand_bytes, /* bytes */
- NULL, /* cleanup */
- NULL, /* add */
- padlock_rand_bytes, /* pseudorand */
- padlock_rand_status, /* rand status */
-};
-
-#else /* !COMPILE_HW_PADLOCK */
-#ifndef OPENSSL_NO_DYNAMIC_ENGINE
-OPENSSL_EXPORT
-int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
-OPENSSL_EXPORT
-int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
-IMPLEMENT_DYNAMIC_CHECK_FN()
-#endif
-#endif /* COMPILE_HW_PADLOCK */
-
-#endif /* !OPENSSL_NO_HW_PADLOCK */
-#endif /* !OPENSSL_NO_HW */
+/*
+ * Support for VIA PadLock Advanced Cryptography Engine (ACE)
+ * Written by Michal Ludvig <michal@logix.cz>
+ * http://www.logix.cz/michal
+ *
+ * Big thanks to Andy Polyakov for a help with optimization,
+ * assembler fixes, port to MS Windows and a lot of other
+ * valuable work on this engine!
+ */
+
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+#include <openssl/crypto.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_AES
+#include <openssl/aes.h>
+#endif
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_PADLOCK
+
+/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
+#if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
+# ifndef OPENSSL_NO_DYNAMIC_ENGINE
+# define DYNAMIC_ENGINE
+# endif
+#elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
+# ifdef ENGINE_DYNAMIC_SUPPORT
+# define DYNAMIC_ENGINE
+# endif
+#else
+# error "Only OpenSSL >= 0.9.7 is supported"
+#endif
+
+/* VIA PadLock AES is available *ONLY* on some x86 CPUs.
+ Not only that it doesn't exist elsewhere, but it
+ even can't be compiled on other platforms!
+
+ In addition, because of the heavy use of inline assembler,
+ compiler choice is limited to GCC and Microsoft C. */
+#undef COMPILE_HW_PADLOCK
+#if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
+# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
+ (defined(_MSC_VER) && defined(_M_IX86))
+# define COMPILE_HW_PADLOCK
+static ENGINE *ENGINE_padlock (void);
+# endif
+#endif
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+
+void ENGINE_load_padlock (void)
+{
+/* On non-x86 CPUs it just returns. */
+#ifdef COMPILE_HW_PADLOCK
+ ENGINE *toadd = ENGINE_padlock ();
+ if (!toadd) return;
+ ENGINE_add (toadd);
+ ENGINE_free (toadd);
+ ERR_clear_error ();
+#endif
+}
+
+#endif
+
+#ifdef COMPILE_HW_PADLOCK
+/* We do these includes here to avoid header problems on platforms that
+ do not have the VIA padlock anyway... */
+#include <stdlib.h>
+#ifdef _WIN32
+# include <malloc.h>
+# ifndef alloca
+# define alloca _alloca
+# endif
+#elif defined(__GNUC__)
+# ifndef alloca
+# define alloca(s) __builtin_alloca(s)
+# endif
+#endif
+
+/* Function for ENGINE detection and control */
+static int padlock_available(void);
+static int padlock_init(ENGINE *e);
+
+/* RNG Stuff */
+static RAND_METHOD padlock_rand;
+
+/* Cipher Stuff */
+#ifndef OPENSSL_NO_AES
+static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
+#endif
+
+/* Engine names */
+static const char *padlock_id = "padlock";
+static char padlock_name[100];
+
+/* Available features */
+static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
+static int padlock_use_rng = 0; /* Random Number Generator */
+#ifndef OPENSSL_NO_AES
+static int padlock_aes_align_required = 1;
+#endif
+
+/* ===== Engine "management" functions ===== */
+
+/* Prepare the ENGINE structure for registration */
+static int
+padlock_bind_helper(ENGINE *e)
+{
+ /* Check available features */
+ padlock_available();
+
+#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */
+ padlock_use_rng=0;
+#endif
+
+ /* Generate a nice engine name with available features */
+ BIO_snprintf(padlock_name, sizeof(padlock_name),
+ "VIA PadLock (%s, %s)",
+ padlock_use_rng ? "RNG" : "no-RNG",
+ padlock_use_ace ? "ACE" : "no-ACE");
+
+ /* Register everything or return with an error */
+ if (!ENGINE_set_id(e, padlock_id) ||
+ !ENGINE_set_name(e, padlock_name) ||
+
+ !ENGINE_set_init_function(e, padlock_init) ||
+#ifndef OPENSSL_NO_AES
+ (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
+#endif
+ (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
+ return 0;
+ }
+
+ /* Everything looks good */
+ return 1;
+}
+
+/* Constructor */
+static ENGINE *
+ENGINE_padlock(void)
+{
+ ENGINE *eng = ENGINE_new();
+
+ if (!eng) {
+ return NULL;
+ }
+
+ if (!padlock_bind_helper(eng)) {
+ ENGINE_free(eng);
+ return NULL;
+ }
+
+ return eng;
+}
+
+/* Check availability of the engine */
+static int
+padlock_init(ENGINE *e)
+{
+ return (padlock_use_rng || padlock_use_ace);
+}
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library.
+ */
+#ifdef DYNAMIC_ENGINE
+static int
+padlock_bind_fn(ENGINE *e, const char *id)
+{
+ if (id && (strcmp(id, padlock_id) != 0)) {
+ return 0;
+ }
+
+ if (!padlock_bind_helper(e)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn)
+#endif /* DYNAMIC_ENGINE */
+
+/* ===== Here comes the "real" engine ===== */
+
+#ifndef OPENSSL_NO_AES
+/* Some AES-related constants */
+#define AES_BLOCK_SIZE 16
+#define AES_KEY_SIZE_128 16
+#define AES_KEY_SIZE_192 24
+#define AES_KEY_SIZE_256 32
+
+/* Here we store the status information relevant to the
+ current context. */
+/* BIG FAT WARNING:
+ * Inline assembler in PADLOCK_XCRYPT_ASM()
+ * depends on the order of items in this structure.
+ * Don't blindly modify, reorder, etc!
+ */
+struct padlock_cipher_data
+{
+ unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */
+ union { unsigned int pad[4];
+ struct {
+ int rounds:4;
+ int dgst:1; /* n/a in C3 */
+ int align:1; /* n/a in C3 */
+ int ciphr:1; /* n/a in C3 */
+ unsigned int keygen:1;
+ int interm:1;
+ unsigned int encdec:1;
+ int ksize:2;
+ } b;
+ } cword; /* Control word */
+ AES_KEY ks; /* Encryption key */
+};
+
+/*
+ * Essentially this variable belongs in thread local storage.
+ * Having this variable global on the other hand can only cause
+ * few bogus key reloads [if any at all on single-CPU system],
+ * so we accept the penatly...
+ */
+static volatile struct padlock_cipher_data *padlock_saved_context;
+#endif
+
+/*
+ * =======================================================
+ * Inline assembler section(s).
+ * =======================================================
+ * Order of arguments is chosen to facilitate Windows port
+ * using __fastcall calling convention. If you wish to add
+ * more routines, keep in mind that first __fastcall
+ * argument is passed in %ecx and second - in %edx.
+ * =======================================================
+ */
+#if defined(__GNUC__) && __GNUC__>=2
+/*
+ * As for excessive "push %ebx"/"pop %ebx" found all over.
+ * When generating position-independent code GCC won't let
+ * us use "b" in assembler templates nor even respect "ebx"
+ * in "clobber description." Therefore the trouble...
+ */
+
+/* Helper function - check if a CPUID instruction
+ is available on this CPU */
+static int
+padlock_insn_cpuid_available(void)
+{
+ int result = -1;
+
+ /* We're checking if the bit #21 of EFLAGS
+ can be toggled. If yes = CPUID is available. */
+ asm volatile (
+ "pushf\n"
+ "popl %%eax\n"
+ "xorl $0x200000, %%eax\n"
+ "movl %%eax, %%ecx\n"
+ "andl $0x200000, %%ecx\n"
+ "pushl %%eax\n"
+ "popf\n"
+ "pushf\n"
+ "popl %%eax\n"
+ "andl $0x200000, %%eax\n"
+ "xorl %%eax, %%ecx\n"
+ "movl %%ecx, %0\n"
+ : "=r" (result) : : "eax", "ecx");
+
+ return (result == 0);
+}
+
+/* Load supported features of the CPU to see if
+ the PadLock is available. */
+static int
+padlock_available(void)
+{
+ char vendor_string[16];
+ unsigned int eax, edx;
+
+ /* First check if the CPUID instruction is available at all... */
+ if (! padlock_insn_cpuid_available())
+ return 0;
+
+ /* Are we running on the Centaur (VIA) CPU? */
+ eax = 0x00000000;
+ vendor_string[12] = 0;
+ asm volatile (
+ "pushl %%ebx\n"
+ "cpuid\n"
+ "movl %%ebx,(%%edi)\n"
+ "movl %%edx,4(%%edi)\n"
+ "movl %%ecx,8(%%edi)\n"
+ "popl %%ebx"
+ : "+a"(eax) : "D"(vendor_string) : "ecx", "edx");
+ if (strcmp(vendor_string, "CentaurHauls") != 0)
+ return 0;
+
+ /* Check for Centaur Extended Feature Flags presence */
+ eax = 0xC0000000;
+ asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
+ : "+a"(eax) : : "ecx", "edx");
+ if (eax < 0xC0000001)
+ return 0;
+
+ /* Read the Centaur Extended Feature Flags */
+ eax = 0xC0000001;
+ asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
+ : "+a"(eax), "=d"(edx) : : "ecx");
+
+ /* Fill up some flags */
+ padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
+ padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
+
+ return padlock_use_ace + padlock_use_rng;
+}
+
+#ifndef OPENSSL_NO_AES
+/* Our own htonl()/ntohl() */
+static inline void
+padlock_bswapl(AES_KEY *ks)
+{
+ size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
+ unsigned int *key = ks->rd_key;
+
+ while (i--) {
+ asm volatile ("bswapl %0" : "+r"(*key));
+ key++;
+ }
+}
+#endif
+
+/* Force key reload from memory to the CPU microcode.
+ Loading EFLAGS from the stack clears EFLAGS[30]
+ which does the trick. */
+static inline void
+padlock_reload_key(void)
+{
+ asm volatile ("pushfl; popfl");
+}
+
+#ifndef OPENSSL_NO_AES
+/*
+ * This is heuristic key context tracing. At first one
+ * believes that one should use atomic swap instructions,
+ * but it's not actually necessary. Point is that if
+ * padlock_saved_context was changed by another thread
+ * after we've read it and before we compare it with cdata,
+ * our key *shall* be reloaded upon thread context switch
+ * and we are therefore set in either case...
+ */
+static inline void
+padlock_verify_context(struct padlock_cipher_data *cdata)
+{
+ asm volatile (
+ "pushfl\n"
+" btl $30,(%%esp)\n"
+" jnc 1f\n"
+" cmpl %2,%1\n"
+" je 1f\n"
+" popfl\n"
+" subl $4,%%esp\n"
+"1: addl $4,%%esp\n"
+" movl %2,%0"
+ :"+m"(padlock_saved_context)
+ : "r"(padlock_saved_context), "r"(cdata) : "cc");
+}
+
+/* Template for padlock_xcrypt_* modes */
+/* BIG FAT WARNING:
+ * The offsets used with 'leal' instructions
+ * describe items of the 'padlock_cipher_data'
+ * structure.
+ */
+#define PADLOCK_XCRYPT_ASM(name,rep_xcrypt) \
+static inline void *name(size_t cnt, \
+ struct padlock_cipher_data *cdata, \
+ void *out, const void *inp) \
+{ void *iv; \
+ asm volatile ( "pushl %%ebx\n" \
+ " leal 16(%0),%%edx\n" \
+ " leal 32(%0),%%ebx\n" \
+ rep_xcrypt "\n" \
+ " popl %%ebx" \
+ : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
+ : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \
+ : "edx", "cc", "memory"); \
+ return iv; \
+}
+
+/* Generate all functions with appropriate opcodes */
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") /* rep xcryptecb */
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") /* rep xcryptcbc */
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") /* rep xcryptcfb */
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") /* rep xcryptofb */
+#endif
+
+/* The RNG call itself */
+static inline unsigned int
+padlock_xstore(void *addr, unsigned int edx_in)
+{
+ unsigned int eax_out;
+
+ asm volatile (".byte 0x0f,0xa7,0xc0" /* xstore */
+ : "=a"(eax_out),"=m"(*(unsigned *)addr)
+ : "D"(addr), "d" (edx_in)
+ );
+
+ return eax_out;
+}
+
+/* Why not inline 'rep movsd'? I failed to find information on what
+ * value in Direction Flag one can expect and consequently have to
+ * apply "better-safe-than-sorry" approach and assume "undefined."
+ * I could explicitly clear it and restore the original value upon
+ * return from padlock_aes_cipher, but it's presumably too much
+ * trouble for too little gain...
+ *
+ * In case you wonder 'rep xcrypt*' instructions above are *not*
+ * affected by the Direction Flag and pointers advance toward
+ * larger addresses unconditionally.
+ */
+static inline unsigned char *
+padlock_memcpy(void *dst,const void *src,size_t n)
+{
+ long *d=dst;
+ const long *s=src;
+
+ n /= sizeof(*d);
+ do { *d++ = *s++; } while (--n);
+
+ return dst;
+}
+
+#elif defined(_MSC_VER)
+/*
+ * Unlike GCC these are real functions. In order to minimize impact
+ * on performance we adhere to __fastcall calling convention in
+ * order to get two first arguments passed through %ecx and %edx.
+ * Which kind of suits very well, as instructions in question use
+ * both %ecx and %edx as input:-)
+ */
+#define REP_XCRYPT(code) \
+ _asm _emit 0xf3 \
+ _asm _emit 0x0f _asm _emit 0xa7 \
+ _asm _emit code
+
+/* BIG FAT WARNING:
+ * The offsets used with 'lea' instructions
+ * describe items of the 'padlock_cipher_data'
+ * structure.
+ */
+#define PADLOCK_XCRYPT_ASM(name,code) \
+static void * __fastcall \
+ name (size_t cnt, void *cdata, \
+ void *outp, const void *inp) \
+{ _asm mov eax,edx \
+ _asm lea edx,[eax+16] \
+ _asm lea ebx,[eax+32] \
+ _asm mov edi,outp \
+ _asm mov esi,inp \
+ REP_XCRYPT(code) \
+}
+
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
+PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
+
+static int __fastcall
+padlock_xstore(void *outp,unsigned int code)
+{ _asm mov edi,ecx
+ _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
+}
+
+static void __fastcall
+padlock_reload_key(void)
+{ _asm pushfd _asm popfd }
+
+static void __fastcall
+padlock_verify_context(void *cdata)
+{ _asm {
+ pushfd
+ bt DWORD PTR[esp],30
+ jnc skip
+ cmp ecx,padlock_saved_context
+ je skip
+ popfd
+ sub esp,4
+ skip: add esp,4
+ mov padlock_saved_context,ecx
+ }
+}
+
+static int
+padlock_available(void)
+{ _asm {
+ pushfd
+ pop eax
+ mov ecx,eax
+ xor eax,1<<21
+ push eax
+ popfd
+ pushfd
+ pop eax
+ xor eax,ecx
+ bt eax,21
+ jnc noluck
+ mov eax,0
+ cpuid
+ xor eax,eax
+ cmp ebx,'tneC'
+ jne noluck
+ cmp edx,'Hrua'
+ jne noluck
+ cmp ecx,'slua'
+ jne noluck
+ mov eax,0xC0000000
+ cpuid
+ mov edx,eax
+ xor eax,eax
+ cmp edx,0xC0000001
+ jb noluck
+ mov eax,0xC0000001
+ cpuid
+ xor eax,eax
+ bt edx,6
+ jnc skip_a
+ bt edx,7
+ jnc skip_a
+ mov padlock_use_ace,1
+ inc eax
+ skip_a: bt edx,2
+ jnc skip_r
+ bt edx,3
+ jnc skip_r
+ mov padlock_use_rng,1
+ inc eax
+ skip_r:
+ noluck:
+ }
+}
+
+static void __fastcall
+padlock_bswapl(void *key)
+{ _asm {
+ pushfd
+ cld
+ mov esi,ecx
+ mov edi,ecx
+ mov ecx,60
+ up: lodsd
+ bswap eax
+ stosd
+ loop up
+ popfd
+ }
+}
+
+/* MS actually specifies status of Direction Flag and compiler even
+ * manages to compile following as 'rep movsd' all by itself...
+ */
+#define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
+#endif
+
+/* ===== AES encryption/decryption ===== */
+#ifndef OPENSSL_NO_AES
+
+#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
+#define NID_aes_128_cfb NID_aes_128_cfb128
+#endif
+
+#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
+#define NID_aes_128_ofb NID_aes_128_ofb128
+#endif
+
+#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
+#define NID_aes_192_cfb NID_aes_192_cfb128
+#endif
+
+#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
+#define NID_aes_192_ofb NID_aes_192_ofb128
+#endif
+
+#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
+#define NID_aes_256_cfb NID_aes_256_cfb128
+#endif
+
+#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
+#define NID_aes_256_ofb NID_aes_256_ofb128
+#endif
+
+/* List of supported ciphers. */
+static int padlock_cipher_nids[] = {
+ NID_aes_128_ecb,
+ NID_aes_128_cbc,
+ NID_aes_128_cfb,
+ NID_aes_128_ofb,
+
+ NID_aes_192_ecb,
+ NID_aes_192_cbc,
+ NID_aes_192_cfb,
+ NID_aes_192_ofb,
+
+ NID_aes_256_ecb,
+ NID_aes_256_cbc,
+ NID_aes_256_cfb,
+ NID_aes_256_ofb,
+};
+static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
+ sizeof(padlock_cipher_nids[0]));
+
+/* Function prototypes ... */
+static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t nbytes);
+
+#define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \
+ ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) )
+#define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
+ NEAREST_ALIGNED(ctx->cipher_data))
+
+#define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE
+#define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE
+#define EVP_CIPHER_block_size_OFB 1
+#define EVP_CIPHER_block_size_CFB 1
+
+/* Declaring so many ciphers by hand would be a pain.
+ Instead introduce a bit of preprocessor magic :-) */
+#define DECLARE_AES_EVP(ksize,lmode,umode) \
+static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \
+ NID_aes_##ksize##_##lmode, \
+ EVP_CIPHER_block_size_##umode, \
+ AES_KEY_SIZE_##ksize, \
+ AES_BLOCK_SIZE, \
+ 0 | EVP_CIPH_##umode##_MODE, \
+ padlock_aes_init_key, \
+ padlock_aes_cipher, \
+ NULL, \
+ sizeof(struct padlock_cipher_data) + 16, \
+ EVP_CIPHER_set_asn1_iv, \
+ EVP_CIPHER_get_asn1_iv, \
+ NULL, \
+ NULL \
+}
+
+DECLARE_AES_EVP(128,ecb,ECB);
+DECLARE_AES_EVP(128,cbc,CBC);
+DECLARE_AES_EVP(128,cfb,CFB);
+DECLARE_AES_EVP(128,ofb,OFB);
+
+DECLARE_AES_EVP(192,ecb,ECB);
+DECLARE_AES_EVP(192,cbc,CBC);
+DECLARE_AES_EVP(192,cfb,CFB);
+DECLARE_AES_EVP(192,ofb,OFB);
+
+DECLARE_AES_EVP(256,ecb,ECB);
+DECLARE_AES_EVP(256,cbc,CBC);
+DECLARE_AES_EVP(256,cfb,CFB);
+DECLARE_AES_EVP(256,ofb,OFB);
+
+static int
+padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
+{
+ /* No specific cipher => return a list of supported nids ... */
+ if (!cipher) {
+ *nids = padlock_cipher_nids;
+ return padlock_cipher_nids_num;
+ }
+
+ /* ... or the requested "cipher" otherwise */
+ switch (nid) {
+ case NID_aes_128_ecb:
+ *cipher = &padlock_aes_128_ecb;
+ break;
+ case NID_aes_128_cbc:
+ *cipher = &padlock_aes_128_cbc;
+ break;
+ case NID_aes_128_cfb:
+ *cipher = &padlock_aes_128_cfb;
+ break;
+ case NID_aes_128_ofb:
+ *cipher = &padlock_aes_128_ofb;
+ break;
+
+ case NID_aes_192_ecb:
+ *cipher = &padlock_aes_192_ecb;
+ break;
+ case NID_aes_192_cbc:
+ *cipher = &padlock_aes_192_cbc;
+ break;
+ case NID_aes_192_cfb:
+ *cipher = &padlock_aes_192_cfb;
+ break;
+ case NID_aes_192_ofb:
+ *cipher = &padlock_aes_192_ofb;
+ break;
+
+ case NID_aes_256_ecb:
+ *cipher = &padlock_aes_256_ecb;
+ break;
+ case NID_aes_256_cbc:
+ *cipher = &padlock_aes_256_cbc;
+ break;
+ case NID_aes_256_cfb:
+ *cipher = &padlock_aes_256_cfb;
+ break;
+ case NID_aes_256_ofb:
+ *cipher = &padlock_aes_256_ofb;
+ break;
+
+ default:
+ /* Sorry, we don't support this NID */
+ *cipher = NULL;
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Prepare the encryption key for PadLock usage */
+static int
+padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ struct padlock_cipher_data *cdata;
+ int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
+
+ if (key==NULL) return 0; /* ERROR */
+
+ cdata = ALIGNED_CIPHER_DATA(ctx);
+ memset(cdata, 0, sizeof(struct padlock_cipher_data));
+
+ /* Prepare Control word. */
+ if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
+ cdata->cword.b.encdec = 0;
+ else
+ cdata->cword.b.encdec = (ctx->encrypt == 0);
+ cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
+ cdata->cword.b.ksize = (key_len - 128) / 64;
+
+ switch(key_len) {
+ case 128:
+ /* PadLock can generate an extended key for
+ AES128 in hardware */
+ memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
+ cdata->cword.b.keygen = 0;
+ break;
+
+ case 192:
+ case 256:
+ /* Generate an extended AES key in software.
+ Needed for AES192/AES256 */
+ /* Well, the above applies to Stepping 8 CPUs
+ and is listed as hardware errata. They most
+ likely will fix it at some point and then
+ a check for stepping would be due here. */
+ if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE ||
+ EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE ||
+ enc)
+ AES_set_encrypt_key(key, key_len, &cdata->ks);
+ else
+ AES_set_decrypt_key(key, key_len, &cdata->ks);
+#ifndef AES_ASM
+ /* OpenSSL C functions use byte-swapped extended key. */
+ padlock_bswapl(&cdata->ks);
+#endif
+ cdata->cword.b.keygen = 1;
+ break;
+
+ default:
+ /* ERROR */
+ return 0;
+ }
+
+ /*
+ * This is done to cover for cases when user reuses the
+ * context for new key. The catch is that if we don't do
+ * this, padlock_eas_cipher might proceed with old key...
+ */
+ padlock_reload_key ();
+
+ return 1;
+}
+
+/*
+ * Simplified version of padlock_aes_cipher() used when
+ * 1) both input and output buffers are at aligned addresses.
+ * or when
+ * 2) running on a newer CPU that doesn't require aligned buffers.
+ */
+static int
+padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
+ const unsigned char *in_arg, size_t nbytes)
+{
+ struct padlock_cipher_data *cdata;
+ void *iv;
+
+ cdata = ALIGNED_CIPHER_DATA(ctx);
+ padlock_verify_context(cdata);
+
+ switch (EVP_CIPHER_CTX_mode(ctx)) {
+ case EVP_CIPH_ECB_MODE:
+ padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
+ break;
+
+ case EVP_CIPH_CBC_MODE:
+ memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+ iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
+ memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
+ break;
+
+ case EVP_CIPH_CFB_MODE:
+ memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+ iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
+ memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
+ break;
+
+ case EVP_CIPH_OFB_MODE:
+ memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+ padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
+ memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
+ break;
+
+ default:
+ return 0;
+ }
+
+ memset(cdata->iv, 0, AES_BLOCK_SIZE);
+
+ return 1;
+}
+
+#ifndef PADLOCK_CHUNK
+# define PADLOCK_CHUNK 512 /* Must be a power of 2 larger than 16 */
+#endif
+#if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
+# error "insane PADLOCK_CHUNK..."
+#endif
+
+/* Re-align the arguments to 16-Bytes boundaries and run the
+ encryption function itself. This function is not AES-specific. */
+static int
+padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
+ const unsigned char *in_arg, size_t nbytes)
+{
+ struct padlock_cipher_data *cdata;
+ const void *inp;
+ unsigned char *out;
+ void *iv;
+ int inp_misaligned, out_misaligned, realign_in_loop;
+ size_t chunk, allocated=0;
+
+ /* ctx->num is maintained in byte-oriented modes,
+ such as CFB and OFB... */
+ if ((chunk = ctx->num)) { /* borrow chunk variable */
+ unsigned char *ivp=ctx->iv;
+
+ switch (EVP_CIPHER_CTX_mode(ctx)) {
+ case EVP_CIPH_CFB_MODE:
+ if (chunk >= AES_BLOCK_SIZE)
+ return 0; /* bogus value */
+
+ if (ctx->encrypt)
+ while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
+ ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
+ chunk++, nbytes--;
+ }
+ else while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
+ unsigned char c = *(in_arg++);
+ *(out_arg++) = c ^ ivp[chunk];
+ ivp[chunk++] = c, nbytes--;
+ }
+
+ ctx->num = chunk%AES_BLOCK_SIZE;
+ break;
+ case EVP_CIPH_OFB_MODE:
+ if (chunk >= AES_BLOCK_SIZE)
+ return 0; /* bogus value */
+
+ while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
+ *(out_arg++) = *(in_arg++) ^ ivp[chunk];
+ chunk++, nbytes--;
+ }
+
+ ctx->num = chunk%AES_BLOCK_SIZE;
+ break;
+ }
+ }
+
+ if (nbytes == 0)
+ return 1;
+#if 0
+ if (nbytes % AES_BLOCK_SIZE)
+ return 0; /* are we expected to do tail processing? */
+#else
+ /* nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC
+ modes and arbitrary value in byte-oriented modes, such as
+ CFB and OFB... */
+#endif
+
+ /* VIA promises CPUs that won't require alignment in the future.
+ For now padlock_aes_align_required is initialized to 1 and
+ the condition is never met... */
+ /* C7 core is capable to manage unaligned input in non-ECB[!]
+ mode, but performance penalties appear to be approximately
+ same as for software alignment below or ~3x. They promise to
+ improve it in the future, but for now we can just as well
+ pretend that it can only handle aligned input... */
+ if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0)
+ return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
+
+ inp_misaligned = (((size_t)in_arg) & 0x0F);
+ out_misaligned = (((size_t)out_arg) & 0x0F);
+
+ /* Note that even if output is aligned and input not,
+ * I still prefer to loop instead of copy the whole
+ * input and then encrypt in one stroke. This is done
+ * in order to improve L1 cache utilization... */
+ realign_in_loop = out_misaligned|inp_misaligned;
+
+ if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0)
+ return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
+
+ /* this takes one "if" out of the loops */
+ chunk = nbytes;
+ chunk %= PADLOCK_CHUNK;
+ if (chunk==0) chunk = PADLOCK_CHUNK;
+
+ if (out_misaligned) {
+ /* optmize for small input */
+ allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);
+ out = alloca(0x10 + allocated);
+ out = NEAREST_ALIGNED(out);
+ }
+ else
+ out = out_arg;
+
+ cdata = ALIGNED_CIPHER_DATA(ctx);
+ padlock_verify_context(cdata);
+
+ switch (EVP_CIPHER_CTX_mode(ctx)) {
+ case EVP_CIPH_ECB_MODE:
+ do {
+ if (inp_misaligned)
+ inp = padlock_memcpy(out, in_arg, chunk);
+ else
+ inp = in_arg;
+ in_arg += chunk;
+
+ padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
+
+ if (out_misaligned)
+ out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
+ else
+ out = out_arg+=chunk;
+
+ nbytes -= chunk;
+ chunk = PADLOCK_CHUNK;
+ } while (nbytes);
+ break;
+
+ case EVP_CIPH_CBC_MODE:
+ memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+ goto cbc_shortcut;
+ do {
+ if (iv != cdata->iv)
+ memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
+ chunk = PADLOCK_CHUNK;
+ cbc_shortcut: /* optimize for small input */
+ if (inp_misaligned)
+ inp = padlock_memcpy(out, in_arg, chunk);
+ else
+ inp = in_arg;
+ in_arg += chunk;
+
+ iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
+
+ if (out_misaligned)
+ out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
+ else
+ out = out_arg+=chunk;
+
+ } while (nbytes -= chunk);
+ memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
+ break;
+
+ case EVP_CIPH_CFB_MODE:
+ memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+ chunk &= ~(AES_BLOCK_SIZE-1);
+ if (chunk) goto cfb_shortcut;
+ else goto cfb_skiploop;
+ do {
+ if (iv != cdata->iv)
+ memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
+ chunk = PADLOCK_CHUNK;
+ cfb_shortcut: /* optimize for small input */
+ if (inp_misaligned)
+ inp = padlock_memcpy(out, in_arg, chunk);
+ else
+ inp = in_arg;
+ in_arg += chunk;
+
+ iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
+
+ if (out_misaligned)
+ out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
+ else
+ out = out_arg+=chunk;
+
+ nbytes -= chunk;
+ } while (nbytes >= AES_BLOCK_SIZE);
+
+ cfb_skiploop:
+ if (nbytes) {
+ unsigned char *ivp = cdata->iv;
+
+ if (iv != ivp) {
+ memcpy(ivp, iv, AES_BLOCK_SIZE);
+ iv = ivp;
+ }
+ ctx->num = nbytes;
+ if (cdata->cword.b.encdec) {
+ cdata->cword.b.encdec=0;
+ padlock_reload_key();
+ padlock_xcrypt_ecb(1,cdata,ivp,ivp);
+ cdata->cword.b.encdec=1;
+ padlock_reload_key();
+ while(nbytes) {
+ unsigned char c = *(in_arg++);
+ *(out_arg++) = c ^ *ivp;
+ *(ivp++) = c, nbytes--;
+ }
+ }
+ else { padlock_reload_key();
+ padlock_xcrypt_ecb(1,cdata,ivp,ivp);
+ padlock_reload_key();
+ while (nbytes) {
+ *ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
+ ivp++, nbytes--;
+ }
+ }
+ }
+
+ memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
+ break;
+
+ case EVP_CIPH_OFB_MODE:
+ memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+ chunk &= ~(AES_BLOCK_SIZE-1);
+ if (chunk) do {
+ if (inp_misaligned)
+ inp = padlock_memcpy(out, in_arg, chunk);
+ else
+ inp = in_arg;
+ in_arg += chunk;
+
+ padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
+
+ if (out_misaligned)
+ out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
+ else
+ out = out_arg+=chunk;
+
+ nbytes -= chunk;
+ chunk = PADLOCK_CHUNK;
+ } while (nbytes >= AES_BLOCK_SIZE);
+
+ if (nbytes) {
+ unsigned char *ivp = cdata->iv;
+
+ ctx->num = nbytes;
+ padlock_reload_key(); /* empirically found */
+ padlock_xcrypt_ecb(1,cdata,ivp,ivp);
+ padlock_reload_key(); /* empirically found */
+ while (nbytes) {
+ *(out_arg++) = *(in_arg++) ^ *ivp;
+ ivp++, nbytes--;
+ }
+ }
+
+ memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
+ break;
+
+ default:
+ return 0;
+ }
+
+ /* Clean the realign buffer if it was used */
+ if (out_misaligned) {
+ volatile unsigned long *p=(void *)out;
+ size_t n = allocated/sizeof(*p);
+ while (n--) *p++=0;
+ }
+
+ memset(cdata->iv, 0, AES_BLOCK_SIZE);
+
+ return 1;
+}
+
+#endif /* OPENSSL_NO_AES */
+
+/* ===== Random Number Generator ===== */
+/*
+ * This code is not engaged. The reason is that it does not comply
+ * with recommendations for VIA RNG usage for secure applications
+ * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
+ * provide meaningful error control...
+ */
+/* Wrapper that provides an interface between the API and
+ the raw PadLock RNG */
+static int
+padlock_rand_bytes(unsigned char *output, int count)
+{
+ unsigned int eax, buf;
+
+ while (count >= 8) {
+ eax = padlock_xstore(output, 0);
+ if (!(eax&(1<<6))) return 0; /* RNG disabled */
+ /* this ---vv--- covers DC bias, Raw Bits and String Filter */
+ if (eax&(0x1F<<10)) return 0;
+ if ((eax&0x1F)==0) continue; /* no data, retry... */
+ if ((eax&0x1F)!=8) return 0; /* fatal failure... */
+ output += 8;
+ count -= 8;
+ }
+ while (count > 0) {
+ eax = padlock_xstore(&buf, 3);
+ if (!(eax&(1<<6))) return 0; /* RNG disabled */
+ /* this ---vv--- covers DC bias, Raw Bits and String Filter */
+ if (eax&(0x1F<<10)) return 0;
+ if ((eax&0x1F)==0) continue; /* no data, retry... */
+ if ((eax&0x1F)!=1) return 0; /* fatal failure... */
+ *output++ = (unsigned char)buf;
+ count--;
+ }
+ *(volatile unsigned int *)&buf=0;
+
+ return 1;
+}
+
+/* Dummy but necessary function */
+static int
+padlock_rand_status(void)
+{
+ return 1;
+}
+
+/* Prepare structure for registration */
+static RAND_METHOD padlock_rand = {
+ NULL, /* seed */
+ padlock_rand_bytes, /* bytes */
+ NULL, /* cleanup */
+ NULL, /* add */
+ padlock_rand_bytes, /* pseudorand */
+ padlock_rand_status, /* rand status */
+};
+
+#else /* !COMPILE_HW_PADLOCK */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+#endif
+#endif /* COMPILE_HW_PADLOCK */
+
+#endif /* !OPENSSL_NO_HW_PADLOCK */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/makeengines.com b/openssl/engines/makeengines.com
index a7e4aa86d..0d3174257 100644
--- a/openssl/engines/makeengines.com
+++ b/openssl/engines/makeengines.com
@@ -1,1021 +1,1021 @@
-$!
-$! MAKEENGINES.COM
-$! Written By: Richard Levitte
-$! richard@levitte.org
-$!
-$! This command file compiles and creates the various engines in form
-$! of shared images. They are placed in [.xxx.EXE.ENGINES], where "xxx"
-$! is ALPHA, IA64 or VAX, depending on your hardware.
-$!
-$! P1 if this is ENGINES or ALL, the engines will build, otherwise not.
-$!
-$! P2 DEBUG or NODEBUG to compile with or without debugger information.
-$!
-$! P3 VAXC for VAX C
-$! DECC for DEC C
-$! GNUC for GNU C (untested)
-$!
-$! P4 if defined, sets the TCP/IP libraries to use. UCX or TCPIP is
-$! used by default since most other implementations come with a
-$! compatibility library. The value must be one of the following:
-$!
-$! UCX for UCX
-$! SOCKETSHR for SOCKETSHR+NETLIB
-$! TCPIP for TCPIP (post UCX)
-$!
-$! P5 if defined, tells the compiler not to use special threads.
-$!
-$! P6 if defined, denotes which engines to build. If not defined,
-$! all available engines are built.
-$!
-$! For 64 bit architectures (Alpha and IA64), specify the pointer size as P7.
-$! For 32 bit architectures (VAX), P7 is ignored.
-$! Currently supported values are:
-$!
-$! 32 To ge a library compiled with /POINTER_SIZE=32
-$! 64 To ge a library compiled with /POINTER_SIZE=64
-$!
-$!-----------------------------------------------------------------------------
-$!
-$! Set the default TCP/IP library to link against if needed
-$!
-$ TCPIP_LIB = ""
-$!
-$! Check What Architecture We Are Using.
-$!
-$ IF (F$GETSYI("CPU").LT.128)
-$ THEN
-$!
-$! The Architecture Is VAX.
-$!
-$ ARCH = "VAX"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! The Architecture Is Alpha, IA64 or whatever comes in the future.
-$!
-$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
-$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
-$!
-$! End The Architecture Check.
-$!
-$ ENDIF
-$!
-$! Set the names of the engines we want to build
-$! NOTE: Some might think this list ugly. However, it's made this way to
-$! reflect the LIBNAMES variable in Makefile as closely as possible,
-$! thereby making it fairly easy to verify that the lists are the same.
-$! NOTE: gmp isn't built, as it's mostly a test engine and brings in another
-$! library that isn't necessarely ported to VMS.
-$!
-$ ENGINES = "," + P6
-$ IF ENGINES .EQS. "," THEN -
- ENGINES = ",4758cca,aep,atalla,cswift,chil,nuron,sureware,ubsec,padlock,"
-$!
-$! GOST requires a 64-bit integer type, unavailable on VAX.
-$!
-$ IF (ARCH .NES. "VAX") THEN -
- ENGINES = ENGINES+ ",ccgost"
-$!
-$! Set the goal directories, and create them if necessary
-$!
-$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.ENGINES]
-$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.ENGINES]
-$ IF F$PARSE(OBJ_DIR) .EQS. "" THEN CREATE/DIRECTORY 'OBJ_DIR'
-$ IF F$PARSE(EXE_DIR) .EQS. "" THEN CREATE/DIRECTORY 'EXE_DIR'
-$!
-$! Set the goal files, and create them if necessary
-$!
-$ CRYPTO_LIB :=SYS$DISK:[-.'ARCH'.EXE.CRYPTO]LIBCRYPTO'LIB32'.OLB
-$ IF F$SEARCH(CRYPTO_LIB) .EQS. "" THEN LIBRARY/CREATE/OBJECT 'CRYPTO_LIB'
-$!
-$! OK, time to check options and initialise
-$!
-$ OPT_PHASE = P1
-$ ACCEPT_PHASE = "ALL,ENGINES"
-$ OPT_DEBUG = P2
-$ OPT_COMPILER = P3
-$ OPT_TCPIP_LIB = P4
-$ OPT_SPECIAL_THREADS = P5
-$ OPT_POINTER_SIZE = P7
-$
-$ GOSUB CHECK_OPTIONS
-$ GOSUB INITIALISE
-$ GOSUB CHECK_OPT_FILE
-$!
-$! Define what goes into each engine. VAX includes a transfer vector.
-$!
-$ ENGINE_ = ""
-$ TV_OBJ = ""
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ ENGINE_ = "engine_vector.mar"
-$ TV_OBJ_NAME = OBJ_DIR + F$PARSE(ENGINE_,,,"NAME","SYNTAX_ONLY") + ".OBJ"
-$ TV_OBJ = ",''TV_OBJ_NAME'"
-$ ENDIF
-$ ENGINE_4758CCA = "e_4758cca"
-$ ENGINE_aep = "e_aep"
-$ ENGINE_atalla = "e_atalla"
-$ ENGINE_cswift = "e_cswift"
-$ ENGINE_chil = "e_chil"
-$ ENGINE_nuron = "e_nuron"
-$ ENGINE_sureware = "e_sureware"
-$ ENGINE_ubsec = "e_ubsec"
-$ ENGINE_padlock = "e_padlock"
-$
-$ ENGINE_ccgost_SUBDIR = "ccgost"
-$ ENGINE_ccgost = "e_gost_err,gost2001_keyx,gost2001,gost89,gost94_keyx,"+ -
- "gost_ameth,gost_asn1,gost_crypt,gost_ctl,gost_eng,"+ -
- "gosthash,gost_keywrap,gost_md,gost_params,gost_pmeth,"+ -
- "gost_sign"
-$!
-$! Define which programs need to be linked with a TCP/IP library
-$!
-$ TCPIP_ENGINES = ",,"
-$ IF COMPILER .EQS. "VAXC" THEN -
- TCPIP_ENGINES = ",,"
-$!
-$! Set up two loops, one that keeps track of the engines,
-$! and one that keeps track of all the files going into
-$! the current engine.
-$!
-$! Here's the start of the engine loop.
-$!
-$ ENGINE_COUNTER = 0
-$ ENGINE_NEXT:
-$!
-$! Extract the current engine name, and if we've reached the end, stop
-$!
-$ ENGINE_NAME = F$ELEMENT(ENGINE_COUNTER,",",ENGINES)
-$ IF (ENGINE_NAME.EQS.",") THEN GOTO ENGINE_DONE
-$!
-$ ENGINE_COUNTER = ENGINE_COUNTER + 1
-$!
-$! Set up the engine library names.
-$!
-$ LIB_ENGINE = "ENGINE_" + ENGINE_NAME
-$!
-$! Check if the library module name actually is defined
-$!
-$ IF F$TYPE('LIB_ENGINE') .EQS. ""
-$ THEN
-$ WRITE SYS$ERROR ""
-$ WRITE SYS$ERROR "The module ",ENGINE_NAME," does not exist. Continuing..."
-$ WRITE SYS$ERROR ""
-$ GOTO ENGINE_NEXT
-$ ENDIF
-$!
-$! Talk to the user
-$!
-$ IF ENGINE_NAME .NES. ""
-$ THEN
-$ WRITE SYS$OUTPUT "Compiling The ",ENGINE_NAME," Library Files. (",BUILDALL,")"
-$ ELSE
-$ WRITE SYS$OUTPUT "Compiling Support Files. (",BUILDALL,")"
-$ ENDIF
-$!
-$! Create a .OPT file for the object files (for a real engine name).
-$!
-$ IF ENGINE_NAME .NES. ""
-$ THEN
-$ OPEN/WRITE OBJECTS 'EXE_DIR''ENGINE_NAME'.OPT
-$ ENDIF
-$!
-$! Here's the start of per-engine module loop.
-$!
-$ FILE_COUNTER = 0
-$ FILE_NEXT:
-$!
-$! Extract the file name from the file list, and if we've reached the end, stop
-$!
-$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",'LIB_ENGINE')
-$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
-$!
-$ FILE_COUNTER = FILE_COUNTER + 1
-$!
-$ IF FILE_NAME .EQS. "" THEN GOTO FILE_NEXT
-$!
-$! Set up the source and object reference
-$!
-$ IF F$TYPE('LIB_ENGINE'_SUBDIR) .EQS. ""
-$ THEN
-$ SOURCE_FILE = F$PARSE(FILE_NAME,"SYS$DISK:[].C",,,"SYNTAX_ONLY")
-$ ELSE
-$ SOURCE_FILE = F$PARSE(FILE_NAME,"SYS$DISK:[."+'LIB_ENGINE'_SUBDIR+"].C",,,"SYNTAX_ONLY")
-$ ENDIF
-$ OBJECT_FILE = OBJ_DIR + F$PARSE(FILE_NAME,,,"NAME","SYNTAX_ONLY") + ".OBJ"
-$!
-$! If we get some problem, we just go on trying to build the next module.
-$ ON WARNING THEN GOTO FILE_NEXT
-$!
-$! Check if the module we want to compile is actually there.
-$!
-$ IF F$SEARCH(SOURCE_FILE) .EQS. ""
-$ THEN
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Doesn't Exist."
-$ WRITE SYS$OUTPUT ""
-$ GOTO EXIT
-$ ENDIF
-$!
-$! Talk to the user.
-$!
-$ WRITE SYS$OUTPUT " ",FILE_NAME,""
-$!
-$! Do the dirty work.
-$!
-$ ON ERROR THEN GOTO FILE_NEXT
-$ IF F$EDIT(F$PARSE(SOURCE_FILE,,,"TYPE","SYNTAX_ONLY"),"UPCASE") .EQS. ".MAR"
-$ THEN
-$ MACRO/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ELSE
-$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ENDIF
-$!
-$! Write the entry to the .OPT file (for a real engine name).
-$!
-$ IF ENGINE_NAME .NES. ""
-$ THEN
-$ WRITE OBJECTS OBJECT_FILE
-$ ENDIF
-$!
-$! Next file
-$!
-$ GOTO FILE_NEXT
-$!
-$ FILE_DONE:
-$!
-$! Do not link the support files.
-$!
-$ IF ENGINE_NAME .EQS. "" THEN GOTO ENGINE_NEXT
-$!
-$! Close the linker options file (for a real engine name).
-$!
-$ CLOSE OBJECTS
-$!
-$! Now, there are two ways to handle this. We can either build
-$! shareable images or stick the engine object file into libcrypto.
-$! For now, the latter is NOT supported.
-$!
-$!!!!! LIBRARY/REPLACE 'CRYPTO_LIB' 'OBJECT_FILE'
-$!
-$! For shareable libraries, we need to do things a little differently
-$! depending on if we link with a TCP/IP library or not.
-$!
-$ ENGINE_OPT := SYS$DISK:[]'ARCH'.OPT
-$ IF TCPIP_LIB .NES. ""
-$ THEN
-$ LINK/'DEBUGGER'/'TRACEBACK' /SHARE='EXE_DIR''ENGINE_NAME'.EXE -
- 'EXE_DIR''ENGINE_NAME'.OPT/OPTION'TV_OBJ', -
- 'CRYPTO_LIB'/LIBRARY, -
- 'ENGINE_OPT'/OPTION,'TCPIP_LIB','OPT_FILE'/OPTION
-$ ELSE
-$ LINK/'DEBUGGER'/'TRACEBACK' /SHARE='EXE_DIR''ENGINE_NAME'.EXE -
- 'EXE_DIR''ENGINE_NAME'.OPT/OPTION'TV_OBJ', -
- 'CRYPTO_LIB'/LIBRARY, -
- 'ENGINE_OPT'/OPTION,'OPT_FILE'/OPTION
-$ ENDIF
-$!
-$! Next engine
-$!
-$ GOTO ENGINE_NEXT
-$!
-$ ENGINE_DONE:
-$!
-$! Talk to the user
-$!
-$ WRITE SYS$OUTPUT "All Done..."
-$ EXIT:
-$ GOSUB CLEANUP
-$ EXIT
-$!
-$! Check For The Link Option FIle.
-$!
-$ CHECK_OPT_FILE:
-$!
-$! Check To See If We Need To Make A VAX C Option File.
-$!
-$ IF (COMPILER.EQS."VAXC")
-$ THEN
-$!
-$! Check To See If We Already Have A VAX C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A VAX C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable VAX C Runtime Library.
-!
-SYS$SHARE:VAXCRTL.EXE/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The VAXC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A GNU C Option File.
-$!
-$ IF (COMPILER.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If We Already Have A GNU C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A GNU C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable C Runtime Library.
-!
-GNU_CC:[000000]GCCLIB/LIBRARY
-SYS$SHARE:VAXCRTL/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A DEC C Option File.
-$!
-$ IF (COMPILER.EQS."DECC")
-$ THEN
-$!
-$! Check To See If We Already Have A DEC C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! Figure Out If We Need A non-VAX Or A VAX Linker Option File.
-$!
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$!
-$! We Need A DEC C Linker Option File For VAX.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable DEC C Runtime Library.
-!
-SYS$SHARE:DECC$SHR.EXE/SHARE
-$EOD
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Create The non-VAX Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File For non-VAX To Link Agianst
-! The Sharable C Runtime Library.
-!
-SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
-SYS$SHARE:CMA$OPEN_RTL/SHARE
-$EOD
-$!
-$! End The DEC C Option File Check.
-$!
-$ ENDIF
-$!
-$! End The Option File Search.
-$!
-$ ENDIF
-$!
-$! End The DEC C Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What Linker Option File We Are Using.
-$!
-$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
-$!
-$! Time To RETURN.
-$!
-$ RETURN
-$!
-$! Check The User's Options.
-$!
-$ CHECK_OPTIONS:
-$!
-$! Check To See If OPT_PHASE Is Blank.
-$!
-$ IF (OPT_PHASE.EQS."ALL")
-$ THEN
-$!
-$! OPT_PHASE Is Blank, So Build Everything.
-$!
-$ BUILDALL = "ALL"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Else, Check To See If OPT_PHASE Has A Valid Argument.
-$!
-$ IF ("," + ACCEPT_PHASE + ",") - ("," + OPT_PHASE + ",") -
- .NES. ("," + ACCEPT_PHASE + ",")
-$ THEN
-$!
-$! A Valid Argument.
-$!
-$ BUILDALL = OPT_PHASE
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The option ",OPT_PHASE," is invalid. The valid options are:"
-$ WRITE SYS$OUTPUT ""
-$ IF ("," + ACCEPT_PHASE + ",") - ",ALL," -
- .NES. ("," + ACCEPT_PHASE + ",") THEN -
- WRITE SYS$OUTPUT " ALL : just build everything."
-$ IF ("," + ACCEPT_PHASE + ",") - ",ENGINES," -
- .NES. ("," + ACCEPT_PHASE + ",") THEN -
- WRITE SYS$OUTPUT " ENGINES : to compile just the [.xxx.EXE.ENGINES]*.EXE hareable images."
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " where 'xxx' stands for:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALPHA : Alpha architecture."
-$ WRITE SYS$OUTPUT " IA64 : IA64 architecture."
-$ WRITE SYS$OUTPUT " VAX : VAX architecture."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The OPT_PHASE Check.
-$!
-$ ENDIF
-$!
-$! Check To See If OPT_DEBUG Is Blank.
-$!
-$ IF (OPT_DEBUG.EQS."NODEBUG")
-$ THEN
-$!
-$! OPT_DEBUG Is NODEBUG, So Compile Without The Debugger Information.
-$!
-$ DEBUGGER = "NODEBUG"
-$ TRACEBACK = "NOTRACEBACK"
-$ GCC_OPTIMIZE = "OPTIMIZE"
-$ CC_OPTIMIZE = "OPTIMIZE"
-$ MACRO_OPTIMIZE = "OPTIMIZE"
-$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
-$ ELSE
-$!
-$! Check To See If We Are To Compile With Debugger Information.
-$!
-$ IF (OPT_DEBUG.EQS."DEBUG")
-$ THEN
-$!
-$! Compile With Debugger Information.
-$!
-$ DEBUGGER = "DEBUG"
-$ TRACEBACK = "TRACEBACK"
-$ GCC_OPTIMIZE = "NOOPTIMIZE"
-$ CC_OPTIMIZE = "NOOPTIMIZE"
-$ MACRO_OPTIMIZE = "NOOPTIMIZE"
-$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
-$ ELSE
-$!
-$! They Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",OPT_DEBUG," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
-$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The OPT_DEBUG Check.
-$!
-$ ENDIF
-$!
-$! Special Threads For OpenVMS v7.1 Or Later
-$!
-$! Written By: Richard Levitte
-$! richard@levitte.org
-$!
-$!
-$! Check To See If We Have A Option For OPT_SPECIAL_THREADS.
-$!
-$ IF (OPT_SPECIAL_THREADS.EQS."")
-$ THEN
-$!
-$! Get The Version Of VMS We Are Using.
-$!
-$ ISSEVEN :=
-$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
-$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
-$!
-$! Check To See If The VMS Version Is v7.1 Or Later.
-$!
-$ IF (TMP.GE.71)
-$ THEN
-$!
-$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
-$!
-$ ISSEVEN := ,PTHREAD_USE_D4
-$!
-$! End The VMS Version Check.
-$!
-$ ENDIF
-$!
-$! End The OPT_SPECIAL_THREADS Check.
-$!
-$ ENDIF
-$!
-$! Check To See If OPT_POINTER_SIZE Is Blank.
-$!
-$ IF (OPT_POINTER_SIZE.EQS."")
-$ THEN
-$ POINTER_SIZE = ""
-$ ELSE
-$!
-$! Check is OPT_POINTER_SIZE Is Valid
-$!
-$ IF (OPT_POINTER_SIZE.EQS."32")
-$ THEN
-$ POINTER_SIZE = "/POINTER_SIZE=32"
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ LIB32 = ""
-$ ELSE
-$ LIB32 = "32"
-$ ENDIF
-$ ELSE
-$ IF (OPT_POINTER_SIZE.EQS."64")
-$ THEN
-$ LIB32 = ""
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ POINTER_SIZE = "/POINTER_SIZE=32"
-$ ELSE
-$ POINTER_SIZE = "/POINTER_SIZE=64"
-$ ENDIF
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",OPT_POINTER_SIZE," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " 32 : Compile with 32 bit pointer size"
-$ WRITE SYS$OUTPUT " 64 : Compile with 64 bit pointer size"
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ GOTO TIDY
-$!
-$! End The Valid Arguement Check.
-$!
-$ ENDIF
-$ ENDIF
-$!
-$! End The OPT_POINTER_SIZE Check.
-$!
-$ ENDIF
-$!
-$! Check To See If OPT_COMPILER Is Blank.
-$!
-$ IF (OPT_COMPILER.EQS."")
-$ THEN
-$!
-$! O.K., The User Didn't Specify A Compiler, Let's Try To
-$! Find Out Which One To Use.
-$!
-$! Check To See If We Have GNU C.
-$!
-$ IF (F$TRNLNM("GNU_CC").NES."")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ OPT_COMPILER = "GNUC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Check To See If We Have VAXC Or DECC.
-$!
-$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ OPT_COMPILER = "DECC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ OPT_COMPILER = "VAXC"
-$!
-$! End The VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The DECC & VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The Compiler Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Have A Option For OPT_TCPIP_LIB.
-$!
-$ IF (OPT_TCPIP_LIB.EQS."")
-$ THEN
-$!
-$! Find out what socket library we have available
-$!
-$ IF F$PARSE("SOCKETSHR:") .NES. ""
-$ THEN
-$!
-$! We have SOCKETSHR, and it is my opinion that it's the best to use.
-$!
-$ OPT_TCPIP_LIB = "SOCKETSHR"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
-$!
-$! Else, let's look for something else
-$!
-$ ELSE
-$!
-$! Like UCX (the reason to do this before Multinet is that the UCX
-$! emulation is easier to use...)
-$!
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
- .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
- .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
-$ THEN
-$!
-$! Last resort: a UCX or UCX-compatible library
-$!
-$ OPT_TCPIP_LIB = "UCX"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
-$!
-$! That was all...
-$!
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$!
-$! Set Up Initial CC Definitions, Possibly With User Ones
-$!
-$ CCDEFS = "TCPIP_TYPE_''OPT_TCPIP_LIB',DSO_VMS"
-$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
-$ CCEXTRAFLAGS = ""
-$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
-$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX"
-$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
- CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
-$!
-$! Check To See If The User Entered A Valid Paramter.
-$!
-$ IF (OPT_COMPILER.EQS."VAXC").OR.(OPT_COMPILER.EQS."DECC").OR.(OPT_COMPILER.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If The User Wanted DECC.
-$!
-$ IF (OPT_COMPILER.EQS."DECC")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ COMPILER = "DECC"
-$!
-$! Tell The User We Are Using DECC.
-$!
-$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
-$!
-$! Use DECC...
-$!
-$ CC = "CC"
-$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
- THEN CC = "CC/DECC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89''POINTER_SIZE'" + -
- "/NOLIST/PREFIX=ALL" + -
- "/INCLUDE=(SYS$DISK:[],SYS$DISK:[.VENDOR_DEFNS])" + -
- CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
-$!
-$! End DECC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use VAXC.
-$!
-$ IF (OPT_COMPILER.EQS."VAXC")
-$ THEN
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ COMPILER = "VAXC"
-$!
-$! Tell The User We Are Using VAX C.
-$!
-$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
-$!
-$! Compile Using VAXC.
-$!
-$ CC = "CC"
-$ IF ARCH.NES."VAX"
-$ THEN
-$ WRITE SYS$OUTPUT "There is no VAX C on Alpha!"
-$ EXIT
-$ ENDIF
-$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=(SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[.VENDOR_DEFNS])" + -
- CCEXTRAFLAGS
-$ CCDEFS = """VAXC""," + CCDEFS
-$!
-$! Define <sys> As SYS$COMMON:[SYSLIB]
-$!
-$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
-$!
-$! End VAXC Check
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use GNU C.
-$!
-$ IF (OPT_COMPILER.EQS."GNUC")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ COMPILER = "GNUC"
-$!
-$! Tell The User We Are Using GNUC.
-$!
-$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
-$!
-$! Use GNU C...
-$!
-$ CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=(SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[.VENDOR_DEFNS])" + -
- CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Set up default defines
-$!
-$ CCDEFS = """FLAT_INC=1""," + CCDEFS
-$!
-$! Finish up the definition of CC.
-$!
-$ IF COMPILER .EQS. "DECC"
-$ THEN
-$ IF CCDISABLEWARNINGS .NES. ""
-$ THEN
-$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
-$ ENDIF
-$ ELSE
-$ CCDISABLEWARNINGS = ""
-$ ENDIF
-$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
-$!
-$! Show user the result
-$!
-$ WRITE/SYMBOL SYS$OUTPUT "Main C Compiling Command: ",CC
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",OPT_COMPILER," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
-$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
-$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! Build a MACRO command for the architecture at hand
-$!
-$ IF ARCH .EQS. "VAX" THEN MACRO = "MACRO/''DEBUGGER'"
-$ IF ARCH .NES. "VAX" THEN MACRO = "MACRO/MIGRATION/''DEBUGGER'/''MACRO_OPTIMIZE'"
-$!
-$! Show user the result
-$!
-$ WRITE/SYMBOL SYS$OUTPUT "Main MACRO Compiling Command: ",MACRO
-$!
-$! Time to check the contents, and to make sure we get the correct library.
-$!
-$ IF OPT_TCPIP_LIB.EQS."SOCKETSHR" .OR. OPT_TCPIP_LIB.EQS."MULTINET" -
- .OR. OPT_TCPIP_LIB.EQS."UCX" .OR. OPT_TCPIP_LIB.EQS."TCPIP" -
- .OR. OPT_TCPIP_LIB.EQS."NONE"
-$ THEN
-$!
-$! Check to see if SOCKETSHR was chosen
-$!
-$ IF OPT_TCPIP_LIB.EQS."SOCKETSHR"
-$ THEN
-$!
-$! Set the library to use SOCKETSHR
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT"
-$!
-$! Done with SOCKETSHR
-$!
-$ ENDIF
-$!
-$! Check to see if MULTINET was chosen
-$!
-$ IF OPT_TCPIP_LIB.EQS."MULTINET"
-$ THEN
-$!
-$! Set the library to use UCX emulation.
-$!
-$ OPT_TCPIP_LIB = "UCX"
-$!
-$! Done with MULTINET
-$!
-$ ENDIF
-$!
-$! Check to see if UCX was chosen
-$!
-$ IF OPT_TCPIP_LIB.EQS."UCX"
-$ THEN
-$!
-$! Set the library to use UCX.
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT"
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
-$ THEN
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT/OPT"
-$ ELSE
-$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
- TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT/OPT"
-$ ENDIF
-$!
-$! Done with UCX
-$!
-$ ENDIF
-$!
-$! Check to see if TCPIP was chosen
-$!
-$ IF OPT_TCPIP_LIB.EQS."TCPIP"
-$ THEN
-$!
-$! Set the library to use TCPIP (post UCX).
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT"
-$!
-$! Done with TCPIP
-$!
-$ ENDIF
-$!
-$! Check to see if NONE was chosen
-$!
-$ IF OPT_TCPIP_LIB.EQS."NONE"
-$ THEN
-$!
-$! Do not use a TCPIP library.
-$!
-$ TCPIP_LIB = ""
-$!
-$! Done with TCPIP
-$!
-$ ENDIF
-$!
-$! Print info
-$!
-$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",OPT_TCPIP_LIB," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
-$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
-$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! Done with TCP/IP libraries
-$!
-$ ENDIF
-$!
-$! Time To RETURN...
-$!
-$ RETURN
-$!
-$ INITIALISE:
-$!
-$! Save old value of the logical name OPENSSL
-$!
-$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
-$!
-$! Save directory information
-$!
-$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
-$ __HERE = F$EDIT(__HERE,"UPCASE")
-$ __TOP = __HERE - "ENGINES]"
-$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
-$!
-$! Set up the logical name OPENSSL to point at the include directory
-$!
-$ DEFINE OPENSSL/NOLOG '__INCLUDE'
-$!
-$! Done
-$!
-$ RETURN
-$!
-$ CLEANUP:
-$!
-$! Restore the logical name OPENSSL if it had a value
-$!
-$ IF __SAVE_OPENSSL .EQS. ""
-$ THEN
-$ DEASSIGN OPENSSL
-$ ELSE
-$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
-$ ENDIF
-$!
-$! Done
-$!
-$ RETURN
+$!
+$! MAKEENGINES.COM
+$! Written By: Richard Levitte
+$! richard@levitte.org
+$!
+$! This command file compiles and creates the various engines in form
+$! of shared images. They are placed in [.xxx.EXE.ENGINES], where "xxx"
+$! is ALPHA, IA64 or VAX, depending on your hardware.
+$!
+$! P1 if this is ENGINES or ALL, the engines will build, otherwise not.
+$!
+$! P2 DEBUG or NODEBUG to compile with or without debugger information.
+$!
+$! P3 VAXC for VAX C
+$! DECC for DEC C
+$! GNUC for GNU C (untested)
+$!
+$! P4 if defined, sets the TCP/IP libraries to use. UCX or TCPIP is
+$! used by default since most other implementations come with a
+$! compatibility library. The value must be one of the following:
+$!
+$! UCX for UCX
+$! SOCKETSHR for SOCKETSHR+NETLIB
+$! TCPIP for TCPIP (post UCX)
+$!
+$! P5 if defined, tells the compiler not to use special threads.
+$!
+$! P6 if defined, denotes which engines to build. If not defined,
+$! all available engines are built.
+$!
+$! For 64 bit architectures (Alpha and IA64), specify the pointer size as P7.
+$! For 32 bit architectures (VAX), P7 is ignored.
+$! Currently supported values are:
+$!
+$! 32 To ge a library compiled with /POINTER_SIZE=32
+$! 64 To ge a library compiled with /POINTER_SIZE=64
+$!
+$!-----------------------------------------------------------------------------
+$!
+$! Set the default TCP/IP library to link against if needed
+$!
+$ TCPIP_LIB = ""
+$!
+$! Check What Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$! The Architecture Is VAX.
+$!
+$ ARCH = "VAX"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$! Set the names of the engines we want to build
+$! NOTE: Some might think this list ugly. However, it's made this way to
+$! reflect the LIBNAMES variable in Makefile as closely as possible,
+$! thereby making it fairly easy to verify that the lists are the same.
+$! NOTE: gmp isn't built, as it's mostly a test engine and brings in another
+$! library that isn't necessarely ported to VMS.
+$!
+$ ENGINES = "," + P6
+$ IF ENGINES .EQS. "," THEN -
+ ENGINES = ",4758cca,aep,atalla,cswift,chil,nuron,sureware,ubsec,padlock,"
+$!
+$! GOST requires a 64-bit integer type, unavailable on VAX.
+$!
+$ IF (ARCH .NES. "VAX") THEN -
+ ENGINES = ENGINES+ ",ccgost"
+$!
+$! Set the goal directories, and create them if necessary
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.ENGINES]
+$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.ENGINES]
+$ IF F$PARSE(OBJ_DIR) .EQS. "" THEN CREATE/DIRECTORY 'OBJ_DIR'
+$ IF F$PARSE(EXE_DIR) .EQS. "" THEN CREATE/DIRECTORY 'EXE_DIR'
+$!
+$! Set the goal files, and create them if necessary
+$!
+$ CRYPTO_LIB :=SYS$DISK:[-.'ARCH'.EXE.CRYPTO]LIBCRYPTO'LIB32'.OLB
+$ IF F$SEARCH(CRYPTO_LIB) .EQS. "" THEN LIBRARY/CREATE/OBJECT 'CRYPTO_LIB'
+$!
+$! OK, time to check options and initialise
+$!
+$ OPT_PHASE = P1
+$ ACCEPT_PHASE = "ALL,ENGINES"
+$ OPT_DEBUG = P2
+$ OPT_COMPILER = P3
+$ OPT_TCPIP_LIB = P4
+$ OPT_SPECIAL_THREADS = P5
+$ OPT_POINTER_SIZE = P7
+$
+$ GOSUB CHECK_OPTIONS
+$ GOSUB INITIALISE
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Define what goes into each engine. VAX includes a transfer vector.
+$!
+$ ENGINE_ = ""
+$ TV_OBJ = ""
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ ENGINE_ = "engine_vector.mar"
+$ TV_OBJ_NAME = OBJ_DIR + F$PARSE(ENGINE_,,,"NAME","SYNTAX_ONLY") + ".OBJ"
+$ TV_OBJ = ",''TV_OBJ_NAME'"
+$ ENDIF
+$ ENGINE_4758CCA = "e_4758cca"
+$ ENGINE_aep = "e_aep"
+$ ENGINE_atalla = "e_atalla"
+$ ENGINE_cswift = "e_cswift"
+$ ENGINE_chil = "e_chil"
+$ ENGINE_nuron = "e_nuron"
+$ ENGINE_sureware = "e_sureware"
+$ ENGINE_ubsec = "e_ubsec"
+$ ENGINE_padlock = "e_padlock"
+$
+$ ENGINE_ccgost_SUBDIR = "ccgost"
+$ ENGINE_ccgost = "e_gost_err,gost2001_keyx,gost2001,gost89,gost94_keyx,"+ -
+ "gost_ameth,gost_asn1,gost_crypt,gost_ctl,gost_eng,"+ -
+ "gosthash,gost_keywrap,gost_md,gost_params,gost_pmeth,"+ -
+ "gost_sign"
+$!
+$! Define which programs need to be linked with a TCP/IP library
+$!
+$ TCPIP_ENGINES = ",,"
+$ IF COMPILER .EQS. "VAXC" THEN -
+ TCPIP_ENGINES = ",,"
+$!
+$! Set up two loops, one that keeps track of the engines,
+$! and one that keeps track of all the files going into
+$! the current engine.
+$!
+$! Here's the start of the engine loop.
+$!
+$ ENGINE_COUNTER = 0
+$ ENGINE_NEXT:
+$!
+$! Extract the current engine name, and if we've reached the end, stop
+$!
+$ ENGINE_NAME = F$ELEMENT(ENGINE_COUNTER,",",ENGINES)
+$ IF (ENGINE_NAME.EQS.",") THEN GOTO ENGINE_DONE
+$!
+$ ENGINE_COUNTER = ENGINE_COUNTER + 1
+$!
+$! Set up the engine library names.
+$!
+$ LIB_ENGINE = "ENGINE_" + ENGINE_NAME
+$!
+$! Check if the library module name actually is defined
+$!
+$ IF F$TYPE('LIB_ENGINE') .EQS. ""
+$ THEN
+$ WRITE SYS$ERROR ""
+$ WRITE SYS$ERROR "The module ",ENGINE_NAME," does not exist. Continuing..."
+$ WRITE SYS$ERROR ""
+$ GOTO ENGINE_NEXT
+$ ENDIF
+$!
+$! Talk to the user
+$!
+$ IF ENGINE_NAME .NES. ""
+$ THEN
+$ WRITE SYS$OUTPUT "Compiling The ",ENGINE_NAME," Library Files. (",BUILDALL,")"
+$ ELSE
+$ WRITE SYS$OUTPUT "Compiling Support Files. (",BUILDALL,")"
+$ ENDIF
+$!
+$! Create a .OPT file for the object files (for a real engine name).
+$!
+$ IF ENGINE_NAME .NES. ""
+$ THEN
+$ OPEN/WRITE OBJECTS 'EXE_DIR''ENGINE_NAME'.OPT
+$ ENDIF
+$!
+$! Here's the start of per-engine module loop.
+$!
+$ FILE_COUNTER = 0
+$ FILE_NEXT:
+$!
+$! Extract the file name from the file list, and if we've reached the end, stop
+$!
+$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",'LIB_ENGINE')
+$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
+$!
+$ FILE_COUNTER = FILE_COUNTER + 1
+$!
+$ IF FILE_NAME .EQS. "" THEN GOTO FILE_NEXT
+$!
+$! Set up the source and object reference
+$!
+$ IF F$TYPE('LIB_ENGINE'_SUBDIR) .EQS. ""
+$ THEN
+$ SOURCE_FILE = F$PARSE(FILE_NAME,"SYS$DISK:[].C",,,"SYNTAX_ONLY")
+$ ELSE
+$ SOURCE_FILE = F$PARSE(FILE_NAME,"SYS$DISK:[."+'LIB_ENGINE'_SUBDIR+"].C",,,"SYNTAX_ONLY")
+$ ENDIF
+$ OBJECT_FILE = OBJ_DIR + F$PARSE(FILE_NAME,,,"NAME","SYNTAX_ONLY") + ".OBJ"
+$!
+$! If we get some problem, we just go on trying to build the next module.
+$ ON WARNING THEN GOTO FILE_NEXT
+$!
+$! Check if the module we want to compile is actually there.
+$!
+$ IF F$SEARCH(SOURCE_FILE) .EQS. ""
+$ THEN
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Doesn't Exist."
+$ WRITE SYS$OUTPUT ""
+$ GOTO EXIT
+$ ENDIF
+$!
+$! Talk to the user.
+$!
+$ WRITE SYS$OUTPUT " ",FILE_NAME,""
+$!
+$! Do the dirty work.
+$!
+$ ON ERROR THEN GOTO FILE_NEXT
+$ IF F$EDIT(F$PARSE(SOURCE_FILE,,,"TYPE","SYNTAX_ONLY"),"UPCASE") .EQS. ".MAR"
+$ THEN
+$ MACRO/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ELSE
+$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ENDIF
+$!
+$! Write the entry to the .OPT file (for a real engine name).
+$!
+$ IF ENGINE_NAME .NES. ""
+$ THEN
+$ WRITE OBJECTS OBJECT_FILE
+$ ENDIF
+$!
+$! Next file
+$!
+$ GOTO FILE_NEXT
+$!
+$ FILE_DONE:
+$!
+$! Do not link the support files.
+$!
+$ IF ENGINE_NAME .EQS. "" THEN GOTO ENGINE_NEXT
+$!
+$! Close the linker options file (for a real engine name).
+$!
+$ CLOSE OBJECTS
+$!
+$! Now, there are two ways to handle this. We can either build
+$! shareable images or stick the engine object file into libcrypto.
+$! For now, the latter is NOT supported.
+$!
+$!!!!! LIBRARY/REPLACE 'CRYPTO_LIB' 'OBJECT_FILE'
+$!
+$! For shareable libraries, we need to do things a little differently
+$! depending on if we link with a TCP/IP library or not.
+$!
+$ ENGINE_OPT := SYS$DISK:[]'ARCH'.OPT
+$ IF TCPIP_LIB .NES. ""
+$ THEN
+$ LINK/'DEBUGGER'/'TRACEBACK' /SHARE='EXE_DIR''ENGINE_NAME'.EXE -
+ 'EXE_DIR''ENGINE_NAME'.OPT/OPTION'TV_OBJ', -
+ 'CRYPTO_LIB'/LIBRARY, -
+ 'ENGINE_OPT'/OPTION,'TCPIP_LIB','OPT_FILE'/OPTION
+$ ELSE
+$ LINK/'DEBUGGER'/'TRACEBACK' /SHARE='EXE_DIR''ENGINE_NAME'.EXE -
+ 'EXE_DIR''ENGINE_NAME'.OPT/OPTION'TV_OBJ', -
+ 'CRYPTO_LIB'/LIBRARY, -
+ 'ENGINE_OPT'/OPTION,'OPT_FILE'/OPTION
+$ ENDIF
+$!
+$! Next engine
+$!
+$ GOTO ENGINE_NEXT
+$!
+$ ENGINE_DONE:
+$!
+$! Talk to the user
+$!
+$ WRITE SYS$OUTPUT "All Done..."
+$ EXIT:
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$! Check To See If We Already Have A VAX C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A VAX C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE/SHARE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If We Already Have A GNU C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A GNU C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB/LIBRARY
+SYS$SHARE:VAXCRTL/SHARE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$! Check To See If We Already Have A DEC C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! Figure Out If We Need A non-VAX Or A VAX Linker Option File.
+$!
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$!
+$! We Need A DEC C Linker Option File For VAX.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE/SHARE
+$EOD
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Create The non-VAX Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Agianst
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
+SYS$SHARE:CMA$OPEN_RTL/SHARE
+$EOD
+$!
+$! End The DEC C Option File Check.
+$!
+$ ENDIF
+$!
+$! End The Option File Search.
+$!
+$ ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If OPT_PHASE Is Blank.
+$!
+$ IF (OPT_PHASE.EQS."ALL")
+$ THEN
+$!
+$! OPT_PHASE Is Blank, So Build Everything.
+$!
+$ BUILDALL = "ALL"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Else, Check To See If OPT_PHASE Has A Valid Argument.
+$!
+$ IF ("," + ACCEPT_PHASE + ",") - ("," + OPT_PHASE + ",") -
+ .NES. ("," + ACCEPT_PHASE + ",")
+$ THEN
+$!
+$! A Valid Argument.
+$!
+$ BUILDALL = OPT_PHASE
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The option ",OPT_PHASE," is invalid. The valid options are:"
+$ WRITE SYS$OUTPUT ""
+$ IF ("," + ACCEPT_PHASE + ",") - ",ALL," -
+ .NES. ("," + ACCEPT_PHASE + ",") THEN -
+ WRITE SYS$OUTPUT " ALL : just build everything."
+$ IF ("," + ACCEPT_PHASE + ",") - ",ENGINES," -
+ .NES. ("," + ACCEPT_PHASE + ",") THEN -
+ WRITE SYS$OUTPUT " ENGINES : to compile just the [.xxx.EXE.ENGINES]*.EXE hareable images."
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " where 'xxx' stands for:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " ALPHA : Alpha architecture."
+$ WRITE SYS$OUTPUT " IA64 : IA64 architecture."
+$ WRITE SYS$OUTPUT " VAX : VAX architecture."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! End The OPT_PHASE Check.
+$!
+$ ENDIF
+$!
+$! Check To See If OPT_DEBUG Is Blank.
+$!
+$ IF (OPT_DEBUG.EQS."NODEBUG")
+$ THEN
+$!
+$! OPT_DEBUG Is NODEBUG, So Compile Without The Debugger Information.
+$!
+$ DEBUGGER = "NODEBUG"
+$ TRACEBACK = "NOTRACEBACK"
+$ GCC_OPTIMIZE = "OPTIMIZE"
+$ CC_OPTIMIZE = "OPTIMIZE"
+$ MACRO_OPTIMIZE = "OPTIMIZE"
+$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$ ELSE
+$!
+$! Check To See If We Are To Compile With Debugger Information.
+$!
+$ IF (OPT_DEBUG.EQS."DEBUG")
+$ THEN
+$!
+$! Compile With Debugger Information.
+$!
+$ DEBUGGER = "DEBUG"
+$ TRACEBACK = "TRACEBACK"
+$ GCC_OPTIMIZE = "NOOPTIMIZE"
+$ CC_OPTIMIZE = "NOOPTIMIZE"
+$ MACRO_OPTIMIZE = "NOOPTIMIZE"
+$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$ ELSE
+$!
+$! They Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",OPT_DEBUG," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
+$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! End The OPT_DEBUG Check.
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By: Richard Levitte
+$! richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For OPT_SPECIAL_THREADS.
+$!
+$ IF (OPT_SPECIAL_THREADS.EQS."")
+$ THEN
+$!
+$! Get The Version Of VMS We Are Using.
+$!
+$ ISSEVEN :=
+$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$! Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$ IF (TMP.GE.71)
+$ THEN
+$!
+$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$ ISSEVEN := ,PTHREAD_USE_D4
+$!
+$! End The VMS Version Check.
+$!
+$ ENDIF
+$!
+$! End The OPT_SPECIAL_THREADS Check.
+$!
+$ ENDIF
+$!
+$! Check To See If OPT_POINTER_SIZE Is Blank.
+$!
+$ IF (OPT_POINTER_SIZE.EQS."")
+$ THEN
+$ POINTER_SIZE = ""
+$ ELSE
+$!
+$! Check is OPT_POINTER_SIZE Is Valid
+$!
+$ IF (OPT_POINTER_SIZE.EQS."32")
+$ THEN
+$ POINTER_SIZE = "/POINTER_SIZE=32"
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ LIB32 = ""
+$ ELSE
+$ LIB32 = "32"
+$ ENDIF
+$ ELSE
+$ IF (OPT_POINTER_SIZE.EQS."64")
+$ THEN
+$ LIB32 = ""
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ POINTER_SIZE = "/POINTER_SIZE=32"
+$ ELSE
+$ POINTER_SIZE = "/POINTER_SIZE=64"
+$ ENDIF
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",OPT_POINTER_SIZE," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " 32 : Compile with 32 bit pointer size"
+$ WRITE SYS$OUTPUT " 64 : Compile with 64 bit pointer size"
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ GOTO TIDY
+$!
+$! End The Valid Arguement Check.
+$!
+$ ENDIF
+$ ENDIF
+$!
+$! End The OPT_POINTER_SIZE Check.
+$!
+$ ENDIF
+$!
+$! Check To See If OPT_COMPILER Is Blank.
+$!
+$ IF (OPT_COMPILER.EQS."")
+$ THEN
+$!
+$! O.K., The User Didn't Specify A Compiler, Let's Try To
+$! Find Out Which One To Use.
+$!
+$! Check To See If We Have GNU C.
+$!
+$ IF (F$TRNLNM("GNU_CC").NES."")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ OPT_COMPILER = "GNUC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Check To See If We Have VAXC Or DECC.
+$!
+$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ OPT_COMPILER = "DECC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ OPT_COMPILER = "VAXC"
+$!
+$! End The VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The DECC & VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For OPT_TCPIP_LIB.
+$!
+$ IF (OPT_TCPIP_LIB.EQS."")
+$ THEN
+$!
+$! Find out what socket library we have available
+$!
+$ IF F$PARSE("SOCKETSHR:") .NES. ""
+$ THEN
+$!
+$! We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$ OPT_TCPIP_LIB = "SOCKETSHR"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$! Else, let's look for something else
+$!
+$ ELSE
+$!
+$! Like UCX (the reason to do this before Multinet is that the UCX
+$! emulation is easier to use...)
+$!
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+ .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+ .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$ THEN
+$!
+$! Last resort: a UCX or UCX-compatible library
+$!
+$ OPT_TCPIP_LIB = "UCX"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$! That was all...
+$!
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "TCPIP_TYPE_''OPT_TCPIP_LIB',DSO_VMS"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+ CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If The User Entered A Valid Paramter.
+$!
+$ IF (OPT_COMPILER.EQS."VAXC").OR.(OPT_COMPILER.EQS."DECC").OR.(OPT_COMPILER.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If The User Wanted DECC.
+$!
+$ IF (OPT_COMPILER.EQS."DECC")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ COMPILER = "DECC"
+$!
+$! Tell The User We Are Using DECC.
+$!
+$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$! Use DECC...
+$!
+$ CC = "CC"
+$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+ THEN CC = "CC/DECC"
+$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89''POINTER_SIZE'" + -
+ "/NOLIST/PREFIX=ALL" + -
+ "/INCLUDE=(SYS$DISK:[],SYS$DISK:[.VENDOR_DEFNS])" + -
+ CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
+$!
+$! End DECC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use VAXC.
+$!
+$ IF (OPT_COMPILER.EQS."VAXC")
+$ THEN
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ COMPILER = "VAXC"
+$!
+$! Tell The User We Are Using VAX C.
+$!
+$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$! Compile Using VAXC.
+$!
+$ CC = "CC"
+$ IF ARCH.NES."VAX"
+$ THEN
+$ WRITE SYS$OUTPUT "There is no VAX C on Alpha!"
+$ EXIT
+$ ENDIF
+$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
+$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[.VENDOR_DEFNS])" + -
+ CCEXTRAFLAGS
+$ CCDEFS = """VAXC""," + CCDEFS
+$!
+$! Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
+$!
+$! End VAXC Check
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use GNU C.
+$!
+$ IF (OPT_COMPILER.EQS."GNUC")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ COMPILER = "GNUC"
+$!
+$! Tell The User We Are Using GNUC.
+$!
+$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$! Use GNU C...
+$!
+$ CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[.VENDOR_DEFNS])" + -
+ CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Set up default defines
+$!
+$ CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$! Finish up the definition of CC.
+$!
+$ IF COMPILER .EQS. "DECC"
+$ THEN
+$ IF CCDISABLEWARNINGS .NES. ""
+$ THEN
+$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$ ENDIF
+$ ELSE
+$ CCDISABLEWARNINGS = ""
+$ ENDIF
+$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$!
+$! Show user the result
+$!
+$ WRITE/SYMBOL SYS$OUTPUT "Main C Compiling Command: ",CC
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",OPT_COMPILER," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
+$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
+$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! Build a MACRO command for the architecture at hand
+$!
+$ IF ARCH .EQS. "VAX" THEN MACRO = "MACRO/''DEBUGGER'"
+$ IF ARCH .NES. "VAX" THEN MACRO = "MACRO/MIGRATION/''DEBUGGER'/''MACRO_OPTIMIZE'"
+$!
+$! Show user the result
+$!
+$ WRITE/SYMBOL SYS$OUTPUT "Main MACRO Compiling Command: ",MACRO
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF OPT_TCPIP_LIB.EQS."SOCKETSHR" .OR. OPT_TCPIP_LIB.EQS."MULTINET" -
+ .OR. OPT_TCPIP_LIB.EQS."UCX" .OR. OPT_TCPIP_LIB.EQS."TCPIP" -
+ .OR. OPT_TCPIP_LIB.EQS."NONE"
+$ THEN
+$!
+$! Check to see if SOCKETSHR was chosen
+$!
+$ IF OPT_TCPIP_LIB.EQS."SOCKETSHR"
+$ THEN
+$!
+$! Set the library to use SOCKETSHR
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT"
+$!
+$! Done with SOCKETSHR
+$!
+$ ENDIF
+$!
+$! Check to see if MULTINET was chosen
+$!
+$ IF OPT_TCPIP_LIB.EQS."MULTINET"
+$ THEN
+$!
+$! Set the library to use UCX emulation.
+$!
+$ OPT_TCPIP_LIB = "UCX"
+$!
+$! Done with MULTINET
+$!
+$ ENDIF
+$!
+$! Check to see if UCX was chosen
+$!
+$ IF OPT_TCPIP_LIB.EQS."UCX"
+$ THEN
+$!
+$! Set the library to use UCX.
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT"
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$ THEN
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT/OPT"
+$ ELSE
+$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT/OPT"
+$ ENDIF
+$!
+$! Done with UCX
+$!
+$ ENDIF
+$!
+$! Check to see if TCPIP was chosen
+$!
+$ IF OPT_TCPIP_LIB.EQS."TCPIP"
+$ THEN
+$!
+$! Set the library to use TCPIP (post UCX).
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT"
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Check to see if NONE was chosen
+$!
+$ IF OPT_TCPIP_LIB.EQS."NONE"
+$ THEN
+$!
+$! Do not use a TCPIP library.
+$!
+$ TCPIP_LIB = ""
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Print info
+$!
+$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",OPT_TCPIP_LIB," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
+$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
+$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "ENGINES]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL/NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the logical name OPENSSL if it had a value
+$!
+$ IF __SAVE_OPENSSL .EQS. ""
+$ THEN
+$ DEASSIGN OPENSSL
+$ ELSE
+$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
+$ ENDIF
+$!
+$! Done
+$!
+$ RETURN
diff --git a/openssl/makevms.com b/openssl/makevms.com
index fe8271405..8c59c67ca 100644
--- a/openssl/makevms.com
+++ b/openssl/makevms.com
@@ -1,1411 +1,1411 @@
-$!
-$! MAKEVMS.COM
-$! Original Author: UNKNOWN
-$! Rewritten By: Robert Byer
-$! Vice-President
-$! A-Com Computing, Inc.
-$! byer@mail.all-net.net
-$!
-$! Changes by Richard Levitte <richard@levitte.org>
-$! Zoltan Arpadffy <zoli@polarhome.com>
-$!
-$! This procedure creates the SSL libraries of "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB"
-$! "[.xxx.EXE.SSL]LIBSSL.OLB"
-$! The "xxx" denotes the machine architecture of ALPHA, IA64 or VAX.
-$!
-$! This procedures accepts two command line options listed below.
-$!
-$! Specify one of the following build options for P1.
-$!
-$! ALL Just build "everything".
-$! CONFIG Just build the "[.CRYPTO._xxx]OPENSSLCONF.H" file.
-$! BUILDINF Just build the "[.CRYPTO._xxx]BUILDINF.H" file.
-$! SOFTLINKS Just fix the Unix soft links.
-$! BUILDALL Same as ALL, except CONFIG, BUILDINF and SOFTILNKS aren't done.
-$! CRYPTO Just build the "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" library.
-$! CRYPTO/x Just build the x part of the
-$! "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" library.
-$! SSL Just build the "[.xxx.EXE.SSL]LIBSSL.OLB" library.
-$! SSL_TASK Just build the "[.xxx.EXE.SSL]SSL_TASK.EXE" program.
-$! TEST Just build the "[.xxx.EXE.TEST]" test programs for OpenSSL.
-$! APPS Just build the "[.xxx.EXE.APPS]" application programs for OpenSSL.
-$! ENGINES Just build the "[.xxx.EXE.ENGINES]" application programs for OpenSSL.
-$!
-$!
-$! For 64 bit architectures (Alpha and IA64), specify the pointer size as P2.
-$! For 32 bit architectures (VAX), P2 is ignored.
-$! Currently supported values are:
-$!
-$! 32 To ge a library compiled with /POINTER_SIZE=32
-$! 64 To ge a library compiled with /POINTER_SIZE=64
-$!
-$!
-$! Specify DEBUG or NODEBUG as P3 to compile with or without debugging
-$! information.
-$!
-$! Specify which compiler as P4 to try to compile under.
-$!
-$! VAXC For VAX C.
-$! DECC For DEC C.
-$! GNUC For GNU C.
-$! LINK To only link the programs from existing object files.
-$! (not yet implemented)
-$!
-$! If you don't specify a compiler, it will try to determine which
-$! "C" compiler to use.
-$!
-$! P5, if defined, sets a TCP/IP library to use, through one of the following
-$! keywords:
-$!
-$! UCX for UCX or UCX emulation
-$! TCPIP for TCP/IP Services or TCP/IP Services emulation
-$! (this is prefered over UCX)
-$! SOCKETSHR for SOCKETSHR+NETLIB
-$! NONE to avoid specifying which TCP/IP implementation to
-$! use at build time (this works with DEC C). This is
-$! the default.
-$!
-$! P6, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
-$!
-$!
-$ DEF_ORIG = F$ENVIRONMENT( "DEFAULT")
-$ ON ERROR THEN GOTO TIDY
-$ ON CONTROL_C THEN GOTO TIDY
-$!
-$! Check if we're in a batch job, and make sure we get to
-$! the directory this script is in
-$!
-$ IF F$MODE() .EQS. "BATCH"
-$ THEN
-$ COMNAME=F$ENVIRONMENT("PROCEDURE")
-$ COMPATH=F$PARSE("A.;",COMNAME) - "A.;"
-$ SET DEF 'COMPATH'
-$ ENDIF
-$!
-$! Check What Architecture We Are Using.
-$!
-$ IF (F$GETSYI("CPU").LT.128)
-$ THEN
-$!
-$! The Architecture Is VAX.
-$!
-$ ARCH = "VAX"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! The Architecture Is Alpha, IA64 or whatever comes in the future.
-$!
-$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
-$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
-$!
-$! End The Architecture Check.
-$!
-$ ENDIF
-$!
-$! Get VMS version.
-$!
-$ VMS_VERSION = f$edit( f$getsyi( "VERSION"), "TRIM")
-$!
-$! Check To Make Sure We Have Valid Command Line Parameters.
-$!
-$ GOSUB CHECK_OPTIONS
-$!
-$! Check To See What We Are To Do.
-$!
-$ IF (BUILDCOMMAND.EQS."ALL")
-$ THEN
-$!
-$! Start with building the OpenSSL configuration file.
-$!
-$ GOSUB CONFIG
-$!
-$! Create The "BUILDINF.H" Include File.
-$!
-$ GOSUB BUILDINF
-$!
-$! Fix The Unix Softlinks.
-$!
-$ GOSUB SOFTLINKS
-$!
-$ ENDIF
-$!
-$ IF (BUILDCOMMAND.EQS."ALL".OR.BUILDCOMMAND.EQS."BUILDALL")
-$ THEN
-$!
-$! Build The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
-$!
-$ GOSUB CRYPTO
-$!
-$! Build The [.xxx.EXE.SSL]LIBSSL.OLB Library.
-$!
-$ GOSUB SSL
-$!
-$! Build The [.xxx.EXE.SSL]SSL_TASK.EXE DECNet SSL Engine.
-$!
-$ GOSUB SSL_TASK
-$!
-$! Build The [.xxx.EXE.TEST] OpenSSL Test Utilities.
-$!
-$ GOSUB TEST
-$!
-$! Build The [.xxx.EXE.APPS] OpenSSL Application Utilities.
-$!
-$ GOSUB APPS
-$!
-$! Build The [.xxx.EXE.ENGINES] OpenSSL Shareable Engines.
-$!
-$ GOSUB ENGINES
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Build Just What The User Wants Us To Build.
-$!
-$ GOSUB 'BUILDCOMMAND'
-$!
-$ ENDIF
-$!
-$! Time To EXIT.
-$!
-$ GOTO TIDY
-$!
-$! Rebuild The [.CRYPTO._xxx]OPENSSLCONF.H" file.
-$!
-$ CONFIG:
-$!
-$! Tell The User We Are Creating The [.CRYPTO._xxx]OPENSSLCONF.H File.
-$!
-$ WRITE SYS$OUTPUT "Creating [.CRYPTO._''ARCH']OPENSSLCONF.H Include File."
-$!
-$! First, make sure the directory exists.
-$!
-$ IF F$PARSE("SYS$DISK:[.CRYPTO._''ARCH']") .EQS. "" THEN -
- CREATE/DIRECTORY SYS$DISK:[.CRYPTO._'ARCH']
-$!
-$! Different tar/UnZip versions/option may have named the file differently
-$ IF F$SEARCH("[.crypto]opensslconf.h_in") .NES. ""
-$ THEN
-$ OPENSSLCONF_H_IN = "[.crypto]opensslconf.h_in"
-$ ELSE
-$ IF F$SEARCH( "[.crypto]opensslconf_h.in") .NES. ""
-$ THEN
-$ OPENSSLCONF_H_IN = "[.crypto]opensslconf_h.in"
-$ ELSE
-$ ! For ODS-5
-$ IF F$SEARCH( "[.crypto]opensslconf.h.in") .NES. ""
-$ THEN
-$ OPENSSLCONF_H_IN = "[.crypto]opensslconf.h.in"
-$ ELSE
-$ WRITE SYS$ERROR "Couldn't find a [.crypto]opensslconf.h.in. Exiting!"
-$ $STATUS = %X00018294 ! "%RMS-F-FNF, file not found".
-$ GOTO TIDY
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$!
-$! Create The [.CRYPTO._xxx]OPENSSLCONF.H File.
-$! Make sure it has the right format.
-$!
-$ OSCH_NAME = "SYS$DISK:[.CRYPTO._''ARCH']OPENSSLCONF.H"
-$ CREATE /FDL=SYS$INPUT: 'OSCH_NAME'
-RECORD
- FORMAT stream_lf
-$ OPEN /APPEND H_FILE 'OSCH_NAME'
-$!
-$! Write The [.CRYPTO._xxx]OPENSSLCONF.H File.
-$!
-$ WRITE H_FILE "/* This file was automatically built using makevms.com */"
-$ WRITE H_FILE "/* and ''OPENSSLCONF_H_IN' */"
-$!
-$! Write a few macros that indicate how this system was built.
-$!
-$ WRITE H_FILE ""
-$ WRITE H_FILE "#ifndef OPENSSL_SYS_VMS"
-$ WRITE H_FILE "# define OPENSSL_SYS_VMS"
-$ WRITE H_FILE "#endif"
-$
-$! One of the best way to figure out what the list should be is to do
-$! the followin on a Unix system:
-$! grep OPENSSL_NO_ crypto/*/*.h ssl/*.h engines/*.h engines/*/*.h|grep ':# *if'|sed -e 's/^.*def //'|sort|uniq
-$! For that reason, the list will also always end up in alphabetical order
-$ CONFIG_LOGICALS := AES,-
- ASM,INLINE_ASM,-
- BF,-
- BIO,-
- BUFFER,-
- BUF_FREELISTS,-
- CAMELLIA,-
- CAST,-
- CMS,-
- COMP,-
- DEPRECATED,-
- DES,-
- DGRAM,-
- DH,-
- DSA,-
- EC,-
- ECDH,-
- ECDSA,-
- ENGINE,-
- ERR,-
- EVP,-
- FP_API,-
- GMP,-
- GOST,-
- HASH_COMP,-
- HMAC,-
- IDEA,-
- JPAKE,-
- KRB5,-
- LHASH,-
- MD2,-
- MD4,-
- MD5,-
- MDC2,-
- OCSP,-
- PSK,-
- RC2,-
- RC4,-
- RC5,-
- RFC3779,-
- RIPEMD,-
- RSA,-
- SEED,-
- SHA,-
- SHA0,-
- SHA1,-
- SHA256,-
- SHA512,-
- SOCK,-
- SSL2,-
- STACK,-
- STATIC_ENGINE,-
- STDIO,-
- STORE,-
- TLSEXT,-
- WHIRLPOOL,-
- X509
-$! Add a few that we know about
-$ CONFIG_LOGICALS := 'CONFIG_LOGICALS',-
- THREADS
-$! The following rules, which dictate how some algorithm choices affect
-$! others, are picked from Configure.
-$! Quick syntax:
-$! list = item[ ; list]
-$! item = algos / dependents
-$! algos = algo [, algos]
-$! dependents = dependent [, dependents]
-$! When a list of algos is specified in one item, it means that they must
-$! all be disabled for the rule to apply.
-$! When a list of dependents is specified in one item, it means that they
-$! will all be disabled if the rule applies.
-$! Rules are checked sequentially. If a rule disables an algorithm, it will
-$! affect all following rules that depend on that algorithm being disabled.
-$! To force something to be enabled or disabled, have no algorithms in the
-$! algos part.
-$ CONFIG_DISABLE_RULES := RIJNDAEL/AES;-
- DES/MDC2;-
- EC/ECDSA,ECDH;-
- MD5/SSL2,SSL3,TLS1;-
- SHA/SSL3,TLS1;-
- RSA/SSL2;-
- RSA,DSA/SSL2;-
- DH/SSL3,TLS1;-
- TLS1/TLSEXT;-
- EC/GOST;-
- DSA/GOST;-
- DH/GOST;-
- /STATIC_ENGINE;-
- /KRB5
-$ CONFIG_ENABLE_RULES := ZLIB_DYNAMIC/ZLIB;-
- /THREADS
-$
-$! Architecture specific rule addtions
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ ! Disable algorithms that require 64 bit integers in C
-$ CONFIG_DISABLE_RULES = CONFIG_DISABLE_RULES + -
- ";/GOST" + -
- ";/WHIRLPOOL"
-$ ENDIF
-$
-$ CONFIG_LOG_I = 0
-$ CONFIG_LOG_LOOP1:
-$ CONFIG_LOG_E = F$EDIT(F$ELEMENT(CONFIG_LOG_I,",",CONFIG_LOGICALS),"TRIM")
-$ CONFIG_LOG_I = CONFIG_LOG_I + 1
-$ IF CONFIG_LOG_E .EQS. "" THEN GOTO CONFIG_LOG_LOOP1
-$ IF CONFIG_LOG_E .EQS. "," THEN GOTO CONFIG_LOG_LOOP1_END
-$ IF F$TRNLNM("OPENSSL_NO_"+CONFIG_LOG_E)
-$ THEN
-$ CONFIG_DISABLED_'CONFIG_LOG_E' := YES
-$ CONFIG_ENABLED_'CONFIG_LOG_E' := NO
-$ CONFIG_CHANGED_'CONFIG_LOG_E' := YES
-$ ELSE
-$ CONFIG_DISABLED_'CONFIG_LOG_E' := NO
-$ CONFIG_ENABLED_'CONFIG_LOG_E' := YES
-$ ! Because all algorithms are assumed enabled by default
-$ CONFIG_CHANGED_'CONFIG_LOG_E' := NO
-$ ENDIF
-$ GOTO CONFIG_LOG_LOOP1
-$ CONFIG_LOG_LOOP1_END:
-$
-$! Apply cascading disable rules
-$ CONFIG_DISABLE_I = 0
-$ CONFIG_DISABLE_LOOP0:
-$ CONFIG_DISABLE_E = F$EDIT(F$ELEMENT(CONFIG_DISABLE_I,";",CONFIG_DISABLE_RULES),"TRIM")
-$ CONFIG_DISABLE_I = CONFIG_DISABLE_I + 1
-$ IF CONFIG_DISABLE_E .EQS. "" THEN GOTO CONFIG_DISABLE_LOOP0
-$ IF CONFIG_DISABLE_E .EQS. ";" THEN GOTO CONFIG_DISABLE_LOOP0_END
-$
-$ CONFIG_DISABLE_ALGOS = F$EDIT(F$ELEMENT(0,"/",CONFIG_DISABLE_E),"TRIM")
-$ CONFIG_DISABLE_DEPENDENTS = F$EDIT(F$ELEMENT(1,"/",CONFIG_DISABLE_E),"TRIM")
-$ TO_DISABLE := YES
-$ CONFIG_ALGO_I = 0
-$ CONFIG_DISABLE_LOOP1:
-$ CONFIG_ALGO_E = F$EDIT(F$ELEMENT(CONFIG_ALGO_I,",",CONFIG_DISABLE_ALGOS),"TRIM")
-$ CONFIG_ALGO_I = CONFIG_ALGO_I + 1
-$ IF CONFIG_ALGO_E .EQS. "" THEN GOTO CONFIG_DISABLE_LOOP1
-$ IF CONFIG_ALGO_E .EQS. "," THEN GOTO CONFIG_DISABLE_LOOP1_END
-$ IF F$TYPE(CONFIG_DISABLED_'CONFIG_ALGO_E') .EQS. ""
-$ THEN
-$ TO_DISABLE := NO
-$ ELSE
-$ IF .NOT. CONFIG_DISABLED_'CONFIG_ALGO_E' THEN TO_DISABLE := NO
-$ ENDIF
-$ GOTO CONFIG_DISABLE_LOOP1
-$ CONFIG_DISABLE_LOOP1_END:
-$
-$ IF TO_DISABLE
-$ THEN
-$ CONFIG_DEPENDENT_I = 0
-$ CONFIG_DISABLE_LOOP2:
-$ CONFIG_DEPENDENT_E = F$EDIT(F$ELEMENT(CONFIG_DEPENDENT_I,",",CONFIG_DISABLE_DEPENDENTS),"TRIM")
-$ CONFIG_DEPENDENT_I = CONFIG_DEPENDENT_I + 1
-$ IF CONFIG_DEPENDENT_E .EQS. "" THEN GOTO CONFIG_DISABLE_LOOP2
-$ IF CONFIG_DEPENDENT_E .EQS. "," THEN GOTO CONFIG_DISABLE_LOOP2_END
-$ CONFIG_DISABLED_'CONFIG_DEPENDENT_E' := YES
-$ CONFIG_ENABLED_'CONFIG_DEPENDENT_E' := NO
-$ ! Better not to assume defaults at this point...
-$ CONFIG_CHANGED_'CONFIG_DEPENDENT_E' := YES
-$ WRITE SYS$ERROR "''CONFIG_DEPENDENT_E' disabled by rule ''CONFIG_DISABLE_E'"
-$ GOTO CONFIG_DISABLE_LOOP2
-$ CONFIG_DISABLE_LOOP2_END:
-$ ENDIF
-$ GOTO CONFIG_DISABLE_LOOP0
-$ CONFIG_DISABLE_LOOP0_END:
-$
-$! Apply cascading enable rules
-$ CONFIG_ENABLE_I = 0
-$ CONFIG_ENABLE_LOOP0:
-$ CONFIG_ENABLE_E = F$EDIT(F$ELEMENT(CONFIG_ENABLE_I,";",CONFIG_ENABLE_RULES),"TRIM")
-$ CONFIG_ENABLE_I = CONFIG_ENABLE_I + 1
-$ IF CONFIG_ENABLE_E .EQS. "" THEN GOTO CONFIG_ENABLE_LOOP0
-$ IF CONFIG_ENABLE_E .EQS. ";" THEN GOTO CONFIG_ENABLE_LOOP0_END
-$
-$ CONFIG_ENABLE_ALGOS = F$EDIT(F$ELEMENT(0,"/",CONFIG_ENABLE_E),"TRIM")
-$ CONFIG_ENABLE_DEPENDENTS = F$EDIT(F$ELEMENT(1,"/",CONFIG_ENABLE_E),"TRIM")
-$ TO_ENABLE := YES
-$ CONFIG_ALGO_I = 0
-$ CONFIG_ENABLE_LOOP1:
-$ CONFIG_ALGO_E = F$EDIT(F$ELEMENT(CONFIG_ALGO_I,",",CONFIG_ENABLE_ALGOS),"TRIM")
-$ CONFIG_ALGO_I = CONFIG_ALGO_I + 1
-$ IF CONFIG_ALGO_E .EQS. "" THEN GOTO CONFIG_ENABLE_LOOP1
-$ IF CONFIG_ALGO_E .EQS. "," THEN GOTO CONFIG_ENABLE_LOOP1_END
-$ IF F$TYPE(CONFIG_ENABLED_'CONFIG_ALGO_E') .EQS. ""
-$ THEN
-$ TO_ENABLE := NO
-$ ELSE
-$ IF .NOT. CONFIG_ENABLED_'CONFIG_ALGO_E' THEN TO_ENABLE := NO
-$ ENDIF
-$ GOTO CONFIG_ENABLE_LOOP1
-$ CONFIG_ENABLE_LOOP1_END:
-$
-$ IF TO_ENABLE
-$ THEN
-$ CONFIG_DEPENDENT_I = 0
-$ CONFIG_ENABLE_LOOP2:
-$ CONFIG_DEPENDENT_E = F$EDIT(F$ELEMENT(CONFIG_DEPENDENT_I,",",CONFIG_ENABLE_DEPENDENTS),"TRIM")
-$ CONFIG_DEPENDENT_I = CONFIG_DEPENDENT_I + 1
-$ IF CONFIG_DEPENDENT_E .EQS. "" THEN GOTO CONFIG_ENABLE_LOOP2
-$ IF CONFIG_DEPENDENT_E .EQS. "," THEN GOTO CONFIG_ENABLE_LOOP2_END
-$ CONFIG_DISABLED_'CONFIG_DEPENDENT_E' := NO
-$ CONFIG_ENABLED_'CONFIG_DEPENDENT_E' := YES
-$ ! Better not to assume defaults at this point...
-$ CONFIG_CHANGED_'CONFIG_DEPENDENT_E' := YES
-$ WRITE SYS$ERROR "''CONFIG_DEPENDENT_E' enabled by rule ''CONFIG_ENABLE_E'"
-$ GOTO CONFIG_ENABLE_LOOP2
-$ CONFIG_ENABLE_LOOP2_END:
-$ ENDIF
-$ GOTO CONFIG_ENABLE_LOOP0
-$ CONFIG_ENABLE_LOOP0_END:
-$
-$! Write to the configuration
-$ CONFIG_LOG_I = 0
-$ CONFIG_LOG_LOOP2:
-$ CONFIG_LOG_E = F$EDIT(F$ELEMENT(CONFIG_LOG_I,",",CONFIG_LOGICALS),"TRIM")
-$ CONFIG_LOG_I = CONFIG_LOG_I + 1
-$ IF CONFIG_LOG_E .EQS. "" THEN GOTO CONFIG_LOG_LOOP2
-$ IF CONFIG_LOG_E .EQS. "," THEN GOTO CONFIG_LOG_LOOP2_END
-$ IF CONFIG_CHANGED_'CONFIG_LOG_E'
-$ THEN
-$ IF CONFIG_DISABLED_'CONFIG_LOG_E'
-$ THEN
-$ WRITE H_FILE "#ifndef OPENSSL_NO_",CONFIG_LOG_E
-$ WRITE H_FILE "# define OPENSSL_NO_",CONFIG_LOG_E
-$ WRITE H_FILE "#endif"
-$ ELSE
-$ WRITE H_FILE "#ifndef OPENSSL_",CONFIG_LOG_E
-$ WRITE H_FILE "# define OPENSSL_",CONFIG_LOG_E
-$ WRITE H_FILE "#endif"
-$ ENDIF
-$ ENDIF
-$ GOTO CONFIG_LOG_LOOP2
-$ CONFIG_LOG_LOOP2_END:
-$!
-$! Add in the common "crypto/opensslconf.h.in".
-$!
-$ TYPE 'OPENSSLCONF_H_IN' /OUTPUT=H_FILE:
-$!
-$ IF ARCH .NES. "VAX"
-$ THEN
-$!
-$! Write the non-VAX specific data
-$!
-$ WRITE H_FILE "#if defined(HEADER_RC4_H)"
-$ WRITE H_FILE "#undef RC4_INT"
-$ WRITE H_FILE "#define RC4_INT unsigned int"
-$ WRITE H_FILE "#undef RC4_CHUNK"
-$ WRITE H_FILE "#define RC4_CHUNK unsigned long long"
-$ WRITE H_FILE "#endif"
-$!
-$ WRITE H_FILE "#if defined(HEADER_DES_LOCL_H)"
-$ WRITE H_FILE "#undef DES_LONG"
-$ WRITE H_FILE "#define DES_LONG unsigned int"
-$ WRITE H_FILE "#undef DES_PTR"
-$ WRITE H_FILE "#define DES_PTR"
-$ WRITE H_FILE "#undef DES_RISC1"
-$ WRITE H_FILE "#undef DES_RISC2"
-$ WRITE H_FILE "#define DES_RISC1"
-$ WRITE H_FILE "#undef DES_UNROLL"
-$ WRITE H_FILE "#define DES_UNROLL"
-$ WRITE H_FILE "#endif"
-$!
-$ WRITE H_FILE "#if defined(HEADER_BN_H)"
-$ WRITE H_FILE "#undef BN_LLONG" ! Never define with SIXTY_FOUR_BIT
-$ WRITE H_FILE "#undef SIXTY_FOUR_BIT_LONG"
-$ WRITE H_FILE "#undef SIXTY_FOUR_BIT"
-$ WRITE H_FILE "#define SIXTY_FOUR_BIT"
-$ WRITE H_FILE "#undef THIRTY_TWO_BIT"
-$ WRITE H_FILE "#undef SIXTEEN_BIT"
-$ WRITE H_FILE "#undef EIGHT_BIT"
-$ WRITE H_FILE "#endif"
-$
-$ WRITE H_FILE "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Write the VAX specific data
-$!
-$ WRITE H_FILE "#if defined(HEADER_RC4_H)"
-$ WRITE H_FILE "#undef RC4_INT"
-$ WRITE H_FILE "#define RC4_INT unsigned char"
-$ WRITE H_FILE "#undef RC4_CHUNK"
-$ WRITE H_FILE "#define RC4_CHUNK unsigned long"
-$ WRITE H_FILE "#endif"
-$!
-$ WRITE H_FILE "#if defined(HEADER_DES_LOCL_H)"
-$ WRITE H_FILE "#undef DES_LONG"
-$ WRITE H_FILE "#define DES_LONG unsigned long"
-$ WRITE H_FILE "#undef DES_PTR"
-$ WRITE H_FILE "#define DES_PTR"
-$ WRITE H_FILE "#undef DES_RISC1"
-$ WRITE H_FILE "#undef DES_RISC2"
-$ WRITE H_FILE "#undef DES_UNROLL"
-$ WRITE H_FILE "#endif"
-$!
-$ WRITE H_FILE "#if defined(HEADER_BN_H)"
-$ WRITE H_FILE "#undef BN_LLONG" ! VAX C/DEC C doesn't have long long
-$ WRITE H_FILE "#undef SIXTY_FOUR_BIT_LONG"
-$ WRITE H_FILE "#undef SIXTY_FOUR_BIT"
-$ WRITE H_FILE "#undef THIRTY_TWO_BIT"
-$ WRITE H_FILE "#define THIRTY_TWO_BIT"
-$ WRITE H_FILE "#undef SIXTEEN_BIT"
-$ WRITE H_FILE "#undef EIGHT_BIT"
-$ WRITE H_FILE "#endif"
-$!
-$! Oddly enough, the following symbol is tested in crypto/sha/sha512.c
-$! before sha.h gets included (and HEADER_SHA_H defined), so we will not
-$! protect this one...
-$ WRITE H_FILE "#undef OPENSSL_NO_SHA512"
-$ WRITE H_FILE "#define OPENSSL_NO_SHA512"
-$!
-$ WRITE H_FILE "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION"
-$ WRITE H_FILE "#define OPENSSL_EXPORT_VAR_AS_FUNCTION"
-$!
-$! End
-$!
-$ ENDIF
-$!
-$! Close the [.CRYPTO._xxx]OPENSSLCONF.H file
-$!
-$ CLOSE H_FILE
-$!
-$! Purge The [.CRYPTO._xxx]OPENSSLCONF.H file
-$!
-$ PURGE SYS$DISK:[.CRYPTO._'ARCH']OPENSSLCONF.H
-$!
-$! That's All, Time To RETURN.
-$!
-$ RETURN
-$!
-$! Rebuild The "[.CRYPTO._xxx]BUILDINF.H" file.
-$!
-$ BUILDINF:
-$!
-$! Tell The User We Are Creating The [.CRYPTO._xxx]BUILDINF.H File.
-$!
-$ WRITE SYS$OUTPUT "Creating [.CRYPTO._''ARCH']BUILDINF.H Include File."
-$!
-$! Create The [.CRYPTO._xxx]BUILDINF.H File.
-$!
-$ BIH_NAME = "SYS$DISK:[.CRYPTO._''ARCH']BUILDINF.H"
-$ CREATE /FDL=SYS$INPUT: 'BIH_NAME'
-RECORD
- FORMAT stream_lf
-$!
-$ OPEN /APPEND H_FILE 'bih_name'
-$!
-$! Get The Current Date & Time.
-$!
-$ TIME = F$TIME()
-$!
-$! Write The [.CRYPTO._xxx]BUILDINF.H File.
-$!
-$ WRITE H_FILE "#define CFLAGS ""/POINTER_SIZE=''POINTER_SIZE'"""
-$ WRITE H_FILE "#define PLATFORM ""VMS ''ARCH' ''VMS_VERSION'"""
-$ WRITE H_FILE "#define DATE ""''TIME'"" "
-$!
-$! Close The [.CRYPTO._xxx]BUILDINF.H File.
-$!
-$ CLOSE H_FILE
-$!
-$! Purge The [.CRYPTO._xxx]BUILDINF.H File.
-$!
-$ PURGE SYS$DISK:[.CRYPTO._'ARCH']BUILDINF.H
-$!
-$! Delete [.CRYPTO]BUILDINF.H File, as there might be some residue from Unix.
-$!
-$ IF F$SEARCH("[.CRYPTO]BUILDINF.H") .NES. "" THEN -
- DELETE SYS$DISK:[.CRYPTO]BUILDINF.H;*
-$!
-$! That's All, Time To RETURN.
-$!
-$ RETURN
-$!
-$! Copy a lot of files around.
-$!
-$ SOFTLINKS:
-$!
-$! Tell The User We Are Partly Rebuilding The [.APPS] Directory.
-$!
-$ WRITE SYS$OUTPUT "Rebuilding The '[.APPS]MD4.C' File."
-$!
-$ DELETE SYS$DISK:[.APPS]MD4.C;*
-$!
-$! Copy MD4.C from [.CRYPTO.MD4] into [.APPS]
-$!
-$ COPY SYS$DISK:[.CRYPTO.MD4]MD4.C SYS$DISK:[.APPS]
-$!
-$! Tell The User We Are Rebuilding The [.INCLUDE.OPENSSL] Directory.
-$!
-$ WRITE SYS$OUTPUT "Rebuilding The '[.INCLUDE.OPENSSL]' Directory."
-$!
-$! First, make sure the directory exists
-$!
-$ IF F$PARSE("SYS$DISK:[.INCLUDE.OPENSSL]") .EQS. "" THEN -
- CREATE/DIRECTORY SYS$DISK:[.INCLUDE.OPENSSL]
-$!
-$! Copy All The ".H" Files From The Main Directory.
-$!
-$ EXHEADER := e_os2.h
-$ COPY 'EXHEADER' SYS$DISK:[.INCLUDE.OPENSSL]
-$!
-$! Copy All The ".H" Files From The [.CRYPTO] Directory Tree.
-$!
-$ SDIRS := ,-
- _'ARCH',-
- OBJECTS,-
- MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,WHRLPOOL,-
- DES,AES,RC2,RC4,RC5,IDEA,BF,CAST,CAMELLIA,SEED,MODES,-
- BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,-
- BUFFER,BIO,STACK,LHASH,RAND,ERR,-
- EVP,ASN1,PEM,X509,X509V3,CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,UI,KRB5,-
- STORE,CMS,PQUEUE,TS,JPAKE
-$ EXHEADER_ := crypto.h,opensslv.h,ebcdic.h,symhacks.h,ossl_typ.h
-$ EXHEADER__'ARCH' := opensslconf.h
-$ EXHEADER_OBJECTS := objects.h,obj_mac.h
-$ EXHEADER_MD2 := md2.h
-$ EXHEADER_MD4 := md4.h
-$ EXHEADER_MD5 := md5.h
-$ EXHEADER_SHA := sha.h
-$ EXHEADER_MDC2 := mdc2.h
-$ EXHEADER_HMAC := hmac.h
-$ EXHEADER_RIPEMD := ripemd.h
-$ EXHEADER_WHRLPOOL := whrlpool.h
-$ EXHEADER_DES := des.h,des_old.h
-$ EXHEADER_AES := aes.h
-$ EXHEADER_RC2 := rc2.h
-$ EXHEADER_RC4 := rc4.h
-$ EXHEADER_RC5 := rc5.h
-$ EXHEADER_IDEA := idea.h
-$ EXHEADER_BF := blowfish.h
-$ EXHEADER_CAST := cast.h
-$ EXHEADER_CAMELLIA := camellia.h
-$ EXHEADER_SEED := seed.h
-$ EXHEADER_MODES := modes.h
-$ EXHEADER_BN := bn.h
-$ EXHEADER_EC := ec.h
-$ EXHEADER_RSA := rsa.h
-$ EXHEADER_DSA := dsa.h
-$ EXHEADER_ECDSA := ecdsa.h
-$ EXHEADER_DH := dh.h
-$ EXHEADER_ECDH := ecdh.h
-$ EXHEADER_DSO := dso.h
-$ EXHEADER_ENGINE := engine.h
-$ EXHEADER_BUFFER := buffer.h
-$ EXHEADER_BIO := bio.h
-$ EXHEADER_STACK := stack.h,safestack.h
-$ EXHEADER_LHASH := lhash.h
-$ EXHEADER_RAND := rand.h
-$ EXHEADER_ERR := err.h
-$ EXHEADER_EVP := evp.h
-$ EXHEADER_ASN1 := asn1.h,asn1_mac.h,asn1t.h
-$ EXHEADER_PEM := pem.h,pem2.h
-$ EXHEADER_X509 := x509.h,x509_vfy.h
-$ EXHEADER_X509V3 := x509v3.h
-$ EXHEADER_CONF := conf.h,conf_api.h
-$ EXHEADER_TXT_DB := txt_db.h
-$ EXHEADER_PKCS7 := pkcs7.h
-$ EXHEADER_PKCS12 := pkcs12.h
-$ EXHEADER_COMP := comp.h
-$ EXHEADER_OCSP := ocsp.h
-$ EXHEADER_UI := ui.h,ui_compat.h
-$ EXHEADER_KRB5 := krb5_asn.h
-$!EXHEADER_STORE := store.h,str_compat.h
-$ EXHEADER_STORE := store.h
-$ EXHEADER_CMS := cms.h
-$ EXHEADER_PQUEUE := pqueue.h
-$ EXHEADER_TS := ts.h
-$ EXHEADER_JPAKE := jpake.h
-$
-$ I = 0
-$ LOOP_SDIRS:
-$ D = F$EDIT(F$ELEMENT(I, ",", SDIRS),"TRIM")
-$ I = I + 1
-$ IF D .EQS. "," THEN GOTO LOOP_SDIRS_END
-$ tmp = EXHEADER_'D'
-$ IF D .EQS. ""
-$ THEN
-$ COPY [.CRYPTO]'tmp' SYS$DISK:[.INCLUDE.OPENSSL] !/LOG
-$ ELSE
-$ COPY [.CRYPTO.'D']'tmp' SYS$DISK:[.INCLUDE.OPENSSL] !/LOG
-$ ENDIF
-$ GOTO LOOP_SDIRS
-$ LOOP_SDIRS_END:
-$!
-$! Copy All The ".H" Files From The [.SSL] Directory.
-$!
-$ EXHEADER := ssl.h,ssl2.h,ssl3.h,ssl23.h,tls1.h,dtls1.h,kssl.h
-$ COPY SYS$DISK:[.SSL]'EXHEADER' SYS$DISK:[.INCLUDE.OPENSSL]
-$!
-$! Purge all doubles
-$!
-$ PURGE SYS$DISK:[.INCLUDE.OPENSSL]*.H
-$!
-$! That's All, Time To RETURN.
-$!
-$ RETURN
-$!
-$! Build The "[.xxx.EXE.CRYPTO]LIBCRYPTO''LIB32'.OLB" Library.
-$!
-$ CRYPTO:
-$!
-$! Tell The User What We Are Doing.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Building The [.",ARCH,".EXE.CRYPTO]LIBCRYPTO''LIB32'.OLB Library."
-$!
-$! Go To The [.CRYPTO] Directory.
-$!
-$ SET DEFAULT SYS$DISK:[.CRYPTO]
-$!
-$! Build The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
-$!
-$ @CRYPTO-LIB LIBRARY 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'"
-$!
-$! Build The [.xxx.EXE.CRYPTO]*.EXE Test Applications.
-$!
-$ @CRYPTO-LIB APPS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'"
-$!
-$! Go Back To The Main Directory.
-$!
-$ SET DEFAULT [-]
-$!
-$! Time To RETURN.
-$!
-$ RETURN
-$!
-$! Build The "[.xxx.EXE.SSL]LIBSSL''LIB32'.OLB" Library.
-$!
-$ SSL:
-$!
-$! Tell The User What We Are Doing.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Building The [.",ARCH,".EXE.SSL]LIBSSL''LIB32'.OLB Library."
-$!
-$! Go To The [.SSL] Directory.
-$!
-$ SET DEFAULT SYS$DISK:[.SSL]
-$!
-$! Build The [.xxx.EXE.SSL]LIBSSL.OLB Library.
-$!
-$ @SSL-LIB LIBRARY 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "''POINTER_SIZE'"
-$!
-$! Go Back To The Main Directory.
-$!
-$ SET DEFAULT [-]
-$!
-$! Time To Return.
-$!
-$ RETURN
-$!
-$! Build The "[.xxx.EXE.SSL]SSL_TASK.EXE" Program.
-$!
-$ SSL_TASK:
-$!
-$! Tell The User What We Are Doing.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Building DECNet Based SSL Engine, [.",ARCH,".EXE.SSL]SSL_TASK.EXE"
-$!
-$! Go To The [.SSL] Directory.
-$!
-$ SET DEFAULT SYS$DISK:[.SSL]
-$!
-$! Build The [.xxx.EXE.SSL]SSL_TASK.EXE
-$!
-$ @SSL-LIB SSL_TASK 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "''POINTER_SIZE'"
-$!
-$! Go Back To The Main Directory.
-$!
-$ SET DEFAULT [-]
-$!
-$! That's All, Time To RETURN.
-$!
-$ RETURN
-$!
-$! Build The OpenSSL Test Programs.
-$!
-$ TEST:
-$!
-$! Tell The User What We Are Doing.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Building The OpenSSL [.",ARCH,".EXE.TEST] Test Utilities."
-$!
-$! Go To The [.TEST] Directory.
-$!
-$ SET DEFAULT SYS$DISK:[.TEST]
-$!
-$! Build The Test Programs.
-$!
-$ @MAKETESTS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "''POINTER_SIZE'"
-$!
-$! Go Back To The Main Directory.
-$!
-$ SET DEFAULT [-]
-$!
-$! That's All, Time To RETURN.
-$!
-$ RETURN
-$!
-$! Build The OpenSSL Application Programs.
-$!
-$ APPS:
-$!
-$! Tell The User What We Are Doing.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Building OpenSSL [.",ARCH,".EXE.APPS] Applications."
-$!
-$! Go To The [.APPS] Directory.
-$!
-$ SET DEFAULT SYS$DISK:[.APPS]
-$!
-$! Build The Application Programs.
-$!
-$ @MAKEAPPS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "" "''POINTER_SIZE'"
-$!
-$! Go Back To The Main Directory.
-$!
-$ SET DEFAULT [-]
-$!
-$! That's All, Time To RETURN.
-$!
-$ RETURN
-$!
-$! Build The OpenSSL Application Programs.
-$!
-$ ENGINES:
-$!
-$! Tell The User What We Are Doing.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Building OpenSSL [.",ARCH,".EXE.ENGINES] Engines."
-$!
-$! Go To The [.ENGINES] Directory.
-$!
-$ SET DEFAULT SYS$DISK:[.ENGINES]
-$!
-$! Build The Application Programs.
-$!
-$ @MAKEENGINES ENGINES 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'"
-$!
-$! Go Back To The Main Directory.
-$!
-$ SET DEFAULT [-]
-$!
-$! That's All, Time To RETURN.
-$!
-$ RETURN
-$!
-$! Check The User's Options.
-$!
-$ CHECK_OPTIONS:
-$!
-$! Check if there's a "part", and separate it out
-$!
-$ BUILDPART = F$ELEMENT(1,"/",P1)
-$ IF BUILDPART .EQS. "/"
-$ THEN
-$ BUILDPART = ""
-$ ELSE
-$ P1 = F$EXTRACT(0,F$LENGTH(P1) - F$LENGTH(BUILDPART) - 1, P1)
-$ ENDIF
-$!
-$! Check To See If P1 Is Blank.
-$!
-$ IF (P1.EQS."ALL")
-$ THEN
-$!
-$! P1 Is ALL, So Build Everything.
-$!
-$ BUILDCOMMAND = "ALL"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Else, Check To See If P1 Has A Valid Argument.
-$!
-$ IF (P1.EQS."CONFIG").OR.(P1.EQS."BUILDINF").OR.(P1.EQS."SOFTLINKS") -
- .OR.(P1.EQS."BUILDALL") -
- .OR.(P1.EQS."CRYPTO").OR.(P1.EQS."SSL") -
- .OR.(P1.EQS."SSL_TASK").OR.(P1.EQS."TEST").OR.(P1.EQS."APPS") -
- .OR.(P1.EQS."ENGINES")
-$ THEN
-$!
-$! A Valid Argument.
-$!
-$ BUILDCOMMAND = P1
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "USAGE: @MAKEVMS.COM [Target] [Pointer size] [Debug option] <Compiler>"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Example: @MAKEVMS.COM ALL """" NODEBUG "
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Target ",P1," Is Invalid. The Valid Target Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALL : Just Build Everything."
-$ WRITE SYS$OUTPUT " CONFIG : Just build the [.CRYPTO._xxx]OPENSSLCONF.H file."
-$ WRITE SYS$OUTPUT " BUILDINF : Just build the [.CRYPTO._xxx]BUILDINF.H file."
-$ WRITE SYS$OUTPUT " SOFTLINKS: Just Fix The Unix soft links."
-$ WRITE SYS$OUTPUT " BUILDALL : Same as ALL, except CONFIG, BUILDINF and SOFTILNKS aren't done."
-$ WRITE SYS$OUTPUT " CRYPTO : To Build Just The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
-$ WRITE SYS$OUTPUT " CRYPTO/x : To Build Just The x Part Of The"
-$ WRITE SYS$OUTPUT " [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
-$ WRITE SYS$OUTPUT " SSL : To Build Just The [.xxx.EXE.SSL]LIBSSL.OLB Library."
-$ WRITE SYS$OUTPUT " SSL_TASK : To Build Just The [.xxx.EXE.SSL]SSL_TASK.EXE Program."
-$ WRITE SYS$OUTPUT " TEST : To Build Just The OpenSSL Test Programs."
-$ WRITE SYS$OUTPUT " APPS : To Build Just The OpenSSL Application Programs."
-$ WRITE SYS$OUTPUT " ENGINES : To Build Just The ENGINES"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALPHA : Alpha Architecture."
-$ WRITE SYS$OUTPUT " IA64 : IA64 Architecture."
-$ WRITE SYS$OUTPUT " VAX : VAX Architecture."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ GOTO TIDY
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P1 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P2 Is Blank.
-$!
-$ IF (P2.EQS."")
-$ THEN
-$ POINTER_SIZE = ""
-$ ELSE
-$!
-$! Check is P2 Is Valid
-$!
-$ IF (P2.EQS."32")
-$ THEN
-$ POINTER_SIZE = "32"
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ LIB32 = ""
-$ ELSE
-$ LIB32 = "32"
-$ ENDIF
-$ ELSE
-$ IF (P2.EQS."64")
-$ THEN
-$ LIB32 = ""
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ POINTER_SIZE = "32"
-$ ELSE
-$ POINTER_SIZE = "64"
-$ ENDIF
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " 32 : Compile with 32 bit pointer size"
-$ WRITE SYS$OUTPUT " 64 : Compile with 64 bit pointer size"
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ GOTO TIDY
-$!
-$! End The Valid Arguement Check.
-$!
-$ ENDIF
-$ ENDIF
-$!
-$! End The P2 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P3 Is Blank.
-$!
-$ IF (P3.EQS."NODEBUG")
-$ THEN
-$!
-$! P3 Is NODEBUG, So Compile Without Debugger Information.
-$!
-$ DEBUGGER = "NODEBUG"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Check To See If We Are To Compile With Debugger Information.
-$!
-$ IF (P3.EQS."DEBUG")
-$ THEN
-$!
-$! Compile With Debugger Information.
-$!
-$ DEBUGGER = "DEBUG"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
-$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ GOTO TIDY
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P3 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P4 Is Blank.
-$!
-$ IF (P4.EQS."")
-$ THEN
-$!
-$! O.K., The User Didn't Specify A Compiler, Let's Try To
-$! Find Out Which One To Use.
-$!
-$! Check To See If We Have GNU C.
-$!
-$ IF (F$TRNLNM("GNU_CC").NES."")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ COMPILER = "GNUC"
-$!
-$! Tell The User We Are Using GNUC.
-$!
-$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
-$!
-$! End The GNU C Compiler Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Have VAXC Or DECC.
-$!
-$ IF (F$GETSYI("CPU").GE.128).OR.(F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ COMPILER = "DECC"
-$!
-$! Tell The User We Are Using DECC.
-$!
-$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ COMPILER = "VAXC"
-$!
-$! Tell The User We Are Using VAX C.
-$!
-$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
-$!
-$! End The DECC & VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Check To See If The User Entered A Valid Paramter.
-$!
-$ IF (P4.EQS."VAXC").OR.(P4.EQS."DECC").OR.(P4.EQS."GNUC")!.OR.(P4.EQS."LINK")
-$ THEN
-$!
-$! Check To See If The User Wanted To Just LINK.
-$!
-$ IF (P4.EQS."LINK")
-$ THEN
-$!
-$! Looks Like LINK-only
-$!
-$ COMPILER = "LINK"
-$!
-$! Tell The User We Are Only Linking.
-$!
-$ WRITE SYS$OUTPUT "LINK Only. This actually NOT YET SUPPORTED!"
-$!
-$! End LINK Check.
-$!
-$ ENDIF
-$!
-$! Check To See If The User Wanted DECC.
-$!
-$ IF (P4.EQS."DECC")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ COMPILER = "DECC"
-$!
-$! Tell The User We Are Using DECC.
-$!
-$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
-$!
-$! End DECC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use VAXC.
-$!
-$ IF (P4.EQS."VAXC")
-$ THEN
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ COMPILER = "VAXC"
-$!
-$! Tell The User We Are Using VAX C.
-$!
-$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
-$!
-$! End VAXC Check
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use GNU C.
-$!
-$ IF (P4.EQS."GNUC")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ COMPILER = "GNUC"
-$!
-$! Tell The User We Are Using GNUC.
-$!
-$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P4," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
-$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
-$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ GOTO TIDY
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P4 Check.
-$!
-$ ENDIF
-$!
-$! Time to check the contents of P5, and to make sure we get the correct library.
-$!
-$ IF P5.EQS."SOCKETSHR" .OR. P5.EQS."MULTINET" .OR. P5.EQS."UCX" -
- .OR. P5.EQS."TCPIP" .OR. P5.EQS."NONE"
-$ THEN
-$!
-$! Check to see if SOCKETSHR was chosen
-$!
-$ IF P5.EQS."SOCKETSHR"
-$ THEN
-$!
-$! Set the library to use SOCKETSHR
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
-$!
-$! Done with SOCKETSHR
-$!
-$ ENDIF
-$!
-$! Check to see if MULTINET was chosen
-$!
-$ IF P5.EQS."MULTINET"
-$ THEN
-$!
-$! Set the library to use UCX emulation.
-$!
-$ P5 = "UCX"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using MultiNet via UCX emulation for TCP/IP"
-$!
-$! Done with MULTINET
-$!
-$ ENDIF
-$!
-$! Check to see if UCX was chosen
-$!
-$ IF P5.EQS."UCX"
-$ THEN
-$!
-$! Set the library to use UCX.
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
-$!
-$! Done with UCX
-$!
-$ ENDIF
-$!
-$! Check to see if TCPIP was chosen
-$!
-$ IF P5.EQS."TCPIP"
-$ THEN
-$!
-$! Set the library to use TCPIP (post UCX).
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using TCPIP (post UCX) for TCP/IP"
-$!
-$! Done with TCPIP
-$!
-$ ENDIF
-$!
-$! Check to see if NONE was chosen
-$!
-$ IF P5.EQS."NONE"
-$ THEN
-$!
-$! Do not use a TCPIP library.
-$!
-$ TCPIP_LIB = ""
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "A specific TCPIP library will not be used."
-$!
-$! Done with NONE.
-$!
-$ ENDIF
-$!
-$! Set the TCPIP_TYPE symbol
-$!
-$ TCPIP_TYPE = P5
-$!
-$! Print info
-$!
-$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$ IF P5 .NES. ""
-$ THEN
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P5," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
-$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
-$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP TCP/IP (post UCX) library."
-$ WRITE SYS$OUTPUT " NONE : To not link with a specific TCP/IP library."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ GOTO TIDY
-$ ELSE
-$!
-$! If TCPIP is not defined, then hardcode it to make
-$! it clear that no TCPIP is desired.
-$!
-$ IF P5 .EQS. ""
-$ THEN
-$ TCPIP_LIB = ""
-$ TCPIP_TYPE = "NONE"
-$ ELSE
-$!
-$! Set the TCPIP_TYPE symbol
-$!
-$ TCPIP_TYPE = P5
-$ ENDIF
-$ ENDIF
-$!
-$! Done with TCP/IP libraries
-$!
-$ ENDIF
-$!
-$! Special Threads For OpenVMS v7.1 Or Later
-$!
-$! Written By: Richard Levitte
-$! richard@levitte.org
-$!
-$!
-$! Check To See If We Have A Option For P6.
-$!
-$ IF (P6.EQS."")
-$ THEN
-$!
-$! Get The Version Of VMS We Are Using.
-$!
-$ ISSEVEN :=
-$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,VMS_VERSION))
-$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
-$!
-$! Check To See If The VMS Version Is v7.1 Or Later.
-$!
-$ IF (TMP.GE.71)
-$ THEN
-$!
-$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
-$!
-$ ISSEVEN := ,PTHREAD_USE_D4
-$!
-$! End The VMS Version Check.
-$!
-$ ENDIF
-$!
-$! End The P6 Check.
-$!
-$ ENDIF
-$!
-$! Time To RETURN...
-$!
-$ RETURN
-$!
-$ TIDY:
-$ SET DEFAULT 'DEF_ORIG'
-$ EXIT
-$!
+$!
+$! MAKEVMS.COM
+$! Original Author: UNKNOWN
+$! Rewritten By: Robert Byer
+$! Vice-President
+$! A-Com Computing, Inc.
+$! byer@mail.all-net.net
+$!
+$! Changes by Richard Levitte <richard@levitte.org>
+$! Zoltan Arpadffy <zoli@polarhome.com>
+$!
+$! This procedure creates the SSL libraries of "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB"
+$! "[.xxx.EXE.SSL]LIBSSL.OLB"
+$! The "xxx" denotes the machine architecture of ALPHA, IA64 or VAX.
+$!
+$! This procedures accepts two command line options listed below.
+$!
+$! Specify one of the following build options for P1.
+$!
+$! ALL Just build "everything".
+$! CONFIG Just build the "[.CRYPTO._xxx]OPENSSLCONF.H" file.
+$! BUILDINF Just build the "[.CRYPTO._xxx]BUILDINF.H" file.
+$! SOFTLINKS Just fix the Unix soft links.
+$! BUILDALL Same as ALL, except CONFIG, BUILDINF and SOFTILNKS aren't done.
+$! CRYPTO Just build the "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" library.
+$! CRYPTO/x Just build the x part of the
+$! "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" library.
+$! SSL Just build the "[.xxx.EXE.SSL]LIBSSL.OLB" library.
+$! SSL_TASK Just build the "[.xxx.EXE.SSL]SSL_TASK.EXE" program.
+$! TEST Just build the "[.xxx.EXE.TEST]" test programs for OpenSSL.
+$! APPS Just build the "[.xxx.EXE.APPS]" application programs for OpenSSL.
+$! ENGINES Just build the "[.xxx.EXE.ENGINES]" application programs for OpenSSL.
+$!
+$!
+$! For 64 bit architectures (Alpha and IA64), specify the pointer size as P2.
+$! For 32 bit architectures (VAX), P2 is ignored.
+$! Currently supported values are:
+$!
+$! 32 To ge a library compiled with /POINTER_SIZE=32
+$! 64 To ge a library compiled with /POINTER_SIZE=64
+$!
+$!
+$! Specify DEBUG or NODEBUG as P3 to compile with or without debugging
+$! information.
+$!
+$! Specify which compiler as P4 to try to compile under.
+$!
+$! VAXC For VAX C.
+$! DECC For DEC C.
+$! GNUC For GNU C.
+$! LINK To only link the programs from existing object files.
+$! (not yet implemented)
+$!
+$! If you don't specify a compiler, it will try to determine which
+$! "C" compiler to use.
+$!
+$! P5, if defined, sets a TCP/IP library to use, through one of the following
+$! keywords:
+$!
+$! UCX for UCX or UCX emulation
+$! TCPIP for TCP/IP Services or TCP/IP Services emulation
+$! (this is prefered over UCX)
+$! SOCKETSHR for SOCKETSHR+NETLIB
+$! NONE to avoid specifying which TCP/IP implementation to
+$! use at build time (this works with DEC C). This is
+$! the default.
+$!
+$! P6, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$!
+$ DEF_ORIG = F$ENVIRONMENT( "DEFAULT")
+$ ON ERROR THEN GOTO TIDY
+$ ON CONTROL_C THEN GOTO TIDY
+$!
+$! Check if we're in a batch job, and make sure we get to
+$! the directory this script is in
+$!
+$ IF F$MODE() .EQS. "BATCH"
+$ THEN
+$ COMNAME=F$ENVIRONMENT("PROCEDURE")
+$ COMPATH=F$PARSE("A.;",COMNAME) - "A.;"
+$ SET DEF 'COMPATH'
+$ ENDIF
+$!
+$! Check What Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$! The Architecture Is VAX.
+$!
+$ ARCH = "VAX"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$! Get VMS version.
+$!
+$ VMS_VERSION = f$edit( f$getsyi( "VERSION"), "TRIM")
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Check To See What We Are To Do.
+$!
+$ IF (BUILDCOMMAND.EQS."ALL")
+$ THEN
+$!
+$! Start with building the OpenSSL configuration file.
+$!
+$ GOSUB CONFIG
+$!
+$! Create The "BUILDINF.H" Include File.
+$!
+$ GOSUB BUILDINF
+$!
+$! Fix The Unix Softlinks.
+$!
+$ GOSUB SOFTLINKS
+$!
+$ ENDIF
+$!
+$ IF (BUILDCOMMAND.EQS."ALL".OR.BUILDCOMMAND.EQS."BUILDALL")
+$ THEN
+$!
+$! Build The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
+$!
+$ GOSUB CRYPTO
+$!
+$! Build The [.xxx.EXE.SSL]LIBSSL.OLB Library.
+$!
+$ GOSUB SSL
+$!
+$! Build The [.xxx.EXE.SSL]SSL_TASK.EXE DECNet SSL Engine.
+$!
+$ GOSUB SSL_TASK
+$!
+$! Build The [.xxx.EXE.TEST] OpenSSL Test Utilities.
+$!
+$ GOSUB TEST
+$!
+$! Build The [.xxx.EXE.APPS] OpenSSL Application Utilities.
+$!
+$ GOSUB APPS
+$!
+$! Build The [.xxx.EXE.ENGINES] OpenSSL Shareable Engines.
+$!
+$ GOSUB ENGINES
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Build Just What The User Wants Us To Build.
+$!
+$ GOSUB 'BUILDCOMMAND'
+$!
+$ ENDIF
+$!
+$! Time To EXIT.
+$!
+$ GOTO TIDY
+$!
+$! Rebuild The [.CRYPTO._xxx]OPENSSLCONF.H" file.
+$!
+$ CONFIG:
+$!
+$! Tell The User We Are Creating The [.CRYPTO._xxx]OPENSSLCONF.H File.
+$!
+$ WRITE SYS$OUTPUT "Creating [.CRYPTO._''ARCH']OPENSSLCONF.H Include File."
+$!
+$! First, make sure the directory exists.
+$!
+$ IF F$PARSE("SYS$DISK:[.CRYPTO._''ARCH']") .EQS. "" THEN -
+ CREATE/DIRECTORY SYS$DISK:[.CRYPTO._'ARCH']
+$!
+$! Different tar/UnZip versions/option may have named the file differently
+$ IF F$SEARCH("[.crypto]opensslconf.h_in") .NES. ""
+$ THEN
+$ OPENSSLCONF_H_IN = "[.crypto]opensslconf.h_in"
+$ ELSE
+$ IF F$SEARCH( "[.crypto]opensslconf_h.in") .NES. ""
+$ THEN
+$ OPENSSLCONF_H_IN = "[.crypto]opensslconf_h.in"
+$ ELSE
+$ ! For ODS-5
+$ IF F$SEARCH( "[.crypto]opensslconf.h.in") .NES. ""
+$ THEN
+$ OPENSSLCONF_H_IN = "[.crypto]opensslconf.h.in"
+$ ELSE
+$ WRITE SYS$ERROR "Couldn't find a [.crypto]opensslconf.h.in. Exiting!"
+$ $STATUS = %X00018294 ! "%RMS-F-FNF, file not found".
+$ GOTO TIDY
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$!
+$! Create The [.CRYPTO._xxx]OPENSSLCONF.H File.
+$! Make sure it has the right format.
+$!
+$ OSCH_NAME = "SYS$DISK:[.CRYPTO._''ARCH']OPENSSLCONF.H"
+$ CREATE /FDL=SYS$INPUT: 'OSCH_NAME'
+RECORD
+ FORMAT stream_lf
+$ OPEN /APPEND H_FILE 'OSCH_NAME'
+$!
+$! Write The [.CRYPTO._xxx]OPENSSLCONF.H File.
+$!
+$ WRITE H_FILE "/* This file was automatically built using makevms.com */"
+$ WRITE H_FILE "/* and ''OPENSSLCONF_H_IN' */"
+$!
+$! Write a few macros that indicate how this system was built.
+$!
+$ WRITE H_FILE ""
+$ WRITE H_FILE "#ifndef OPENSSL_SYS_VMS"
+$ WRITE H_FILE "# define OPENSSL_SYS_VMS"
+$ WRITE H_FILE "#endif"
+$
+$! One of the best way to figure out what the list should be is to do
+$! the followin on a Unix system:
+$! grep OPENSSL_NO_ crypto/*/*.h ssl/*.h engines/*.h engines/*/*.h|grep ':# *if'|sed -e 's/^.*def //'|sort|uniq
+$! For that reason, the list will also always end up in alphabetical order
+$ CONFIG_LOGICALS := AES,-
+ ASM,INLINE_ASM,-
+ BF,-
+ BIO,-
+ BUFFER,-
+ BUF_FREELISTS,-
+ CAMELLIA,-
+ CAST,-
+ CMS,-
+ COMP,-
+ DEPRECATED,-
+ DES,-
+ DGRAM,-
+ DH,-
+ DSA,-
+ EC,-
+ ECDH,-
+ ECDSA,-
+ ENGINE,-
+ ERR,-
+ EVP,-
+ FP_API,-
+ GMP,-
+ GOST,-
+ HASH_COMP,-
+ HMAC,-
+ IDEA,-
+ JPAKE,-
+ KRB5,-
+ LHASH,-
+ MD2,-
+ MD4,-
+ MD5,-
+ MDC2,-
+ OCSP,-
+ PSK,-
+ RC2,-
+ RC4,-
+ RC5,-
+ RFC3779,-
+ RIPEMD,-
+ RSA,-
+ SEED,-
+ SHA,-
+ SHA0,-
+ SHA1,-
+ SHA256,-
+ SHA512,-
+ SOCK,-
+ SSL2,-
+ STACK,-
+ STATIC_ENGINE,-
+ STDIO,-
+ STORE,-
+ TLSEXT,-
+ WHIRLPOOL,-
+ X509
+$! Add a few that we know about
+$ CONFIG_LOGICALS := 'CONFIG_LOGICALS',-
+ THREADS
+$! The following rules, which dictate how some algorithm choices affect
+$! others, are picked from Configure.
+$! Quick syntax:
+$! list = item[ ; list]
+$! item = algos / dependents
+$! algos = algo [, algos]
+$! dependents = dependent [, dependents]
+$! When a list of algos is specified in one item, it means that they must
+$! all be disabled for the rule to apply.
+$! When a list of dependents is specified in one item, it means that they
+$! will all be disabled if the rule applies.
+$! Rules are checked sequentially. If a rule disables an algorithm, it will
+$! affect all following rules that depend on that algorithm being disabled.
+$! To force something to be enabled or disabled, have no algorithms in the
+$! algos part.
+$ CONFIG_DISABLE_RULES := RIJNDAEL/AES;-
+ DES/MDC2;-
+ EC/ECDSA,ECDH;-
+ MD5/SSL2,SSL3,TLS1;-
+ SHA/SSL3,TLS1;-
+ RSA/SSL2;-
+ RSA,DSA/SSL2;-
+ DH/SSL3,TLS1;-
+ TLS1/TLSEXT;-
+ EC/GOST;-
+ DSA/GOST;-
+ DH/GOST;-
+ /STATIC_ENGINE;-
+ /KRB5
+$ CONFIG_ENABLE_RULES := ZLIB_DYNAMIC/ZLIB;-
+ /THREADS
+$
+$! Architecture specific rule addtions
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ ! Disable algorithms that require 64 bit integers in C
+$ CONFIG_DISABLE_RULES = CONFIG_DISABLE_RULES + -
+ ";/GOST" + -
+ ";/WHIRLPOOL"
+$ ENDIF
+$
+$ CONFIG_LOG_I = 0
+$ CONFIG_LOG_LOOP1:
+$ CONFIG_LOG_E = F$EDIT(F$ELEMENT(CONFIG_LOG_I,",",CONFIG_LOGICALS),"TRIM")
+$ CONFIG_LOG_I = CONFIG_LOG_I + 1
+$ IF CONFIG_LOG_E .EQS. "" THEN GOTO CONFIG_LOG_LOOP1
+$ IF CONFIG_LOG_E .EQS. "," THEN GOTO CONFIG_LOG_LOOP1_END
+$ IF F$TRNLNM("OPENSSL_NO_"+CONFIG_LOG_E)
+$ THEN
+$ CONFIG_DISABLED_'CONFIG_LOG_E' := YES
+$ CONFIG_ENABLED_'CONFIG_LOG_E' := NO
+$ CONFIG_CHANGED_'CONFIG_LOG_E' := YES
+$ ELSE
+$ CONFIG_DISABLED_'CONFIG_LOG_E' := NO
+$ CONFIG_ENABLED_'CONFIG_LOG_E' := YES
+$ ! Because all algorithms are assumed enabled by default
+$ CONFIG_CHANGED_'CONFIG_LOG_E' := NO
+$ ENDIF
+$ GOTO CONFIG_LOG_LOOP1
+$ CONFIG_LOG_LOOP1_END:
+$
+$! Apply cascading disable rules
+$ CONFIG_DISABLE_I = 0
+$ CONFIG_DISABLE_LOOP0:
+$ CONFIG_DISABLE_E = F$EDIT(F$ELEMENT(CONFIG_DISABLE_I,";",CONFIG_DISABLE_RULES),"TRIM")
+$ CONFIG_DISABLE_I = CONFIG_DISABLE_I + 1
+$ IF CONFIG_DISABLE_E .EQS. "" THEN GOTO CONFIG_DISABLE_LOOP0
+$ IF CONFIG_DISABLE_E .EQS. ";" THEN GOTO CONFIG_DISABLE_LOOP0_END
+$
+$ CONFIG_DISABLE_ALGOS = F$EDIT(F$ELEMENT(0,"/",CONFIG_DISABLE_E),"TRIM")
+$ CONFIG_DISABLE_DEPENDENTS = F$EDIT(F$ELEMENT(1,"/",CONFIG_DISABLE_E),"TRIM")
+$ TO_DISABLE := YES
+$ CONFIG_ALGO_I = 0
+$ CONFIG_DISABLE_LOOP1:
+$ CONFIG_ALGO_E = F$EDIT(F$ELEMENT(CONFIG_ALGO_I,",",CONFIG_DISABLE_ALGOS),"TRIM")
+$ CONFIG_ALGO_I = CONFIG_ALGO_I + 1
+$ IF CONFIG_ALGO_E .EQS. "" THEN GOTO CONFIG_DISABLE_LOOP1
+$ IF CONFIG_ALGO_E .EQS. "," THEN GOTO CONFIG_DISABLE_LOOP1_END
+$ IF F$TYPE(CONFIG_DISABLED_'CONFIG_ALGO_E') .EQS. ""
+$ THEN
+$ TO_DISABLE := NO
+$ ELSE
+$ IF .NOT. CONFIG_DISABLED_'CONFIG_ALGO_E' THEN TO_DISABLE := NO
+$ ENDIF
+$ GOTO CONFIG_DISABLE_LOOP1
+$ CONFIG_DISABLE_LOOP1_END:
+$
+$ IF TO_DISABLE
+$ THEN
+$ CONFIG_DEPENDENT_I = 0
+$ CONFIG_DISABLE_LOOP2:
+$ CONFIG_DEPENDENT_E = F$EDIT(F$ELEMENT(CONFIG_DEPENDENT_I,",",CONFIG_DISABLE_DEPENDENTS),"TRIM")
+$ CONFIG_DEPENDENT_I = CONFIG_DEPENDENT_I + 1
+$ IF CONFIG_DEPENDENT_E .EQS. "" THEN GOTO CONFIG_DISABLE_LOOP2
+$ IF CONFIG_DEPENDENT_E .EQS. "," THEN GOTO CONFIG_DISABLE_LOOP2_END
+$ CONFIG_DISABLED_'CONFIG_DEPENDENT_E' := YES
+$ CONFIG_ENABLED_'CONFIG_DEPENDENT_E' := NO
+$ ! Better not to assume defaults at this point...
+$ CONFIG_CHANGED_'CONFIG_DEPENDENT_E' := YES
+$ WRITE SYS$ERROR "''CONFIG_DEPENDENT_E' disabled by rule ''CONFIG_DISABLE_E'"
+$ GOTO CONFIG_DISABLE_LOOP2
+$ CONFIG_DISABLE_LOOP2_END:
+$ ENDIF
+$ GOTO CONFIG_DISABLE_LOOP0
+$ CONFIG_DISABLE_LOOP0_END:
+$
+$! Apply cascading enable rules
+$ CONFIG_ENABLE_I = 0
+$ CONFIG_ENABLE_LOOP0:
+$ CONFIG_ENABLE_E = F$EDIT(F$ELEMENT(CONFIG_ENABLE_I,";",CONFIG_ENABLE_RULES),"TRIM")
+$ CONFIG_ENABLE_I = CONFIG_ENABLE_I + 1
+$ IF CONFIG_ENABLE_E .EQS. "" THEN GOTO CONFIG_ENABLE_LOOP0
+$ IF CONFIG_ENABLE_E .EQS. ";" THEN GOTO CONFIG_ENABLE_LOOP0_END
+$
+$ CONFIG_ENABLE_ALGOS = F$EDIT(F$ELEMENT(0,"/",CONFIG_ENABLE_E),"TRIM")
+$ CONFIG_ENABLE_DEPENDENTS = F$EDIT(F$ELEMENT(1,"/",CONFIG_ENABLE_E),"TRIM")
+$ TO_ENABLE := YES
+$ CONFIG_ALGO_I = 0
+$ CONFIG_ENABLE_LOOP1:
+$ CONFIG_ALGO_E = F$EDIT(F$ELEMENT(CONFIG_ALGO_I,",",CONFIG_ENABLE_ALGOS),"TRIM")
+$ CONFIG_ALGO_I = CONFIG_ALGO_I + 1
+$ IF CONFIG_ALGO_E .EQS. "" THEN GOTO CONFIG_ENABLE_LOOP1
+$ IF CONFIG_ALGO_E .EQS. "," THEN GOTO CONFIG_ENABLE_LOOP1_END
+$ IF F$TYPE(CONFIG_ENABLED_'CONFIG_ALGO_E') .EQS. ""
+$ THEN
+$ TO_ENABLE := NO
+$ ELSE
+$ IF .NOT. CONFIG_ENABLED_'CONFIG_ALGO_E' THEN TO_ENABLE := NO
+$ ENDIF
+$ GOTO CONFIG_ENABLE_LOOP1
+$ CONFIG_ENABLE_LOOP1_END:
+$
+$ IF TO_ENABLE
+$ THEN
+$ CONFIG_DEPENDENT_I = 0
+$ CONFIG_ENABLE_LOOP2:
+$ CONFIG_DEPENDENT_E = F$EDIT(F$ELEMENT(CONFIG_DEPENDENT_I,",",CONFIG_ENABLE_DEPENDENTS),"TRIM")
+$ CONFIG_DEPENDENT_I = CONFIG_DEPENDENT_I + 1
+$ IF CONFIG_DEPENDENT_E .EQS. "" THEN GOTO CONFIG_ENABLE_LOOP2
+$ IF CONFIG_DEPENDENT_E .EQS. "," THEN GOTO CONFIG_ENABLE_LOOP2_END
+$ CONFIG_DISABLED_'CONFIG_DEPENDENT_E' := NO
+$ CONFIG_ENABLED_'CONFIG_DEPENDENT_E' := YES
+$ ! Better not to assume defaults at this point...
+$ CONFIG_CHANGED_'CONFIG_DEPENDENT_E' := YES
+$ WRITE SYS$ERROR "''CONFIG_DEPENDENT_E' enabled by rule ''CONFIG_ENABLE_E'"
+$ GOTO CONFIG_ENABLE_LOOP2
+$ CONFIG_ENABLE_LOOP2_END:
+$ ENDIF
+$ GOTO CONFIG_ENABLE_LOOP0
+$ CONFIG_ENABLE_LOOP0_END:
+$
+$! Write to the configuration
+$ CONFIG_LOG_I = 0
+$ CONFIG_LOG_LOOP2:
+$ CONFIG_LOG_E = F$EDIT(F$ELEMENT(CONFIG_LOG_I,",",CONFIG_LOGICALS),"TRIM")
+$ CONFIG_LOG_I = CONFIG_LOG_I + 1
+$ IF CONFIG_LOG_E .EQS. "" THEN GOTO CONFIG_LOG_LOOP2
+$ IF CONFIG_LOG_E .EQS. "," THEN GOTO CONFIG_LOG_LOOP2_END
+$ IF CONFIG_CHANGED_'CONFIG_LOG_E'
+$ THEN
+$ IF CONFIG_DISABLED_'CONFIG_LOG_E'
+$ THEN
+$ WRITE H_FILE "#ifndef OPENSSL_NO_",CONFIG_LOG_E
+$ WRITE H_FILE "# define OPENSSL_NO_",CONFIG_LOG_E
+$ WRITE H_FILE "#endif"
+$ ELSE
+$ WRITE H_FILE "#ifndef OPENSSL_",CONFIG_LOG_E
+$ WRITE H_FILE "# define OPENSSL_",CONFIG_LOG_E
+$ WRITE H_FILE "#endif"
+$ ENDIF
+$ ENDIF
+$ GOTO CONFIG_LOG_LOOP2
+$ CONFIG_LOG_LOOP2_END:
+$!
+$! Add in the common "crypto/opensslconf.h.in".
+$!
+$ TYPE 'OPENSSLCONF_H_IN' /OUTPUT=H_FILE:
+$!
+$ IF ARCH .NES. "VAX"
+$ THEN
+$!
+$! Write the non-VAX specific data
+$!
+$ WRITE H_FILE "#if defined(HEADER_RC4_H)"
+$ WRITE H_FILE "#undef RC4_INT"
+$ WRITE H_FILE "#define RC4_INT unsigned int"
+$ WRITE H_FILE "#undef RC4_CHUNK"
+$ WRITE H_FILE "#define RC4_CHUNK unsigned long long"
+$ WRITE H_FILE "#endif"
+$!
+$ WRITE H_FILE "#if defined(HEADER_DES_LOCL_H)"
+$ WRITE H_FILE "#undef DES_LONG"
+$ WRITE H_FILE "#define DES_LONG unsigned int"
+$ WRITE H_FILE "#undef DES_PTR"
+$ WRITE H_FILE "#define DES_PTR"
+$ WRITE H_FILE "#undef DES_RISC1"
+$ WRITE H_FILE "#undef DES_RISC2"
+$ WRITE H_FILE "#define DES_RISC1"
+$ WRITE H_FILE "#undef DES_UNROLL"
+$ WRITE H_FILE "#define DES_UNROLL"
+$ WRITE H_FILE "#endif"
+$!
+$ WRITE H_FILE "#if defined(HEADER_BN_H)"
+$ WRITE H_FILE "#undef BN_LLONG" ! Never define with SIXTY_FOUR_BIT
+$ WRITE H_FILE "#undef SIXTY_FOUR_BIT_LONG"
+$ WRITE H_FILE "#undef SIXTY_FOUR_BIT"
+$ WRITE H_FILE "#define SIXTY_FOUR_BIT"
+$ WRITE H_FILE "#undef THIRTY_TWO_BIT"
+$ WRITE H_FILE "#undef SIXTEEN_BIT"
+$ WRITE H_FILE "#undef EIGHT_BIT"
+$ WRITE H_FILE "#endif"
+$
+$ WRITE H_FILE "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Write the VAX specific data
+$!
+$ WRITE H_FILE "#if defined(HEADER_RC4_H)"
+$ WRITE H_FILE "#undef RC4_INT"
+$ WRITE H_FILE "#define RC4_INT unsigned char"
+$ WRITE H_FILE "#undef RC4_CHUNK"
+$ WRITE H_FILE "#define RC4_CHUNK unsigned long"
+$ WRITE H_FILE "#endif"
+$!
+$ WRITE H_FILE "#if defined(HEADER_DES_LOCL_H)"
+$ WRITE H_FILE "#undef DES_LONG"
+$ WRITE H_FILE "#define DES_LONG unsigned long"
+$ WRITE H_FILE "#undef DES_PTR"
+$ WRITE H_FILE "#define DES_PTR"
+$ WRITE H_FILE "#undef DES_RISC1"
+$ WRITE H_FILE "#undef DES_RISC2"
+$ WRITE H_FILE "#undef DES_UNROLL"
+$ WRITE H_FILE "#endif"
+$!
+$ WRITE H_FILE "#if defined(HEADER_BN_H)"
+$ WRITE H_FILE "#undef BN_LLONG" ! VAX C/DEC C doesn't have long long
+$ WRITE H_FILE "#undef SIXTY_FOUR_BIT_LONG"
+$ WRITE H_FILE "#undef SIXTY_FOUR_BIT"
+$ WRITE H_FILE "#undef THIRTY_TWO_BIT"
+$ WRITE H_FILE "#define THIRTY_TWO_BIT"
+$ WRITE H_FILE "#undef SIXTEEN_BIT"
+$ WRITE H_FILE "#undef EIGHT_BIT"
+$ WRITE H_FILE "#endif"
+$!
+$! Oddly enough, the following symbol is tested in crypto/sha/sha512.c
+$! before sha.h gets included (and HEADER_SHA_H defined), so we will not
+$! protect this one...
+$ WRITE H_FILE "#undef OPENSSL_NO_SHA512"
+$ WRITE H_FILE "#define OPENSSL_NO_SHA512"
+$!
+$ WRITE H_FILE "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION"
+$ WRITE H_FILE "#define OPENSSL_EXPORT_VAR_AS_FUNCTION"
+$!
+$! End
+$!
+$ ENDIF
+$!
+$! Close the [.CRYPTO._xxx]OPENSSLCONF.H file
+$!
+$ CLOSE H_FILE
+$!
+$! Purge The [.CRYPTO._xxx]OPENSSLCONF.H file
+$!
+$ PURGE SYS$DISK:[.CRYPTO._'ARCH']OPENSSLCONF.H
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Rebuild The "[.CRYPTO._xxx]BUILDINF.H" file.
+$!
+$ BUILDINF:
+$!
+$! Tell The User We Are Creating The [.CRYPTO._xxx]BUILDINF.H File.
+$!
+$ WRITE SYS$OUTPUT "Creating [.CRYPTO._''ARCH']BUILDINF.H Include File."
+$!
+$! Create The [.CRYPTO._xxx]BUILDINF.H File.
+$!
+$ BIH_NAME = "SYS$DISK:[.CRYPTO._''ARCH']BUILDINF.H"
+$ CREATE /FDL=SYS$INPUT: 'BIH_NAME'
+RECORD
+ FORMAT stream_lf
+$!
+$ OPEN /APPEND H_FILE 'bih_name'
+$!
+$! Get The Current Date & Time.
+$!
+$ TIME = F$TIME()
+$!
+$! Write The [.CRYPTO._xxx]BUILDINF.H File.
+$!
+$ WRITE H_FILE "#define CFLAGS ""/POINTER_SIZE=''POINTER_SIZE'"""
+$ WRITE H_FILE "#define PLATFORM ""VMS ''ARCH' ''VMS_VERSION'"""
+$ WRITE H_FILE "#define DATE ""''TIME'"" "
+$!
+$! Close The [.CRYPTO._xxx]BUILDINF.H File.
+$!
+$ CLOSE H_FILE
+$!
+$! Purge The [.CRYPTO._xxx]BUILDINF.H File.
+$!
+$ PURGE SYS$DISK:[.CRYPTO._'ARCH']BUILDINF.H
+$!
+$! Delete [.CRYPTO]BUILDINF.H File, as there might be some residue from Unix.
+$!
+$ IF F$SEARCH("[.CRYPTO]BUILDINF.H") .NES. "" THEN -
+ DELETE SYS$DISK:[.CRYPTO]BUILDINF.H;*
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Copy a lot of files around.
+$!
+$ SOFTLINKS:
+$!
+$! Tell The User We Are Partly Rebuilding The [.APPS] Directory.
+$!
+$ WRITE SYS$OUTPUT "Rebuilding The '[.APPS]MD4.C' File."
+$!
+$ DELETE SYS$DISK:[.APPS]MD4.C;*
+$!
+$! Copy MD4.C from [.CRYPTO.MD4] into [.APPS]
+$!
+$ COPY SYS$DISK:[.CRYPTO.MD4]MD4.C SYS$DISK:[.APPS]
+$!
+$! Tell The User We Are Rebuilding The [.INCLUDE.OPENSSL] Directory.
+$!
+$ WRITE SYS$OUTPUT "Rebuilding The '[.INCLUDE.OPENSSL]' Directory."
+$!
+$! First, make sure the directory exists
+$!
+$ IF F$PARSE("SYS$DISK:[.INCLUDE.OPENSSL]") .EQS. "" THEN -
+ CREATE/DIRECTORY SYS$DISK:[.INCLUDE.OPENSSL]
+$!
+$! Copy All The ".H" Files From The Main Directory.
+$!
+$ EXHEADER := e_os2.h
+$ COPY 'EXHEADER' SYS$DISK:[.INCLUDE.OPENSSL]
+$!
+$! Copy All The ".H" Files From The [.CRYPTO] Directory Tree.
+$!
+$ SDIRS := ,-
+ _'ARCH',-
+ OBJECTS,-
+ MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,WHRLPOOL,-
+ DES,AES,RC2,RC4,RC5,IDEA,BF,CAST,CAMELLIA,SEED,MODES,-
+ BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,-
+ BUFFER,BIO,STACK,LHASH,RAND,ERR,-
+ EVP,ASN1,PEM,X509,X509V3,CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,UI,KRB5,-
+ STORE,CMS,PQUEUE,TS,JPAKE
+$ EXHEADER_ := crypto.h,opensslv.h,ebcdic.h,symhacks.h,ossl_typ.h
+$ EXHEADER__'ARCH' := opensslconf.h
+$ EXHEADER_OBJECTS := objects.h,obj_mac.h
+$ EXHEADER_MD2 := md2.h
+$ EXHEADER_MD4 := md4.h
+$ EXHEADER_MD5 := md5.h
+$ EXHEADER_SHA := sha.h
+$ EXHEADER_MDC2 := mdc2.h
+$ EXHEADER_HMAC := hmac.h
+$ EXHEADER_RIPEMD := ripemd.h
+$ EXHEADER_WHRLPOOL := whrlpool.h
+$ EXHEADER_DES := des.h,des_old.h
+$ EXHEADER_AES := aes.h
+$ EXHEADER_RC2 := rc2.h
+$ EXHEADER_RC4 := rc4.h
+$ EXHEADER_RC5 := rc5.h
+$ EXHEADER_IDEA := idea.h
+$ EXHEADER_BF := blowfish.h
+$ EXHEADER_CAST := cast.h
+$ EXHEADER_CAMELLIA := camellia.h
+$ EXHEADER_SEED := seed.h
+$ EXHEADER_MODES := modes.h
+$ EXHEADER_BN := bn.h
+$ EXHEADER_EC := ec.h
+$ EXHEADER_RSA := rsa.h
+$ EXHEADER_DSA := dsa.h
+$ EXHEADER_ECDSA := ecdsa.h
+$ EXHEADER_DH := dh.h
+$ EXHEADER_ECDH := ecdh.h
+$ EXHEADER_DSO := dso.h
+$ EXHEADER_ENGINE := engine.h
+$ EXHEADER_BUFFER := buffer.h
+$ EXHEADER_BIO := bio.h
+$ EXHEADER_STACK := stack.h,safestack.h
+$ EXHEADER_LHASH := lhash.h
+$ EXHEADER_RAND := rand.h
+$ EXHEADER_ERR := err.h
+$ EXHEADER_EVP := evp.h
+$ EXHEADER_ASN1 := asn1.h,asn1_mac.h,asn1t.h
+$ EXHEADER_PEM := pem.h,pem2.h
+$ EXHEADER_X509 := x509.h,x509_vfy.h
+$ EXHEADER_X509V3 := x509v3.h
+$ EXHEADER_CONF := conf.h,conf_api.h
+$ EXHEADER_TXT_DB := txt_db.h
+$ EXHEADER_PKCS7 := pkcs7.h
+$ EXHEADER_PKCS12 := pkcs12.h
+$ EXHEADER_COMP := comp.h
+$ EXHEADER_OCSP := ocsp.h
+$ EXHEADER_UI := ui.h,ui_compat.h
+$ EXHEADER_KRB5 := krb5_asn.h
+$!EXHEADER_STORE := store.h,str_compat.h
+$ EXHEADER_STORE := store.h
+$ EXHEADER_CMS := cms.h
+$ EXHEADER_PQUEUE := pqueue.h
+$ EXHEADER_TS := ts.h
+$ EXHEADER_JPAKE := jpake.h
+$
+$ I = 0
+$ LOOP_SDIRS:
+$ D = F$EDIT(F$ELEMENT(I, ",", SDIRS),"TRIM")
+$ I = I + 1
+$ IF D .EQS. "," THEN GOTO LOOP_SDIRS_END
+$ tmp = EXHEADER_'D'
+$ IF D .EQS. ""
+$ THEN
+$ COPY [.CRYPTO]'tmp' SYS$DISK:[.INCLUDE.OPENSSL] !/LOG
+$ ELSE
+$ COPY [.CRYPTO.'D']'tmp' SYS$DISK:[.INCLUDE.OPENSSL] !/LOG
+$ ENDIF
+$ GOTO LOOP_SDIRS
+$ LOOP_SDIRS_END:
+$!
+$! Copy All The ".H" Files From The [.SSL] Directory.
+$!
+$ EXHEADER := ssl.h,ssl2.h,ssl3.h,ssl23.h,tls1.h,dtls1.h,kssl.h
+$ COPY SYS$DISK:[.SSL]'EXHEADER' SYS$DISK:[.INCLUDE.OPENSSL]
+$!
+$! Purge all doubles
+$!
+$ PURGE SYS$DISK:[.INCLUDE.OPENSSL]*.H
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Build The "[.xxx.EXE.CRYPTO]LIBCRYPTO''LIB32'.OLB" Library.
+$!
+$ CRYPTO:
+$!
+$! Tell The User What We Are Doing.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Building The [.",ARCH,".EXE.CRYPTO]LIBCRYPTO''LIB32'.OLB Library."
+$!
+$! Go To The [.CRYPTO] Directory.
+$!
+$ SET DEFAULT SYS$DISK:[.CRYPTO]
+$!
+$! Build The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
+$!
+$ @CRYPTO-LIB LIBRARY 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'"
+$!
+$! Build The [.xxx.EXE.CRYPTO]*.EXE Test Applications.
+$!
+$ @CRYPTO-LIB APPS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'"
+$!
+$! Go Back To The Main Directory.
+$!
+$ SET DEFAULT [-]
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Build The "[.xxx.EXE.SSL]LIBSSL''LIB32'.OLB" Library.
+$!
+$ SSL:
+$!
+$! Tell The User What We Are Doing.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Building The [.",ARCH,".EXE.SSL]LIBSSL''LIB32'.OLB Library."
+$!
+$! Go To The [.SSL] Directory.
+$!
+$ SET DEFAULT SYS$DISK:[.SSL]
+$!
+$! Build The [.xxx.EXE.SSL]LIBSSL.OLB Library.
+$!
+$ @SSL-LIB LIBRARY 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "''POINTER_SIZE'"
+$!
+$! Go Back To The Main Directory.
+$!
+$ SET DEFAULT [-]
+$!
+$! Time To Return.
+$!
+$ RETURN
+$!
+$! Build The "[.xxx.EXE.SSL]SSL_TASK.EXE" Program.
+$!
+$ SSL_TASK:
+$!
+$! Tell The User What We Are Doing.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Building DECNet Based SSL Engine, [.",ARCH,".EXE.SSL]SSL_TASK.EXE"
+$!
+$! Go To The [.SSL] Directory.
+$!
+$ SET DEFAULT SYS$DISK:[.SSL]
+$!
+$! Build The [.xxx.EXE.SSL]SSL_TASK.EXE
+$!
+$ @SSL-LIB SSL_TASK 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "''POINTER_SIZE'"
+$!
+$! Go Back To The Main Directory.
+$!
+$ SET DEFAULT [-]
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Build The OpenSSL Test Programs.
+$!
+$ TEST:
+$!
+$! Tell The User What We Are Doing.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Building The OpenSSL [.",ARCH,".EXE.TEST] Test Utilities."
+$!
+$! Go To The [.TEST] Directory.
+$!
+$ SET DEFAULT SYS$DISK:[.TEST]
+$!
+$! Build The Test Programs.
+$!
+$ @MAKETESTS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "''POINTER_SIZE'"
+$!
+$! Go Back To The Main Directory.
+$!
+$ SET DEFAULT [-]
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Build The OpenSSL Application Programs.
+$!
+$ APPS:
+$!
+$! Tell The User What We Are Doing.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Building OpenSSL [.",ARCH,".EXE.APPS] Applications."
+$!
+$! Go To The [.APPS] Directory.
+$!
+$ SET DEFAULT SYS$DISK:[.APPS]
+$!
+$! Build The Application Programs.
+$!
+$ @MAKEAPPS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "" "''POINTER_SIZE'"
+$!
+$! Go Back To The Main Directory.
+$!
+$ SET DEFAULT [-]
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Build The OpenSSL Application Programs.
+$!
+$ ENGINES:
+$!
+$! Tell The User What We Are Doing.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Building OpenSSL [.",ARCH,".EXE.ENGINES] Engines."
+$!
+$! Go To The [.ENGINES] Directory.
+$!
+$ SET DEFAULT SYS$DISK:[.ENGINES]
+$!
+$! Build The Application Programs.
+$!
+$ @MAKEENGINES ENGINES 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" "''ISSEVEN'" "''BUILDPART'" "''POINTER_SIZE'"
+$!
+$! Go Back To The Main Directory.
+$!
+$ SET DEFAULT [-]
+$!
+$! That's All, Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check if there's a "part", and separate it out
+$!
+$ BUILDPART = F$ELEMENT(1,"/",P1)
+$ IF BUILDPART .EQS. "/"
+$ THEN
+$ BUILDPART = ""
+$ ELSE
+$ P1 = F$EXTRACT(0,F$LENGTH(P1) - F$LENGTH(BUILDPART) - 1, P1)
+$ ENDIF
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."ALL")
+$ THEN
+$!
+$! P1 Is ALL, So Build Everything.
+$!
+$ BUILDCOMMAND = "ALL"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Else, Check To See If P1 Has A Valid Argument.
+$!
+$ IF (P1.EQS."CONFIG").OR.(P1.EQS."BUILDINF").OR.(P1.EQS."SOFTLINKS") -
+ .OR.(P1.EQS."BUILDALL") -
+ .OR.(P1.EQS."CRYPTO").OR.(P1.EQS."SSL") -
+ .OR.(P1.EQS."SSL_TASK").OR.(P1.EQS."TEST").OR.(P1.EQS."APPS") -
+ .OR.(P1.EQS."ENGINES")
+$ THEN
+$!
+$! A Valid Argument.
+$!
+$ BUILDCOMMAND = P1
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "USAGE: @MAKEVMS.COM [Target] [Pointer size] [Debug option] <Compiler>"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Example: @MAKEVMS.COM ALL """" NODEBUG "
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Target ",P1," Is Invalid. The Valid Target Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " ALL : Just Build Everything."
+$ WRITE SYS$OUTPUT " CONFIG : Just build the [.CRYPTO._xxx]OPENSSLCONF.H file."
+$ WRITE SYS$OUTPUT " BUILDINF : Just build the [.CRYPTO._xxx]BUILDINF.H file."
+$ WRITE SYS$OUTPUT " SOFTLINKS: Just Fix The Unix soft links."
+$ WRITE SYS$OUTPUT " BUILDALL : Same as ALL, except CONFIG, BUILDINF and SOFTILNKS aren't done."
+$ WRITE SYS$OUTPUT " CRYPTO : To Build Just The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
+$ WRITE SYS$OUTPUT " CRYPTO/x : To Build Just The x Part Of The"
+$ WRITE SYS$OUTPUT " [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
+$ WRITE SYS$OUTPUT " SSL : To Build Just The [.xxx.EXE.SSL]LIBSSL.OLB Library."
+$ WRITE SYS$OUTPUT " SSL_TASK : To Build Just The [.xxx.EXE.SSL]SSL_TASK.EXE Program."
+$ WRITE SYS$OUTPUT " TEST : To Build Just The OpenSSL Test Programs."
+$ WRITE SYS$OUTPUT " APPS : To Build Just The OpenSSL Application Programs."
+$ WRITE SYS$OUTPUT " ENGINES : To Build Just The ENGINES"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " ALPHA : Alpha Architecture."
+$ WRITE SYS$OUTPUT " IA64 : IA64 Architecture."
+$ WRITE SYS$OUTPUT " VAX : VAX Architecture."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ GOTO TIDY
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P2 Is Blank.
+$!
+$ IF (P2.EQS."")
+$ THEN
+$ POINTER_SIZE = ""
+$ ELSE
+$!
+$! Check is P2 Is Valid
+$!
+$ IF (P2.EQS."32")
+$ THEN
+$ POINTER_SIZE = "32"
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ LIB32 = ""
+$ ELSE
+$ LIB32 = "32"
+$ ENDIF
+$ ELSE
+$ IF (P2.EQS."64")
+$ THEN
+$ LIB32 = ""
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ POINTER_SIZE = "32"
+$ ELSE
+$ POINTER_SIZE = "64"
+$ ENDIF
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " 32 : Compile with 32 bit pointer size"
+$ WRITE SYS$OUTPUT " 64 : Compile with 64 bit pointer size"
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ GOTO TIDY
+$!
+$! End The Valid Arguement Check.
+$!
+$ ENDIF
+$ ENDIF
+$!
+$! End The P2 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P3 Is Blank.
+$!
+$ IF (P3.EQS."NODEBUG")
+$ THEN
+$!
+$! P3 Is NODEBUG, So Compile Without Debugger Information.
+$!
+$ DEBUGGER = "NODEBUG"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Check To See If We Are To Compile With Debugger Information.
+$!
+$ IF (P3.EQS."DEBUG")
+$ THEN
+$!
+$! Compile With Debugger Information.
+$!
+$ DEBUGGER = "DEBUG"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
+$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ GOTO TIDY
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! End The P3 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P4 Is Blank.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$! O.K., The User Didn't Specify A Compiler, Let's Try To
+$! Find Out Which One To Use.
+$!
+$! Check To See If We Have GNU C.
+$!
+$ IF (F$TRNLNM("GNU_CC").NES."")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ COMPILER = "GNUC"
+$!
+$! Tell The User We Are Using GNUC.
+$!
+$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$! End The GNU C Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have VAXC Or DECC.
+$!
+$ IF (F$GETSYI("CPU").GE.128).OR.(F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ COMPILER = "DECC"
+$!
+$! Tell The User We Are Using DECC.
+$!
+$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ COMPILER = "VAXC"
+$!
+$! Tell The User We Are Using VAX C.
+$!
+$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$! End The DECC & VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Check To See If The User Entered A Valid Paramter.
+$!
+$ IF (P4.EQS."VAXC").OR.(P4.EQS."DECC").OR.(P4.EQS."GNUC")!.OR.(P4.EQS."LINK")
+$ THEN
+$!
+$! Check To See If The User Wanted To Just LINK.
+$!
+$ IF (P4.EQS."LINK")
+$ THEN
+$!
+$! Looks Like LINK-only
+$!
+$ COMPILER = "LINK"
+$!
+$! Tell The User We Are Only Linking.
+$!
+$ WRITE SYS$OUTPUT "LINK Only. This actually NOT YET SUPPORTED!"
+$!
+$! End LINK Check.
+$!
+$ ENDIF
+$!
+$! Check To See If The User Wanted DECC.
+$!
+$ IF (P4.EQS."DECC")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ COMPILER = "DECC"
+$!
+$! Tell The User We Are Using DECC.
+$!
+$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$! End DECC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use VAXC.
+$!
+$ IF (P4.EQS."VAXC")
+$ THEN
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ COMPILER = "VAXC"
+$!
+$! Tell The User We Are Using VAX C.
+$!
+$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$! End VAXC Check
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use GNU C.
+$!
+$ IF (P4.EQS."GNUC")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ COMPILER = "GNUC"
+$!
+$! Tell The User We Are Using GNUC.
+$!
+$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P4," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
+$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
+$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ GOTO TIDY
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! End The P4 Check.
+$!
+$ ENDIF
+$!
+$! Time to check the contents of P5, and to make sure we get the correct library.
+$!
+$ IF P5.EQS."SOCKETSHR" .OR. P5.EQS."MULTINET" .OR. P5.EQS."UCX" -
+ .OR. P5.EQS."TCPIP" .OR. P5.EQS."NONE"
+$ THEN
+$!
+$! Check to see if SOCKETSHR was chosen
+$!
+$ IF P5.EQS."SOCKETSHR"
+$ THEN
+$!
+$! Set the library to use SOCKETSHR
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$! Done with SOCKETSHR
+$!
+$ ENDIF
+$!
+$! Check to see if MULTINET was chosen
+$!
+$ IF P5.EQS."MULTINET"
+$ THEN
+$!
+$! Set the library to use UCX emulation.
+$!
+$ P5 = "UCX"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using MultiNet via UCX emulation for TCP/IP"
+$!
+$! Done with MULTINET
+$!
+$ ENDIF
+$!
+$! Check to see if UCX was chosen
+$!
+$ IF P5.EQS."UCX"
+$ THEN
+$!
+$! Set the library to use UCX.
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$! Done with UCX
+$!
+$ ENDIF
+$!
+$! Check to see if TCPIP was chosen
+$!
+$ IF P5.EQS."TCPIP"
+$ THEN
+$!
+$! Set the library to use TCPIP (post UCX).
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using TCPIP (post UCX) for TCP/IP"
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Check to see if NONE was chosen
+$!
+$ IF P5.EQS."NONE"
+$ THEN
+$!
+$! Do not use a TCPIP library.
+$!
+$ TCPIP_LIB = ""
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "A specific TCPIP library will not be used."
+$!
+$! Done with NONE.
+$!
+$ ENDIF
+$!
+$! Set the TCPIP_TYPE symbol
+$!
+$ TCPIP_TYPE = P5
+$!
+$! Print info
+$!
+$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$ IF P5 .NES. ""
+$ THEN
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P5," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
+$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
+$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP TCP/IP (post UCX) library."
+$ WRITE SYS$OUTPUT " NONE : To not link with a specific TCP/IP library."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ GOTO TIDY
+$ ELSE
+$!
+$! If TCPIP is not defined, then hardcode it to make
+$! it clear that no TCPIP is desired.
+$!
+$ IF P5 .EQS. ""
+$ THEN
+$ TCPIP_LIB = ""
+$ TCPIP_TYPE = "NONE"
+$ ELSE
+$!
+$! Set the TCPIP_TYPE symbol
+$!
+$ TCPIP_TYPE = P5
+$ ENDIF
+$ ENDIF
+$!
+$! Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By: Richard Levitte
+$! richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P6.
+$!
+$ IF (P6.EQS."")
+$ THEN
+$!
+$! Get The Version Of VMS We Are Using.
+$!
+$ ISSEVEN :=
+$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,VMS_VERSION))
+$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$! Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$ IF (TMP.GE.71)
+$ THEN
+$!
+$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$ ISSEVEN := ,PTHREAD_USE_D4
+$!
+$! End The VMS Version Check.
+$!
+$ ENDIF
+$!
+$! End The P6 Check.
+$!
+$ ENDIF
+$!
+$! Time To RETURN...
+$!
+$ RETURN
+$!
+$ TIDY:
+$ SET DEFAULT 'DEF_ORIG'
+$ EXIT
+$!
diff --git a/openssl/openssl.spec b/openssl/openssl.spec
index 1fc73408f..bcfb32612 100644
--- a/openssl/openssl.spec
+++ b/openssl/openssl.spec
@@ -1,213 +1,213 @@
-%define _unpackaged_files_terminate_build 0
-%define libmaj 1
-%define libmin 0
-%define librel 0
-%define librev d
-Release: 1
-
-%define openssldir /var/ssl
-
-Summary: Secure Sockets Layer and cryptography libraries and tools
-Name: openssl
-#Version: %{libmaj}.%{libmin}.%{librel}
-Version: %{libmaj}.%{libmin}.%{librel}%{librev}
-Source0: ftp://ftp.openssl.org/source/%{name}-%{version}.tar.gz
-Copyright: Freely distributable
-Group: System Environment/Libraries
-Provides: SSL
-URL: http://www.openssl.org/
-Packager: Damien Miller <djm@mindrot.org>
-BuildRoot: /var/tmp/%{name}-%{version}-root
-
-%description
-The OpenSSL Project is a collaborative effort to develop a robust,
-commercial-grade, fully featured, and Open Source toolkit implementing the
-Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
-protocols as well as a full-strength general purpose cryptography library.
-The project is managed by a worldwide community of volunteers that use the
-Internet to communicate, plan, and develop the OpenSSL tookit and its related
-documentation.
-
-OpenSSL is based on the excellent SSLeay library developed from Eric A.
-Young and Tim J. Hudson. The OpenSSL toolkit is licensed under an
-Apache-style licence, which basically means that you are free to get and
-use it for commercial and non-commercial purposes.
-
-This package contains the base OpenSSL cryptography and SSL/TLS
-libraries and tools.
-
-%package devel
-Summary: Secure Sockets Layer and cryptography static libraries and headers
-Group: Development/Libraries
-Requires: openssl
-%description devel
-The OpenSSL Project is a collaborative effort to develop a robust,
-commercial-grade, fully featured, and Open Source toolkit implementing the
-Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
-protocols as well as a full-strength general purpose cryptography library.
-The project is managed by a worldwide community of volunteers that use the
-Internet to communicate, plan, and develop the OpenSSL tookit and its related
-documentation.
-
-OpenSSL is based on the excellent SSLeay library developed from Eric A.
-Young and Tim J. Hudson. The OpenSSL toolkit is licensed under an
-Apache-style licence, which basically means that you are free to get and
-use it for commercial and non-commercial purposes.
-
-This package contains the the OpenSSL cryptography and SSL/TLS
-static libraries and header files required when developing applications.
-
-%package doc
-Summary: OpenSSL miscellaneous files
-Group: Documentation
-Requires: openssl
-%description doc
-The OpenSSL Project is a collaborative effort to develop a robust,
-commercial-grade, fully featured, and Open Source toolkit implementing the
-Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
-protocols as well as a full-strength general purpose cryptography library.
-The project is managed by a worldwide community of volunteers that use the
-Internet to communicate, plan, and develop the OpenSSL tookit and its related
-documentation.
-
-OpenSSL is based on the excellent SSLeay library developed from Eric A.
-Young and Tim J. Hudson. The OpenSSL toolkit is licensed under an
-Apache-style licence, which basically means that you are free to get and
-use it for commercial and non-commercial purposes.
-
-This package contains the the OpenSSL cryptography and SSL/TLS extra
-documentation and POD files from which the man pages were produced.
-
-%prep
-
-%setup -q
-
-%build
-
-%define CONFIG_FLAGS -DSSL_ALLOW_ADH --prefix=/usr --openssldir=%{openssldir}
-
-perl util/perlpath.pl /usr/bin/perl
-
-%ifarch i386 i486 i586 i686
-./Configure %{CONFIG_FLAGS} linux-elf shared
-%endif
-%ifarch ppc
-./Configure %{CONFIG_FLAGS} linux-ppc shared
-%endif
-%ifarch alpha
-./Configure %{CONFIG_FLAGS} linux-alpha shared
-%endif
-%ifarch x86_64
-./Configure %{CONFIG_FLAGS} linux-x86_64 shared
-%endif
-LD_LIBRARY_PATH=`pwd` make
-LD_LIBRARY_PATH=`pwd` make rehash
-LD_LIBRARY_PATH=`pwd` make test
-
-%install
-rm -rf $RPM_BUILD_ROOT
-make MANDIR=/usr/man MANSUFFIX=ssl INSTALL_PREFIX="$RPM_BUILD_ROOT" install
-
-# Make backwards-compatibility symlink to ssleay
-ln -sf /usr/bin/openssl $RPM_BUILD_ROOT/usr/bin/ssleay
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(0644,root,root,0755)
-%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
-
-%attr(0755,root,root) /usr/bin/*
-%attr(0755,root,root) /usr/lib/*.so*
-%attr(0755,root,root) %{openssldir}/misc/*
-%attr(0644,root,root) /usr/man/man[157]/*
-
-%config %attr(0644,root,root) %{openssldir}/openssl.cnf
-%dir %attr(0755,root,root) %{openssldir}/certs
-%dir %attr(0755,root,root) %{openssldir}/misc
-%dir %attr(0750,root,root) %{openssldir}/private
-
-%files devel
-%defattr(0644,root,root,0755)
-%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
-
-%attr(0644,root,root) /usr/lib/*.a
-%attr(0644,root,root) /usr/lib/pkgconfig/openssl.pc
-%attr(0644,root,root) /usr/include/openssl/*
-%attr(0644,root,root) /usr/man/man[3]/*
-
-%files doc
-%defattr(0644,root,root,0755)
-%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
-%doc doc
-
-%post
-ldconfig
-
-%postun
-ldconfig
-
-%changelog
-* Sun Jun 6 2005 Richard Levitte <richard@levitte.org>
-- Remove the incorrect installation of '%{openssldir}/lib'.
-* Wed May 7 2003 Richard Levitte <richard@levitte.org>
-- Add /usr/lib/pkgconfig/openssl.pc to the development section.
-* Thu Mar 22 2001 Richard Levitte <richard@levitte.org>
-- Removed redundant subsection that re-installed libcrypto.a and libssl.a
- as well. Also remove RSAref stuff completely, since it's not needed
- any more.
-* Thu Mar 15 2001 Jeremiah Johnson <jjohnson@penguincomputing.com>
-- Removed redundant subsection that re-installed libcrypto.so.0.9.6 and
- libssl.so.0.9.6. As well as the subsection that created symlinks for
- these. make install handles all this.
-* Sat Oct 21 2000 Horms <horms@vergenet.net>
-- Make sure symlinks are created by using -f flag to ln.
- Otherwise some .so libraries are copied rather than
- linked in the resulting binary RPM. This causes the package
- to be larger than neccessary and makes ldconfig complain.
-* Fri Oct 13 2000 Horms <horms@vergenet.net>
-- Make defattr is set for files in all packages so packages built as
- non-root will still be installed with files owned by root.
-* Thu Sep 14 2000 Richard Levitte <richard@levitte.org>
-- Changed to adapt to the new (supported) way of making shared libraries
-- Installs all static libraries, not just libRSAglue.a
-- Extra documents now end up in a separate document package
-* Sun Feb 27 2000 Damien Miller <djm@mindrot.org>
-- Merged patches to spec
-- Updated to 0.9.5beta2 (now with manpages)
-* Sat Feb 5 2000 Michal Jaegermann <michal@harddata.com>
-- added 'linux-alpha' to configuration
-- fixed nasty absolute links
-* Tue Jan 25 2000 Bennett Todd <bet@rahul.net>
-- Added -DSSL_ALLOW_ADH, bumped Release to 4
-* Thu Oct 14 1999 Damien Miller <djm@mindrot.org>
-- Set default permissions
-- Removed documentation from devel sub-package
-* Thu Sep 30 1999 Damien Miller <djm@mindrot.org>
-- Added "make test" stage
-- GPG signed
-* Tue Sep 10 1999 Damien Miller <damien@ibs.com.au>
-- Updated to version 0.9.4
-* Tue May 25 1999 Damien Miller <damien@ibs.com.au>
-- Updated to version 0.9.3
-- Added attributes for all files
-- Paramatised openssl directory
-* Sat Mar 20 1999 Carlo M. Arenas Belon <carenas@jmconsultores.com.pe>
-- Added "official" bnrec patch and taking other out
-- making a link from ssleay to openssl binary
-- putting all changelog together on SPEC file
-* Fri Mar 5 1999 Henri Gomez <gomez@slib.fr>
-- Added bnrec patch
-* Tue Dec 29 1998 Jonathan Ruano <kobalt@james.encomix.es>
-- minimum spec and patches changes for openssl
-- modified for openssl sources
-* Sat Aug 8 1998 Khimenko Victor <khim@sch57.msk.ru>
-- shared library creating process honours $RPM_OPT_FLAGS
-- shared libarry supports threads (as well as static library)
-* Wed Jul 22 1998 Khimenko Victor <khim@sch57.msk.ru>
-- building of shared library completely reworked
-* Tue Jul 21 1998 Khimenko Victor <khim@sch57.msk.ru>
-- RPM is BuildRoot'ed
-* Tue Feb 10 1998 Khimenko Victor <khim@sch57.msk.ru>
-- all stuff is moved out of /usr/local
+%define _unpackaged_files_terminate_build 0
+%define libmaj 1
+%define libmin 0
+%define librel 0
+%define librev d
+Release: 1
+
+%define openssldir /var/ssl
+
+Summary: Secure Sockets Layer and cryptography libraries and tools
+Name: openssl
+#Version: %{libmaj}.%{libmin}.%{librel}
+Version: %{libmaj}.%{libmin}.%{librel}%{librev}
+Source0: ftp://ftp.openssl.org/source/%{name}-%{version}.tar.gz
+Copyright: Freely distributable
+Group: System Environment/Libraries
+Provides: SSL
+URL: http://www.openssl.org/
+Packager: Damien Miller <djm@mindrot.org>
+BuildRoot: /var/tmp/%{name}-%{version}-root
+
+%description
+The OpenSSL Project is a collaborative effort to develop a robust,
+commercial-grade, fully featured, and Open Source toolkit implementing the
+Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
+protocols as well as a full-strength general purpose cryptography library.
+The project is managed by a worldwide community of volunteers that use the
+Internet to communicate, plan, and develop the OpenSSL tookit and its related
+documentation.
+
+OpenSSL is based on the excellent SSLeay library developed from Eric A.
+Young and Tim J. Hudson. The OpenSSL toolkit is licensed under an
+Apache-style licence, which basically means that you are free to get and
+use it for commercial and non-commercial purposes.
+
+This package contains the base OpenSSL cryptography and SSL/TLS
+libraries and tools.
+
+%package devel
+Summary: Secure Sockets Layer and cryptography static libraries and headers
+Group: Development/Libraries
+Requires: openssl
+%description devel
+The OpenSSL Project is a collaborative effort to develop a robust,
+commercial-grade, fully featured, and Open Source toolkit implementing the
+Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
+protocols as well as a full-strength general purpose cryptography library.
+The project is managed by a worldwide community of volunteers that use the
+Internet to communicate, plan, and develop the OpenSSL tookit and its related
+documentation.
+
+OpenSSL is based on the excellent SSLeay library developed from Eric A.
+Young and Tim J. Hudson. The OpenSSL toolkit is licensed under an
+Apache-style licence, which basically means that you are free to get and
+use it for commercial and non-commercial purposes.
+
+This package contains the the OpenSSL cryptography and SSL/TLS
+static libraries and header files required when developing applications.
+
+%package doc
+Summary: OpenSSL miscellaneous files
+Group: Documentation
+Requires: openssl
+%description doc
+The OpenSSL Project is a collaborative effort to develop a robust,
+commercial-grade, fully featured, and Open Source toolkit implementing the
+Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
+protocols as well as a full-strength general purpose cryptography library.
+The project is managed by a worldwide community of volunteers that use the
+Internet to communicate, plan, and develop the OpenSSL tookit and its related
+documentation.
+
+OpenSSL is based on the excellent SSLeay library developed from Eric A.
+Young and Tim J. Hudson. The OpenSSL toolkit is licensed under an
+Apache-style licence, which basically means that you are free to get and
+use it for commercial and non-commercial purposes.
+
+This package contains the the OpenSSL cryptography and SSL/TLS extra
+documentation and POD files from which the man pages were produced.
+
+%prep
+
+%setup -q
+
+%build
+
+%define CONFIG_FLAGS -DSSL_ALLOW_ADH --prefix=/usr --openssldir=%{openssldir}
+
+perl util/perlpath.pl /usr/bin/perl
+
+%ifarch i386 i486 i586 i686
+./Configure %{CONFIG_FLAGS} linux-elf shared
+%endif
+%ifarch ppc
+./Configure %{CONFIG_FLAGS} linux-ppc shared
+%endif
+%ifarch alpha
+./Configure %{CONFIG_FLAGS} linux-alpha shared
+%endif
+%ifarch x86_64
+./Configure %{CONFIG_FLAGS} linux-x86_64 shared
+%endif
+LD_LIBRARY_PATH=`pwd` make
+LD_LIBRARY_PATH=`pwd` make rehash
+LD_LIBRARY_PATH=`pwd` make test
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make MANDIR=/usr/man MANSUFFIX=ssl INSTALL_PREFIX="$RPM_BUILD_ROOT" install
+
+# Make backwards-compatibility symlink to ssleay
+ln -sf /usr/bin/openssl $RPM_BUILD_ROOT/usr/bin/ssleay
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(0644,root,root,0755)
+%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
+
+%attr(0755,root,root) /usr/bin/*
+%attr(0755,root,root) /usr/lib/*.so*
+%attr(0755,root,root) %{openssldir}/misc/*
+%attr(0644,root,root) /usr/man/man[157]/*
+
+%config %attr(0644,root,root) %{openssldir}/openssl.cnf
+%dir %attr(0755,root,root) %{openssldir}/certs
+%dir %attr(0755,root,root) %{openssldir}/misc
+%dir %attr(0750,root,root) %{openssldir}/private
+
+%files devel
+%defattr(0644,root,root,0755)
+%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
+
+%attr(0644,root,root) /usr/lib/*.a
+%attr(0644,root,root) /usr/lib/pkgconfig/openssl.pc
+%attr(0644,root,root) /usr/include/openssl/*
+%attr(0644,root,root) /usr/man/man[3]/*
+
+%files doc
+%defattr(0644,root,root,0755)
+%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
+%doc doc
+
+%post
+ldconfig
+
+%postun
+ldconfig
+
+%changelog
+* Sun Jun 6 2005 Richard Levitte <richard@levitte.org>
+- Remove the incorrect installation of '%{openssldir}/lib'.
+* Wed May 7 2003 Richard Levitte <richard@levitte.org>
+- Add /usr/lib/pkgconfig/openssl.pc to the development section.
+* Thu Mar 22 2001 Richard Levitte <richard@levitte.org>
+- Removed redundant subsection that re-installed libcrypto.a and libssl.a
+ as well. Also remove RSAref stuff completely, since it's not needed
+ any more.
+* Thu Mar 15 2001 Jeremiah Johnson <jjohnson@penguincomputing.com>
+- Removed redundant subsection that re-installed libcrypto.so.0.9.6 and
+ libssl.so.0.9.6. As well as the subsection that created symlinks for
+ these. make install handles all this.
+* Sat Oct 21 2000 Horms <horms@vergenet.net>
+- Make sure symlinks are created by using -f flag to ln.
+ Otherwise some .so libraries are copied rather than
+ linked in the resulting binary RPM. This causes the package
+ to be larger than neccessary and makes ldconfig complain.
+* Fri Oct 13 2000 Horms <horms@vergenet.net>
+- Make defattr is set for files in all packages so packages built as
+ non-root will still be installed with files owned by root.
+* Thu Sep 14 2000 Richard Levitte <richard@levitte.org>
+- Changed to adapt to the new (supported) way of making shared libraries
+- Installs all static libraries, not just libRSAglue.a
+- Extra documents now end up in a separate document package
+* Sun Feb 27 2000 Damien Miller <djm@mindrot.org>
+- Merged patches to spec
+- Updated to 0.9.5beta2 (now with manpages)
+* Sat Feb 5 2000 Michal Jaegermann <michal@harddata.com>
+- added 'linux-alpha' to configuration
+- fixed nasty absolute links
+* Tue Jan 25 2000 Bennett Todd <bet@rahul.net>
+- Added -DSSL_ALLOW_ADH, bumped Release to 4
+* Thu Oct 14 1999 Damien Miller <djm@mindrot.org>
+- Set default permissions
+- Removed documentation from devel sub-package
+* Thu Sep 30 1999 Damien Miller <djm@mindrot.org>
+- Added "make test" stage
+- GPG signed
+* Tue Sep 10 1999 Damien Miller <damien@ibs.com.au>
+- Updated to version 0.9.4
+* Tue May 25 1999 Damien Miller <damien@ibs.com.au>
+- Updated to version 0.9.3
+- Added attributes for all files
+- Paramatised openssl directory
+* Sat Mar 20 1999 Carlo M. Arenas Belon <carenas@jmconsultores.com.pe>
+- Added "official" bnrec patch and taking other out
+- making a link from ssleay to openssl binary
+- putting all changelog together on SPEC file
+* Fri Mar 5 1999 Henri Gomez <gomez@slib.fr>
+- Added bnrec patch
+* Tue Dec 29 1998 Jonathan Ruano <kobalt@james.encomix.es>
+- minimum spec and patches changes for openssl
+- modified for openssl sources
+* Sat Aug 8 1998 Khimenko Victor <khim@sch57.msk.ru>
+- shared library creating process honours $RPM_OPT_FLAGS
+- shared libarry supports threads (as well as static library)
+* Wed Jul 22 1998 Khimenko Victor <khim@sch57.msk.ru>
+- building of shared library completely reworked
+* Tue Jul 21 1998 Khimenko Victor <khim@sch57.msk.ru>
+- RPM is BuildRoot'ed
+* Tue Feb 10 1998 Khimenko Victor <khim@sch57.msk.ru>
+- all stuff is moved out of /usr/local
diff --git a/openssl/ssl/d1_enc.c b/openssl/ssl/d1_enc.c
index d762dc5c5..becbab91c 100644
--- a/openssl/ssl/d1_enc.c
+++ b/openssl/ssl/d1_enc.c
@@ -1,289 +1,289 @@
-/* ssl/d1_enc.c */
-/*
- * DTLS implementation written by Nagendra Modadugu
- * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
- */
-/* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include "ssl_locl.h"
-#ifndef OPENSSL_NO_COMP
-#include <openssl/comp.h>
-#endif
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/md5.h>
-#include <openssl/rand.h>
-#ifdef KSSL_DEBUG
-#include <openssl/des.h>
-#endif
-
-int dtls1_enc(SSL *s, int send)
- {
- SSL3_RECORD *rec;
- EVP_CIPHER_CTX *ds;
- unsigned long l;
- int bs,i,ii,j,k,n=0;
- const EVP_CIPHER *enc;
-
- if (send)
- {
- if (EVP_MD_CTX_md(s->write_hash))
- {
- n=EVP_MD_CTX_size(s->write_hash);
- if (n < 0)
- return -1;
- }
- ds=s->enc_write_ctx;
- rec= &(s->s3->wrec);
- if (s->enc_write_ctx == NULL)
- enc=NULL;
- else
- {
- enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
- if ( rec->data != rec->input)
- /* we can't write into the input stream */
- fprintf(stderr, "%s:%d: rec->data != rec->input\n",
- __FILE__, __LINE__);
- else if ( EVP_CIPHER_block_size(ds->cipher) > 1)
- {
- if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)) <= 0)
- return -1;
- }
- }
- }
- else
- {
- if (EVP_MD_CTX_md(s->read_hash))
- {
- n=EVP_MD_CTX_size(s->read_hash);
- if (n < 0)
- return -1;
- }
- ds=s->enc_read_ctx;
- rec= &(s->s3->rrec);
- if (s->enc_read_ctx == NULL)
- enc=NULL;
- else
- enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
- }
-
-#ifdef KSSL_DEBUG
- printf("dtls1_enc(%d)\n", send);
-#endif /* KSSL_DEBUG */
-
- if ((s->session == NULL) || (ds == NULL) ||
- (enc == NULL))
- {
- memmove(rec->data,rec->input,rec->length);
- rec->input=rec->data;
- }
- else
- {
- l=rec->length;
- bs=EVP_CIPHER_block_size(ds->cipher);
-
- if ((bs != 1) && send)
- {
- i=bs-((int)l%bs);
-
- /* Add weird padding of upto 256 bytes */
-
- /* we need to add 'i' padding bytes of value j */
- j=i-1;
- if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
- {
- if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
- j++;
- }
- for (k=(int)l; k<(int)(l+i); k++)
- rec->input[k]=j;
- l+=i;
- rec->length+=i;
- }
-
-#ifdef KSSL_DEBUG
- {
- unsigned long ui;
- printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
- ds,rec->data,rec->input,l);
- printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
- ds->buf_len, ds->cipher->key_len,
- DES_KEY_SZ, DES_SCHEDULE_SZ,
- ds->cipher->iv_len);
- printf("\t\tIV: ");
- for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
- printf("\n");
- printf("\trec->input=");
- for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
- printf("\n");
- }
-#endif /* KSSL_DEBUG */
-
- if (!send)
- {
- if (l == 0 || l%bs != 0)
- return -1;
- }
-
- EVP_Cipher(ds,rec->data,rec->input,l);
-
-#ifdef KSSL_DEBUG
- {
- unsigned long i;
- printf("\trec->data=");
- for (i=0; i<l; i++)
- printf(" %02x", rec->data[i]); printf("\n");
- }
-#endif /* KSSL_DEBUG */
-
- if ((bs != 1) && !send)
- {
- ii=i=rec->data[l-1]; /* padding_length */
- i++;
- if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
- {
- /* First packet is even in size, so check */
- if ((memcmp(s->s3->read_sequence,
- "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
- s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
- if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
- i--;
- }
- /* TLS 1.0 does not bound the number of padding bytes by the block size.
- * All of them must have value 'padding_length'. */
- if (i > (int)rec->length)
- {
- /* Incorrect padding. SSLerr() and ssl3_alert are done
- * by caller: we don't want to reveal whether this is
- * a decryption error or a MAC verification failure
- * (see http://www.openssl.org/~bodo/tls-cbc.txt)
- */
- return -1;
- }
- for (j=(int)(l-i); j<(int)l; j++)
- {
- if (rec->data[j] != ii)
- {
- /* Incorrect padding */
- return -1;
- }
- }
- rec->length-=i;
-
- rec->data += bs; /* skip the implicit IV */
- rec->input += bs;
- rec->length -= bs;
- }
- }
- return(1);
- }
-
+/* ssl/d1_enc.c */
+/*
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_COMP
+#include <openssl/comp.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/md5.h>
+#include <openssl/rand.h>
+#ifdef KSSL_DEBUG
+#include <openssl/des.h>
+#endif
+
+int dtls1_enc(SSL *s, int send)
+ {
+ SSL3_RECORD *rec;
+ EVP_CIPHER_CTX *ds;
+ unsigned long l;
+ int bs,i,ii,j,k,n=0;
+ const EVP_CIPHER *enc;
+
+ if (send)
+ {
+ if (EVP_MD_CTX_md(s->write_hash))
+ {
+ n=EVP_MD_CTX_size(s->write_hash);
+ if (n < 0)
+ return -1;
+ }
+ ds=s->enc_write_ctx;
+ rec= &(s->s3->wrec);
+ if (s->enc_write_ctx == NULL)
+ enc=NULL;
+ else
+ {
+ enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
+ if ( rec->data != rec->input)
+ /* we can't write into the input stream */
+ fprintf(stderr, "%s:%d: rec->data != rec->input\n",
+ __FILE__, __LINE__);
+ else if ( EVP_CIPHER_block_size(ds->cipher) > 1)
+ {
+ if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)) <= 0)
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ if (EVP_MD_CTX_md(s->read_hash))
+ {
+ n=EVP_MD_CTX_size(s->read_hash);
+ if (n < 0)
+ return -1;
+ }
+ ds=s->enc_read_ctx;
+ rec= &(s->s3->rrec);
+ if (s->enc_read_ctx == NULL)
+ enc=NULL;
+ else
+ enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
+ }
+
+#ifdef KSSL_DEBUG
+ printf("dtls1_enc(%d)\n", send);
+#endif /* KSSL_DEBUG */
+
+ if ((s->session == NULL) || (ds == NULL) ||
+ (enc == NULL))
+ {
+ memmove(rec->data,rec->input,rec->length);
+ rec->input=rec->data;
+ }
+ else
+ {
+ l=rec->length;
+ bs=EVP_CIPHER_block_size(ds->cipher);
+
+ if ((bs != 1) && send)
+ {
+ i=bs-((int)l%bs);
+
+ /* Add weird padding of upto 256 bytes */
+
+ /* we need to add 'i' padding bytes of value j */
+ j=i-1;
+ if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
+ {
+ if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
+ j++;
+ }
+ for (k=(int)l; k<(int)(l+i); k++)
+ rec->input[k]=j;
+ l+=i;
+ rec->length+=i;
+ }
+
+#ifdef KSSL_DEBUG
+ {
+ unsigned long ui;
+ printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
+ ds,rec->data,rec->input,l);
+ printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
+ ds->buf_len, ds->cipher->key_len,
+ DES_KEY_SZ, DES_SCHEDULE_SZ,
+ ds->cipher->iv_len);
+ printf("\t\tIV: ");
+ for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
+ printf("\n");
+ printf("\trec->input=");
+ for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
+ printf("\n");
+ }
+#endif /* KSSL_DEBUG */
+
+ if (!send)
+ {
+ if (l == 0 || l%bs != 0)
+ return -1;
+ }
+
+ EVP_Cipher(ds,rec->data,rec->input,l);
+
+#ifdef KSSL_DEBUG
+ {
+ unsigned long i;
+ printf("\trec->data=");
+ for (i=0; i<l; i++)
+ printf(" %02x", rec->data[i]); printf("\n");
+ }
+#endif /* KSSL_DEBUG */
+
+ if ((bs != 1) && !send)
+ {
+ ii=i=rec->data[l-1]; /* padding_length */
+ i++;
+ if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
+ {
+ /* First packet is even in size, so check */
+ if ((memcmp(s->s3->read_sequence,
+ "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
+ s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
+ if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
+ i--;
+ }
+ /* TLS 1.0 does not bound the number of padding bytes by the block size.
+ * All of them must have value 'padding_length'. */
+ if (i > (int)rec->length)
+ {
+ /* Incorrect padding. SSLerr() and ssl3_alert are done
+ * by caller: we don't want to reveal whether this is
+ * a decryption error or a MAC verification failure
+ * (see http://www.openssl.org/~bodo/tls-cbc.txt)
+ */
+ return -1;
+ }
+ for (j=(int)(l-i); j<(int)l; j++)
+ {
+ if (rec->data[j] != ii)
+ {
+ /* Incorrect padding */
+ return -1;
+ }
+ }
+ rec->length-=i;
+
+ rec->data += bs; /* skip the implicit IV */
+ rec->input += bs;
+ rec->length -= bs;
+ }
+ }
+ return(1);
+ }
+
diff --git a/openssl/ssl/d1_pkt.c b/openssl/ssl/d1_pkt.c
index 79b723a5e..c10514222 100644
--- a/openssl/ssl/d1_pkt.c
+++ b/openssl/ssl/d1_pkt.c
@@ -1,1769 +1,1769 @@
-/* ssl/d1_pkt.c */
-/*
- * DTLS implementation written by Nagendra Modadugu
- * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
- */
-/* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include <errno.h>
-#define USE_SOCKETS
-#include "ssl_locl.h"
-#include <openssl/evp.h>
-#include <openssl/buffer.h>
-#include <openssl/pqueue.h>
-#include <openssl/rand.h>
-
-/* mod 128 saturating subtract of two 64-bit values in big-endian order */
-static int satsub64be(const unsigned char *v1,const unsigned char *v2)
-{ int ret,sat,brw,i;
-
- if (sizeof(long) == 8) do
- { const union { long one; char little; } is_endian = {1};
- long l;
-
- if (is_endian.little) break;
- /* not reached on little-endians */
- /* following test is redundant, because input is
- * always aligned, but I take no chances... */
- if (((size_t)v1|(size_t)v2)&0x7) break;
-
- l = *((long *)v1);
- l -= *((long *)v2);
- if (l>128) return 128;
- else if (l<-128) return -128;
- else return (int)l;
- } while (0);
-
- ret = (int)v1[7]-(int)v2[7];
- sat = 0;
- brw = ret>>8; /* brw is either 0 or -1 */
- if (ret & 0x80)
- { for (i=6;i>=0;i--)
- { brw += (int)v1[i]-(int)v2[i];
- sat |= ~brw;
- brw >>= 8;
- }
- }
- else
- { for (i=6;i>=0;i--)
- { brw += (int)v1[i]-(int)v2[i];
- sat |= brw;
- brw >>= 8;
- }
- }
- brw <<= 8; /* brw is either 0 or -256 */
-
- if (sat&0xff) return brw | 0x80;
- else return brw + (ret&0xFF);
-}
-
-static int have_handshake_fragment(SSL *s, int type, unsigned char *buf,
- int len, int peek);
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
-static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
-static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
- unsigned int *is_next_epoch);
-#if 0
-static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
- unsigned short *priority, unsigned long *offset);
-#endif
-static int dtls1_buffer_record(SSL *s, record_pqueue *q,
- unsigned char *priority);
-static int dtls1_process_record(SSL *s);
-static void dtls1_clear_timeouts(SSL *s);
-
-/* copy buffered record into SSL structure */
-static int
-dtls1_copy_record(SSL *s, pitem *item)
- {
- DTLS1_RECORD_DATA *rdata;
-
- rdata = (DTLS1_RECORD_DATA *)item->data;
-
- if (s->s3->rbuf.buf != NULL)
- OPENSSL_free(s->s3->rbuf.buf);
-
- s->packet = rdata->packet;
- s->packet_length = rdata->packet_length;
- memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
- memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
-
- /* Set proper sequence number for mac calculation */
- memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6);
-
- return(1);
- }
-
-
-static int
-dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
- {
- DTLS1_RECORD_DATA *rdata;
- pitem *item;
-
- /* Limit the size of the queue to prevent DOS attacks */
- if (pqueue_size(queue->q) >= 100)
- return 0;
-
- rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
- item = pitem_new(priority, rdata);
- if (rdata == NULL || item == NULL)
- {
- if (rdata != NULL) OPENSSL_free(rdata);
- if (item != NULL) pitem_free(item);
-
- SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
- return(0);
- }
-
- rdata->packet = s->packet;
- rdata->packet_length = s->packet_length;
- memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER));
- memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD));
-
- item->data = rdata;
-
- /* insert should not fail, since duplicates are dropped */
- if (pqueue_insert(queue->q, item) == NULL)
- {
- OPENSSL_free(rdata);
- pitem_free(item);
- return(0);
- }
-
- s->packet = NULL;
- s->packet_length = 0;
- memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER));
- memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD));
-
- if (!ssl3_setup_buffers(s))
- {
- SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
- OPENSSL_free(rdata);
- pitem_free(item);
- return(0);
- }
-
- return(1);
- }
-
-
-static int
-dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
- {
- pitem *item;
-
- item = pqueue_pop(queue->q);
- if (item)
- {
- dtls1_copy_record(s, item);
-
- OPENSSL_free(item->data);
- pitem_free(item);
-
- return(1);
- }
-
- return(0);
- }
-
-
-/* retrieve a buffered record that belongs to the new epoch, i.e., not processed
- * yet */
-#define dtls1_get_unprocessed_record(s) \
- dtls1_retrieve_buffered_record((s), \
- &((s)->d1->unprocessed_rcds))
-
-/* retrieve a buffered record that belongs to the current epoch, ie, processed */
-#define dtls1_get_processed_record(s) \
- dtls1_retrieve_buffered_record((s), \
- &((s)->d1->processed_rcds))
-
-static int
-dtls1_process_buffered_records(SSL *s)
- {
- pitem *item;
-
- item = pqueue_peek(s->d1->unprocessed_rcds.q);
- if (item)
- {
- /* Check if epoch is current. */
- if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch)
- return(1); /* Nothing to do. */
-
- /* Process all the records. */
- while (pqueue_peek(s->d1->unprocessed_rcds.q))
- {
- dtls1_get_unprocessed_record(s);
- if ( ! dtls1_process_record(s))
- return(0);
- dtls1_buffer_record(s, &(s->d1->processed_rcds),
- s->s3->rrec.seq_num);
- }
- }
-
- /* sync epoch numbers once all the unprocessed records
- * have been processed */
- s->d1->processed_rcds.epoch = s->d1->r_epoch;
- s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1;
-
- return(1);
- }
-
-
-#if 0
-
-static int
-dtls1_get_buffered_record(SSL *s)
- {
- pitem *item;
- PQ_64BIT priority =
- (((PQ_64BIT)s->d1->handshake_read_seq) << 32) |
- ((PQ_64BIT)s->d1->r_msg_hdr.frag_off);
-
- if ( ! SSL_in_init(s)) /* if we're not (re)negotiating,
- nothing buffered */
- return 0;
-
-
- item = pqueue_peek(s->d1->rcvd_records);
- if (item && item->priority == priority)
- {
- /* Check if we've received the record of interest. It must be
- * a handshake record, since data records as passed up without
- * buffering */
- DTLS1_RECORD_DATA *rdata;
- item = pqueue_pop(s->d1->rcvd_records);
- rdata = (DTLS1_RECORD_DATA *)item->data;
-
- if (s->s3->rbuf.buf != NULL)
- OPENSSL_free(s->s3->rbuf.buf);
-
- s->packet = rdata->packet;
- s->packet_length = rdata->packet_length;
- memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
- memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
-
- OPENSSL_free(item->data);
- pitem_free(item);
-
- /* s->d1->next_expected_seq_num++; */
- return(1);
- }
-
- return 0;
- }
-
-#endif
-
-static int
-dtls1_process_record(SSL *s)
-{
- int i,al;
- int clear=0;
- int enc_err;
- SSL_SESSION *sess;
- SSL3_RECORD *rr;
- unsigned int mac_size;
- unsigned char md[EVP_MAX_MD_SIZE];
-
-
- rr= &(s->s3->rrec);
- sess = s->session;
-
- /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
- * and we have that many bytes in s->packet
- */
- rr->input= &(s->packet[DTLS1_RT_HEADER_LENGTH]);
-
- /* ok, we can now read from 's->packet' data into 'rr'
- * rr->input points at rr->length bytes, which
- * need to be copied into rr->data by either
- * the decryption or by the decompression
- * When the data is 'copied' into the rr->data buffer,
- * rr->input will be pointed at the new buffer */
-
- /* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
- * rr->length bytes of encrypted compressed stuff. */
-
- /* check is not needed I believe */
- if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
- {
- al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
- goto f_err;
- }
-
- /* decrypt in place in 'rr->input' */
- rr->data=rr->input;
-
- enc_err = s->method->ssl3_enc->enc(s,0);
- if (enc_err <= 0)
- {
- if (enc_err == 0)
- /* SSLerr() and ssl3_send_alert() have been called */
- goto err;
-
- /* otherwise enc_err == -1 */
- al=SSL_AD_BAD_RECORD_MAC;
- goto f_err;
- }
-
-#ifdef TLS_DEBUG
-printf("dec %d\n",rr->length);
-{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
-printf("\n");
-#endif
-
- /* r->length is now the compressed data plus mac */
- if ( (sess == NULL) ||
- (s->enc_read_ctx == NULL) ||
- (s->read_hash == NULL))
- clear=1;
-
- if (!clear)
- {
- /* !clear => s->read_hash != NULL => mac_size != -1 */
- int t;
- t=EVP_MD_CTX_size(s->read_hash);
- OPENSSL_assert(t >= 0);
- mac_size=t;
-
- if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
- {
-#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
- al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
- goto f_err;
-#else
- goto err;
-#endif
- }
- /* check the MAC for rr->input (it's in mac_size bytes at the tail) */
- if (rr->length < mac_size)
- {
-#if 0 /* OK only for stream ciphers */
- al=SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
- goto f_err;
-#else
- goto err;
-#endif
- }
- rr->length-=mac_size;
- i=s->method->ssl3_enc->mac(s,md,0);
- if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
- {
- goto err;
- }
- }
-
- /* r->length is now just compressed */
- if (s->expand != NULL)
- {
- if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH)
- {
- al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
- goto f_err;
- }
- if (!ssl3_do_uncompress(s))
- {
- al=SSL_AD_DECOMPRESSION_FAILURE;
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_BAD_DECOMPRESSION);
- goto f_err;
- }
- }
-
- if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH)
- {
- al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
- goto f_err;
- }
-
- rr->off=0;
- /* So at this point the following is true
- * ssl->s3->rrec.type is the type of record
- * ssl->s3->rrec.length == number of bytes in record
- * ssl->s3->rrec.off == offset to first valid byte
- * ssl->s3->rrec.data == where to take bytes from, increment
- * after use :-).
- */
-
- /* we have pulled in a full packet so zero things */
- s->packet_length=0;
- dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
- return(1);
-
-f_err:
- ssl3_send_alert(s,SSL3_AL_FATAL,al);
-err:
- return(0);
-}
-
-
-/* Call this to get a new input record.
- * It will return <= 0 if more data is needed, normally due to an error
- * or non-blocking IO.
- * When it finishes, one packet has been decoded and can be found in
- * ssl->s3->rrec.type - is the type of record
- * ssl->s3->rrec.data, - data
- * ssl->s3->rrec.length, - number of bytes
- */
-/* used only by dtls1_read_bytes */
-int dtls1_get_record(SSL *s)
- {
- int ssl_major,ssl_minor;
- int i,n;
- SSL3_RECORD *rr;
- unsigned char *p = NULL;
- unsigned short version;
- DTLS1_BITMAP *bitmap;
- unsigned int is_next_epoch;
-
- rr= &(s->s3->rrec);
-
- /* The epoch may have changed. If so, process all the
- * pending records. This is a non-blocking operation. */
- dtls1_process_buffered_records(s);
-
- /* if we're renegotiating, then there may be buffered records */
- if (dtls1_get_processed_record(s))
- return 1;
-
- /* get something from the wire */
-again:
- /* check if we have the header */
- if ( (s->rstate != SSL_ST_READ_BODY) ||
- (s->packet_length < DTLS1_RT_HEADER_LENGTH))
- {
- n=ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
- /* read timeout is handled by dtls1_read_bytes */
- if (n <= 0) return(n); /* error or non-blocking */
-
- /* this packet contained a partial record, dump it */
- if (s->packet_length != DTLS1_RT_HEADER_LENGTH)
- {
- s->packet_length = 0;
- goto again;
- }
-
- s->rstate=SSL_ST_READ_BODY;
-
- p=s->packet;
-
- /* Pull apart the header into the DTLS1_RECORD */
- rr->type= *(p++);
- ssl_major= *(p++);
- ssl_minor= *(p++);
- version=(ssl_major<<8)|ssl_minor;
-
- /* sequence number is 64 bits, with top 2 bytes = epoch */
- n2s(p,rr->epoch);
-
- memcpy(&(s->s3->read_sequence[2]), p, 6);
- p+=6;
-
- n2s(p,rr->length);
-
- /* Lets check version */
- if (!s->first_packet)
- {
- if (version != s->version)
- {
- /* unexpected version, silently discard */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
- }
-
- if ((version & 0xff00) != (s->version & 0xff00))
- {
- /* wrong version, silently discard record */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
-
- if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
- {
- /* record too long, silently discard it */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
-
- /* now s->rstate == SSL_ST_READ_BODY */
- }
-
- /* s->rstate == SSL_ST_READ_BODY, get and decode the data */
-
- if (rr->length > s->packet_length-DTLS1_RT_HEADER_LENGTH)
- {
- /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
- i=rr->length;
- n=ssl3_read_n(s,i,i,1);
- if (n <= 0) return(n); /* error or non-blocking io */
-
- /* this packet contained a partial record, dump it */
- if ( n != i)
- {
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
-
- /* now n == rr->length,
- * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */
- }
- s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */
-
- /* match epochs. NULL means the packet is dropped on the floor */
- bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
- if ( bitmap == NULL)
- {
- rr->length = 0;
- s->packet_length = 0; /* dump this record */
- goto again; /* get another record */
- }
-
- /* Check whether this is a repeat, or aged record.
- * Don't check if we're listening and this message is
- * a ClientHello. They can look as if they're replayed,
- * since they arrive from different connections and
- * would be dropped unnecessarily.
- */
- if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
- *p == SSL3_MT_CLIENT_HELLO) &&
- !dtls1_record_replay_check(s, bitmap))
- {
- rr->length = 0;
- s->packet_length=0; /* dump this record */
- goto again; /* get another record */
- }
-
- /* just read a 0 length packet */
- if (rr->length == 0) goto again;
-
- /* If this record is from the next epoch (either HM or ALERT),
- * and a handshake is currently in progress, buffer it since it
- * cannot be processed at this time. */
- if (is_next_epoch)
- {
- if (SSL_in_init(s) || s->in_handshake)
- {
- dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
- }
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
-
- if (!dtls1_process_record(s))
- {
- rr->length = 0;
- s->packet_length = 0; /* dump this record */
- goto again; /* get another record */
- }
-
- dtls1_clear_timeouts(s); /* done waiting */
- return(1);
-
- }
-
-/* Return up to 'len' payload bytes received in 'type' records.
- * 'type' is one of the following:
- *
- * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
- * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
- * - 0 (during a shutdown, no data has to be returned)
- *
- * If we don't have stored data to work from, read a SSL/TLS record first
- * (possibly multiple records if we still don't have anything to return).
- *
- * This function must handle any surprises the peer may have for us, such as
- * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
- * a surprise, but handled as if it were), or renegotiation requests.
- * Also if record payloads contain fragments too small to process, we store
- * them until there is enough for the respective protocol (the record protocol
- * may use arbitrary fragmentation and even interleaving):
- * Change cipher spec protocol
- * just 1 byte needed, no need for keeping anything stored
- * Alert protocol
- * 2 bytes needed (AlertLevel, AlertDescription)
- * Handshake protocol
- * 4 bytes needed (HandshakeType, uint24 length) -- we just have
- * to detect unexpected Client Hello and Hello Request messages
- * here, anything else is handled by higher layers
- * Application data protocol
- * none of our business
- */
-int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
- {
- int al,i,j,ret;
- unsigned int n;
- SSL3_RECORD *rr;
- void (*cb)(const SSL *ssl,int type2,int val)=NULL;
-
- if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
- if (!ssl3_setup_buffers(s))
- return(-1);
-
- /* XXX: check what the second '&& type' is about */
- if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
- (type != SSL3_RT_HANDSHAKE) && type) ||
- (peek && (type != SSL3_RT_APPLICATION_DATA)))
- {
- SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
- return -1;
- }
-
- /* check whether there's a handshake message (client hello?) waiting */
- if ( (ret = have_handshake_fragment(s, type, buf, len, peek)))
- return ret;
-
- /* Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */
-
- if (!s->in_handshake && SSL_in_init(s))
- {
- /* type == SSL3_RT_APPLICATION_DATA */
- i=s->handshake_func(s);
- if (i < 0) return(i);
- if (i == 0)
- {
- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
- return(-1);
- }
- }
-
-start:
- s->rwstate=SSL_NOTHING;
-
- /* s->s3->rrec.type - is the type of record
- * s->s3->rrec.data, - data
- * s->s3->rrec.off, - offset into 'data' for next read
- * s->s3->rrec.length, - number of bytes. */
- rr = &(s->s3->rrec);
-
- /* We are not handshaking and have no data yet,
- * so process data buffered during the last handshake
- * in advance, if any.
- */
- if (s->state == SSL_ST_OK && rr->length == 0)
- {
- pitem *item;
- item = pqueue_pop(s->d1->buffered_app_data.q);
- if (item)
- {
- dtls1_copy_record(s, item);
-
- OPENSSL_free(item->data);
- pitem_free(item);
- }
- }
-
- /* Check for timeout */
- if (dtls1_handle_timeout(s) > 0)
- goto start;
-
- /* get new packet if necessary */
- if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
- {
- ret=dtls1_get_record(s);
- if (ret <= 0)
- {
- ret = dtls1_read_failed(s, ret);
- /* anything other than a timeout is an error */
- if (ret <= 0)
- return(ret);
- else
- goto start;
- }
- }
-
- /* we now have a packet which can be read and processed */
-
- if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
- * reset by ssl3_get_finished */
- && (rr->type != SSL3_RT_HANDSHAKE))
- {
- /* We now have application data between CCS and Finished.
- * Most likely the packets were reordered on their way, so
- * buffer the application data for later processing rather
- * than dropping the connection.
- */
- dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num);
- rr->length = 0;
- goto start;
- }
-
- /* If the other end has shut down, throw anything we read away
- * (even in 'peek' mode) */
- if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
- {
- rr->length=0;
- s->rwstate=SSL_NOTHING;
- return(0);
- }
-
-
- if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
- {
- /* make sure that we are not getting application data when we
- * are doing a handshake for the first time */
- if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
- (s->enc_read_ctx == NULL))
- {
- al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE);
- goto f_err;
- }
-
- if (len <= 0) return(len);
-
- if ((unsigned int)len > rr->length)
- n = rr->length;
- else
- n = (unsigned int)len;
-
- memcpy(buf,&(rr->data[rr->off]),n);
- if (!peek)
- {
- rr->length-=n;
- rr->off+=n;
- if (rr->length == 0)
- {
- s->rstate=SSL_ST_READ_HEADER;
- rr->off=0;
- }
- }
- return(n);
- }
-
-
- /* If we get here, then type != rr->type; if we have a handshake
- * message, then it was unexpected (Hello Request or Client Hello). */
-
- /* In case of record types for which we have 'fragment' storage,
- * fill that so that we can process the data at a fixed place.
- */
- {
- unsigned int k, dest_maxlen = 0;
- unsigned char *dest = NULL;
- unsigned int *dest_len = NULL;
-
- if (rr->type == SSL3_RT_HANDSHAKE)
- {
- dest_maxlen = sizeof s->d1->handshake_fragment;
- dest = s->d1->handshake_fragment;
- dest_len = &s->d1->handshake_fragment_len;
- }
- else if (rr->type == SSL3_RT_ALERT)
- {
- dest_maxlen = sizeof(s->d1->alert_fragment);
- dest = s->d1->alert_fragment;
- dest_len = &s->d1->alert_fragment_len;
- }
- /* else it's a CCS message, or application data or wrong */
- else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC)
- {
- /* Application data while renegotiating
- * is allowed. Try again reading.
- */
- if (rr->type == SSL3_RT_APPLICATION_DATA)
- {
- BIO *bio;
- s->s3->in_read_app_data=2;
- bio=SSL_get_rbio(s);
- s->rwstate=SSL_READING;
- BIO_clear_retry_flags(bio);
- BIO_set_retry_read(bio);
- return(-1);
- }
-
- /* Not certain if this is the right error handling */
- al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
- goto f_err;
- }
-
- if (dest_maxlen > 0)
- {
- /* XDTLS: In a pathalogical case, the Client Hello
- * may be fragmented--don't always expect dest_maxlen bytes */
- if ( rr->length < dest_maxlen)
- {
-#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
- /*
- * for normal alerts rr->length is 2, while
- * dest_maxlen is 7 if we were to handle this
- * non-existing alert...
- */
- FIX ME
-#endif
- s->rstate=SSL_ST_READ_HEADER;
- rr->length = 0;
- goto start;
- }
-
- /* now move 'n' bytes: */
- for ( k = 0; k < dest_maxlen; k++)
- {
- dest[k] = rr->data[rr->off++];
- rr->length--;
- }
- *dest_len = dest_maxlen;
- }
- }
-
- /* s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE;
- * s->d1->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT.
- * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */
-
- /* If we are a client, check for an incoming 'Hello Request': */
- if ((!s->server) &&
- (s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
- (s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
- (s->session != NULL) && (s->session->cipher != NULL))
- {
- s->d1->handshake_fragment_len = 0;
-
- if ((s->d1->handshake_fragment[1] != 0) ||
- (s->d1->handshake_fragment[2] != 0) ||
- (s->d1->handshake_fragment[3] != 0))
- {
- al=SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
- goto err;
- }
-
- /* no need to check sequence number on HELLO REQUEST messages */
-
- if (s->msg_callback)
- s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
- s->d1->handshake_fragment, 4, s, s->msg_callback_arg);
-
- if (SSL_is_init_finished(s) &&
- !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
- !s->s3->renegotiate)
- {
- ssl3_renegotiate(s);
- if (ssl3_renegotiate_check(s))
- {
- i=s->handshake_func(s);
- if (i < 0) return(i);
- if (i == 0)
- {
- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
- return(-1);
- }
-
- if (!(s->mode & SSL_MODE_AUTO_RETRY))
- {
- if (s->s3->rbuf.left == 0) /* no read-ahead left? */
- {
- BIO *bio;
- /* In the case where we try to read application data,
- * but we trigger an SSL handshake, we return -1 with
- * the retry option set. Otherwise renegotiation may
- * cause nasty problems in the blocking world */
- s->rwstate=SSL_READING;
- bio=SSL_get_rbio(s);
- BIO_clear_retry_flags(bio);
- BIO_set_retry_read(bio);
- return(-1);
- }
- }
- }
- }
- /* we either finished a handshake or ignored the request,
- * now try again to obtain the (application) data we were asked for */
- goto start;
- }
-
- if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH)
- {
- int alert_level = s->d1->alert_fragment[0];
- int alert_descr = s->d1->alert_fragment[1];
-
- s->d1->alert_fragment_len = 0;
-
- if (s->msg_callback)
- s->msg_callback(0, s->version, SSL3_RT_ALERT,
- s->d1->alert_fragment, 2, s, s->msg_callback_arg);
-
- if (s->info_callback != NULL)
- cb=s->info_callback;
- else if (s->ctx->info_callback != NULL)
- cb=s->ctx->info_callback;
-
- if (cb != NULL)
- {
- j = (alert_level << 8) | alert_descr;
- cb(s, SSL_CB_READ_ALERT, j);
- }
-
- if (alert_level == 1) /* warning */
- {
- s->s3->warn_alert = alert_descr;
- if (alert_descr == SSL_AD_CLOSE_NOTIFY)
- {
- s->shutdown |= SSL_RECEIVED_SHUTDOWN;
- return(0);
- }
-#if 0
- /* XXX: this is a possible improvement in the future */
- /* now check if it's a missing record */
- if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
- {
- unsigned short seq;
- unsigned int frag_off;
- unsigned char *p = &(s->d1->alert_fragment[2]);
-
- n2s(p, seq);
- n2l3(p, frag_off);
-
- dtls1_retransmit_message(s,
- dtls1_get_queue_priority(frag->msg_header.seq, 0),
- frag_off, &found);
- if ( ! found && SSL_in_init(s))
- {
- /* fprintf( stderr,"in init = %d\n", SSL_in_init(s)); */
- /* requested a message not yet sent,
- send an alert ourselves */
- ssl3_send_alert(s,SSL3_AL_WARNING,
- DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
- }
- }
-#endif
- }
- else if (alert_level == 2) /* fatal */
- {
- char tmp[16];
-
- s->rwstate=SSL_NOTHING;
- s->s3->fatal_alert = alert_descr;
- SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
- BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr);
- ERR_add_error_data(2,"SSL alert number ",tmp);
- s->shutdown|=SSL_RECEIVED_SHUTDOWN;
- SSL_CTX_remove_session(s->ctx,s->session);
- return(0);
- }
- else
- {
- al=SSL_AD_ILLEGAL_PARAMETER;
- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);
- goto f_err;
- }
-
- goto start;
- }
-
- if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */
- {
- s->rwstate=SSL_NOTHING;
- rr->length=0;
- return(0);
- }
-
- if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
- {
- struct ccs_header_st ccs_hdr;
- unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH;
-
- dtls1_get_ccs_header(rr->data, &ccs_hdr);
-
- if (s->version == DTLS1_BAD_VER)
- ccs_hdr_len = 3;
-
- /* 'Change Cipher Spec' is just a single byte, so we know
- * exactly what the record payload has to look like */
- /* XDTLS: check that epoch is consistent */
- if ( (rr->length != ccs_hdr_len) ||
- (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
- {
- i=SSL_AD_ILLEGAL_PARAMETER;
- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
- goto err;
- }
-
- rr->length=0;
-
- if (s->msg_callback)
- s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
- rr->data, 1, s, s->msg_callback_arg);
-
- /* We can't process a CCS now, because previous handshake
- * messages are still missing, so just drop it.
- */
- if (!s->d1->change_cipher_spec_ok)
- {
- goto start;
- }
-
- s->d1->change_cipher_spec_ok = 0;
-
- s->s3->change_cipher_spec=1;
- if (!ssl3_do_change_cipher_spec(s))
- goto err;
-
- /* do this whenever CCS is processed */
- dtls1_reset_seq_numbers(s, SSL3_CC_READ);
-
- if (s->version == DTLS1_BAD_VER)
- s->d1->handshake_read_seq++;
-
- goto start;
- }
-
- /* Unexpected handshake message (Client Hello, or protocol violation) */
- if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
- !s->in_handshake)
- {
- struct hm_header_st msg_hdr;
-
- /* this may just be a stale retransmit */
- dtls1_get_message_header(rr->data, &msg_hdr);
- if( rr->epoch != s->d1->r_epoch)
- {
- rr->length = 0;
- goto start;
- }
-
- /* If we are server, we may have a repeated FINISHED of the
- * client here, then retransmit our CCS and FINISHED.
- */
- if (msg_hdr.type == SSL3_MT_FINISHED)
- {
- dtls1_retransmit_buffered_messages(s);
- rr->length = 0;
- goto start;
- }
-
- if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
- !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
- {
-#if 0 /* worked only because C operator preferences are not as expected (and
- * because this is not really needed for clients except for detecting
- * protocol violations): */
- s->state=SSL_ST_BEFORE|(s->server)
- ?SSL_ST_ACCEPT
- :SSL_ST_CONNECT;
-#else
- s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
-#endif
- s->new_session=1;
- }
- i=s->handshake_func(s);
- if (i < 0) return(i);
- if (i == 0)
- {
- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
- return(-1);
- }
-
- if (!(s->mode & SSL_MODE_AUTO_RETRY))
- {
- if (s->s3->rbuf.left == 0) /* no read-ahead left? */
- {
- BIO *bio;
- /* In the case where we try to read application data,
- * but we trigger an SSL handshake, we return -1 with
- * the retry option set. Otherwise renegotiation may
- * cause nasty problems in the blocking world */
- s->rwstate=SSL_READING;
- bio=SSL_get_rbio(s);
- BIO_clear_retry_flags(bio);
- BIO_set_retry_read(bio);
- return(-1);
- }
- }
- goto start;
- }
-
- switch (rr->type)
- {
- default:
-#ifndef OPENSSL_NO_TLS
- /* TLS just ignores unknown message types */
- if (s->version == TLS1_VERSION)
- {
- rr->length = 0;
- goto start;
- }
-#endif
- al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
- goto f_err;
- case SSL3_RT_CHANGE_CIPHER_SPEC:
- case SSL3_RT_ALERT:
- case SSL3_RT_HANDSHAKE:
- /* we already handled all of these, with the possible exception
- * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that
- * should not happen when type != rr->type */
- al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_DTLS1_READ_BYTES,ERR_R_INTERNAL_ERROR);
- goto f_err;
- case SSL3_RT_APPLICATION_DATA:
- /* At this point, we were expecting handshake data,
- * but have application data. If the library was
- * running inside ssl3_read() (i.e. in_read_app_data
- * is set) and it makes sense to read application data
- * at this point (session renegotiation not yet started),
- * we will indulge it.
- */
- if (s->s3->in_read_app_data &&
- (s->s3->total_renegotiations != 0) &&
- ((
- (s->state & SSL_ST_CONNECT) &&
- (s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
- (s->state <= SSL3_ST_CR_SRVR_HELLO_A)
- ) || (
- (s->state & SSL_ST_ACCEPT) &&
- (s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
- (s->state >= SSL3_ST_SR_CLNT_HELLO_A)
- )
- ))
- {
- s->s3->in_read_app_data=2;
- return(-1);
- }
- else
- {
- al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
- goto f_err;
- }
- }
- /* not reached */
-
-f_err:
- ssl3_send_alert(s,SSL3_AL_FATAL,al);
-err:
- return(-1);
- }
-
-int
-dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
- {
- int i;
-
- if (SSL_in_init(s) && !s->in_handshake)
- {
- i=s->handshake_func(s);
- if (i < 0) return(i);
- if (i == 0)
- {
- SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
- return -1;
- }
- }
-
- if (len > SSL3_RT_MAX_PLAIN_LENGTH)
- {
- SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_DTLS_MESSAGE_TOO_BIG);
- return -1;
- }
-
- i = dtls1_write_bytes(s, type, buf_, len);
- return i;
- }
-
-
- /* this only happens when a client hello is received and a handshake
- * is started. */
-static int
-have_handshake_fragment(SSL *s, int type, unsigned char *buf,
- int len, int peek)
- {
-
- if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0))
- /* (partially) satisfy request from storage */
- {
- unsigned char *src = s->d1->handshake_fragment;
- unsigned char *dst = buf;
- unsigned int k,n;
-
- /* peek == 0 */
- n = 0;
- while ((len > 0) && (s->d1->handshake_fragment_len > 0))
- {
- *dst++ = *src++;
- len--; s->d1->handshake_fragment_len--;
- n++;
- }
- /* move any remaining fragment bytes: */
- for (k = 0; k < s->d1->handshake_fragment_len; k++)
- s->d1->handshake_fragment[k] = *src++;
- return n;
- }
-
- return 0;
- }
-
-
-
-
-/* Call this to write data in records of type 'type'
- * It will return <= 0 if not all data has been sent or non-blocking IO.
- */
-int dtls1_write_bytes(SSL *s, int type, const void *buf, int len)
- {
- int i;
-
- OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
- s->rwstate=SSL_NOTHING;
- i=do_dtls1_write(s, type, buf, len, 0);
- return i;
- }
-
-int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment)
- {
- unsigned char *p,*pseq;
- int i,mac_size,clear=0;
- int prefix_len = 0;
- SSL3_RECORD *wr;
- SSL3_BUFFER *wb;
- SSL_SESSION *sess;
- int bs;
-
- /* first check if there is a SSL3_BUFFER still being written
- * out. This will happen with non blocking IO */
- if (s->s3->wbuf.left != 0)
- {
- OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */
- return(ssl3_write_pending(s,type,buf,len));
- }
-
- /* If we have an alert to send, lets send it */
- if (s->s3->alert_dispatch)
- {
- i=s->method->ssl_dispatch_alert(s);
- if (i <= 0)
- return(i);
- /* if it went, fall through and send more stuff */
- }
-
- if (len == 0 && !create_empty_fragment)
- return 0;
-
- wr= &(s->s3->wrec);
- wb= &(s->s3->wbuf);
- sess=s->session;
-
- if ( (sess == NULL) ||
- (s->enc_write_ctx == NULL) ||
- (EVP_MD_CTX_md(s->write_hash) == NULL))
- clear=1;
-
- if (clear)
- mac_size=0;
- else
- {
- mac_size=EVP_MD_CTX_size(s->write_hash);
- if (mac_size < 0)
- goto err;
- }
-
- /* DTLS implements explicit IV, so no need for empty fragments */
-#if 0
- /* 'create_empty_fragment' is true only when this function calls itself */
- if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done
- && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
- {
- /* countermeasure against known-IV weakness in CBC ciphersuites
- * (see http://www.openssl.org/~bodo/tls-cbc.txt)
- */
-
- if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)
- {
- /* recursive function call with 'create_empty_fragment' set;
- * this prepares and buffers the data for an empty fragment
- * (these 'prefix_len' bytes are sent out later
- * together with the actual payload) */
- prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1);
- if (prefix_len <= 0)
- goto err;
-
- if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)
- {
- /* insufficient space */
- SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- }
-
- s->s3->empty_fragment_done = 1;
- }
-#endif
- p = wb->buf + prefix_len;
-
- /* write the header */
-
- *(p++)=type&0xff;
- wr->type=type;
-
- *(p++)=(s->version>>8);
- *(p++)=s->version&0xff;
-
- /* field where we are to write out packet epoch, seq num and len */
- pseq=p;
- p+=10;
-
- /* lets setup the record stuff. */
-
- /* Make space for the explicit IV in case of CBC.
- * (this is a bit of a boundary violation, but what the heck).
- */
- if ( s->enc_write_ctx &&
- (EVP_CIPHER_mode( s->enc_write_ctx->cipher ) & EVP_CIPH_CBC_MODE))
- bs = EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
- else
- bs = 0;
-
- wr->data=p + bs; /* make room for IV in case of CBC */
- wr->length=(int)len;
- wr->input=(unsigned char *)buf;
-
- /* we now 'read' from wr->input, wr->length bytes into
- * wr->data */
-
- /* first we compress */
- if (s->compress != NULL)
- {
- if (!ssl3_do_compress(s))
- {
- SSLerr(SSL_F_DO_DTLS1_WRITE,SSL_R_COMPRESSION_FAILURE);
- goto err;
- }
- }
- else
- {
- memcpy(wr->data,wr->input,wr->length);
- wr->input=wr->data;
- }
-
- /* we should still have the output to wr->data and the input
- * from wr->input. Length should be wr->length.
- * wr->data still points in the wb->buf */
-
- if (mac_size != 0)
- {
- if(s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1) < 0)
- goto err;
- wr->length+=mac_size;
- }
-
- /* this is true regardless of mac size */
- wr->input=p;
- wr->data=p;
-
-
- /* ssl3_enc can only have an error on read */
- if (bs) /* bs != 0 in case of CBC */
- {
- RAND_pseudo_bytes(p,bs);
- /* master IV and last CBC residue stand for
- * the rest of randomness */
- wr->length += bs;
- }
-
- s->method->ssl3_enc->enc(s,1);
-
- /* record length after mac and block padding */
-/* if (type == SSL3_RT_APPLICATION_DATA ||
- (type == SSL3_RT_ALERT && ! SSL_in_init(s))) */
-
- /* there's only one epoch between handshake and app data */
-
- s2n(s->d1->w_epoch, pseq);
-
- /* XDTLS: ?? */
-/* else
- s2n(s->d1->handshake_epoch, pseq); */
-
- memcpy(pseq, &(s->s3->write_sequence[2]), 6);
- pseq+=6;
- s2n(wr->length,pseq);
-
- /* we should now have
- * wr->data pointing to the encrypted data, which is
- * wr->length long */
- wr->type=type; /* not needed but helps for debugging */
- wr->length+=DTLS1_RT_HEADER_LENGTH;
-
-#if 0 /* this is now done at the message layer */
- /* buffer the record, making it easy to handle retransmits */
- if ( type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC)
- dtls1_buffer_record(s, wr->data, wr->length,
- *((PQ_64BIT *)&(s->s3->write_sequence[0])));
-#endif
-
- ssl3_record_sequence_update(&(s->s3->write_sequence[0]));
-
- if (create_empty_fragment)
- {
- /* we are in a recursive call;
- * just return the length, don't write out anything here
- */
- return wr->length;
- }
-
- /* now let's set up wb */
- wb->left = prefix_len + wr->length;
- wb->offset = 0;
-
- /* memorize arguments so that ssl3_write_pending can detect bad write retries later */
- s->s3->wpend_tot=len;
- s->s3->wpend_buf=buf;
- s->s3->wpend_type=type;
- s->s3->wpend_ret=len;
-
- /* we now just need to write the buffer */
- return ssl3_write_pending(s,type,buf,len);
-err:
- return -1;
- }
-
-
-
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
- {
- int cmp;
- unsigned int shift;
- const unsigned char *seq = s->s3->read_sequence;
-
- cmp = satsub64be(seq,bitmap->max_seq_num);
- if (cmp > 0)
- {
- memcpy (s->s3->rrec.seq_num,seq,8);
- return 1; /* this record in new */
- }
- shift = -cmp;
- if (shift >= sizeof(bitmap->map)*8)
- return 0; /* stale, outside the window */
- else if (bitmap->map & (1UL<<shift))
- return 0; /* record previously received */
-
- memcpy (s->s3->rrec.seq_num,seq,8);
- return 1;
- }
-
-
-static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
- {
- int cmp;
- unsigned int shift;
- const unsigned char *seq = s->s3->read_sequence;
-
- cmp = satsub64be(seq,bitmap->max_seq_num);
- if (cmp > 0)
- {
- shift = cmp;
- if (shift < sizeof(bitmap->map)*8)
- bitmap->map <<= shift, bitmap->map |= 1UL;
- else
- bitmap->map = 1UL;
- memcpy(bitmap->max_seq_num,seq,8);
- }
- else {
- shift = -cmp;
- if (shift < sizeof(bitmap->map)*8)
- bitmap->map |= 1UL<<shift;
- }
- }
-
-
-int dtls1_dispatch_alert(SSL *s)
- {
- int i,j;
- void (*cb)(const SSL *ssl,int type,int val)=NULL;
- unsigned char buf[DTLS1_AL_HEADER_LENGTH];
- unsigned char *ptr = &buf[0];
-
- s->s3->alert_dispatch=0;
-
- memset(buf, 0x00, sizeof(buf));
- *ptr++ = s->s3->send_alert[0];
- *ptr++ = s->s3->send_alert[1];
-
-#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
- if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
- {
- s2n(s->d1->handshake_read_seq, ptr);
-#if 0
- if ( s->d1->r_msg_hdr.frag_off == 0) /* waiting for a new msg */
-
- else
- s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */
-#endif
-
-#if 0
- fprintf(stderr, "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n",s->d1->handshake_read_seq,s->d1->r_msg_hdr.seq);
-#endif
- l2n3(s->d1->r_msg_hdr.frag_off, ptr);
- }
-#endif
-
- i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
- if (i <= 0)
- {
- s->s3->alert_dispatch=1;
- /* fprintf( stderr, "not done with alert\n" ); */
- }
- else
- {
- if (s->s3->send_alert[0] == SSL3_AL_FATAL
-#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
- || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
-#endif
- )
- (void)BIO_flush(s->wbio);
-
- if (s->msg_callback)
- s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert,
- 2, s, s->msg_callback_arg);
-
- if (s->info_callback != NULL)
- cb=s->info_callback;
- else if (s->ctx->info_callback != NULL)
- cb=s->ctx->info_callback;
-
- if (cb != NULL)
- {
- j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1];
- cb(s,SSL_CB_WRITE_ALERT,j);
- }
- }
- return(i);
- }
-
-
-static DTLS1_BITMAP *
-dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch)
- {
-
- *is_next_epoch = 0;
-
- /* In current epoch, accept HM, CCS, DATA, & ALERT */
- if (rr->epoch == s->d1->r_epoch)
- return &s->d1->bitmap;
-
- /* Only HM and ALERT messages can be from the next epoch */
- else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) &&
- (rr->type == SSL3_RT_HANDSHAKE ||
- rr->type == SSL3_RT_ALERT))
- {
- *is_next_epoch = 1;
- return &s->d1->next_bitmap;
- }
-
- return NULL;
- }
-
-#if 0
-static int
-dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, unsigned short *priority,
- unsigned long *offset)
- {
-
- /* alerts are passed up immediately */
- if ( rr->type == SSL3_RT_APPLICATION_DATA ||
- rr->type == SSL3_RT_ALERT)
- return 0;
-
- /* Only need to buffer if a handshake is underway.
- * (this implies that Hello Request and Client Hello are passed up
- * immediately) */
- if ( SSL_in_init(s))
- {
- unsigned char *data = rr->data;
- /* need to extract the HM/CCS sequence number here */
- if ( rr->type == SSL3_RT_HANDSHAKE ||
- rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
- {
- unsigned short seq_num;
- struct hm_header_st msg_hdr;
- struct ccs_header_st ccs_hdr;
-
- if ( rr->type == SSL3_RT_HANDSHAKE)
- {
- dtls1_get_message_header(data, &msg_hdr);
- seq_num = msg_hdr.seq;
- *offset = msg_hdr.frag_off;
- }
- else
- {
- dtls1_get_ccs_header(data, &ccs_hdr);
- seq_num = ccs_hdr.seq;
- *offset = 0;
- }
-
- /* this is either a record we're waiting for, or a
- * retransmit of something we happened to previously
- * receive (higher layers will drop the repeat silently */
- if ( seq_num < s->d1->handshake_read_seq)
- return 0;
- if (rr->type == SSL3_RT_HANDSHAKE &&
- seq_num == s->d1->handshake_read_seq &&
- msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off)
- return 0;
- else if ( seq_num == s->d1->handshake_read_seq &&
- (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC ||
- msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off))
- return 0;
- else
- {
- *priority = seq_num;
- return 1;
- }
- }
- else /* unknown record type */
- return 0;
- }
-
- return 0;
- }
-#endif
-
-void
-dtls1_reset_seq_numbers(SSL *s, int rw)
- {
- unsigned char *seq;
- unsigned int seq_bytes = sizeof(s->s3->read_sequence);
-
- if ( rw & SSL3_CC_READ)
- {
- seq = s->s3->read_sequence;
- s->d1->r_epoch++;
- memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP));
- memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
- }
- else
- {
- seq = s->s3->write_sequence;
- memcpy(s->d1->last_write_sequence, seq, sizeof(s->s3->write_sequence));
- s->d1->w_epoch++;
- }
-
- memset(seq, 0x00, seq_bytes);
- }
-
-
-static void
-dtls1_clear_timeouts(SSL *s)
- {
- memset(&(s->d1->timeout), 0x00, sizeof(struct dtls1_timeout_st));
- }
+/* ssl/d1_pkt.c */
+/*
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "ssl_locl.h"
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+#include <openssl/pqueue.h>
+#include <openssl/rand.h>
+
+/* mod 128 saturating subtract of two 64-bit values in big-endian order */
+static int satsub64be(const unsigned char *v1,const unsigned char *v2)
+{ int ret,sat,brw,i;
+
+ if (sizeof(long) == 8) do
+ { const union { long one; char little; } is_endian = {1};
+ long l;
+
+ if (is_endian.little) break;
+ /* not reached on little-endians */
+ /* following test is redundant, because input is
+ * always aligned, but I take no chances... */
+ if (((size_t)v1|(size_t)v2)&0x7) break;
+
+ l = *((long *)v1);
+ l -= *((long *)v2);
+ if (l>128) return 128;
+ else if (l<-128) return -128;
+ else return (int)l;
+ } while (0);
+
+ ret = (int)v1[7]-(int)v2[7];
+ sat = 0;
+ brw = ret>>8; /* brw is either 0 or -1 */
+ if (ret & 0x80)
+ { for (i=6;i>=0;i--)
+ { brw += (int)v1[i]-(int)v2[i];
+ sat |= ~brw;
+ brw >>= 8;
+ }
+ }
+ else
+ { for (i=6;i>=0;i--)
+ { brw += (int)v1[i]-(int)v2[i];
+ sat |= brw;
+ brw >>= 8;
+ }
+ }
+ brw <<= 8; /* brw is either 0 or -256 */
+
+ if (sat&0xff) return brw | 0x80;
+ else return brw + (ret&0xFF);
+}
+
+static int have_handshake_fragment(SSL *s, int type, unsigned char *buf,
+ int len, int peek);
+static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
+static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
+static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
+ unsigned int *is_next_epoch);
+#if 0
+static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
+ unsigned short *priority, unsigned long *offset);
+#endif
+static int dtls1_buffer_record(SSL *s, record_pqueue *q,
+ unsigned char *priority);
+static int dtls1_process_record(SSL *s);
+static void dtls1_clear_timeouts(SSL *s);
+
+/* copy buffered record into SSL structure */
+static int
+dtls1_copy_record(SSL *s, pitem *item)
+ {
+ DTLS1_RECORD_DATA *rdata;
+
+ rdata = (DTLS1_RECORD_DATA *)item->data;
+
+ if (s->s3->rbuf.buf != NULL)
+ OPENSSL_free(s->s3->rbuf.buf);
+
+ s->packet = rdata->packet;
+ s->packet_length = rdata->packet_length;
+ memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
+ memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
+
+ /* Set proper sequence number for mac calculation */
+ memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6);
+
+ return(1);
+ }
+
+
+static int
+dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
+ {
+ DTLS1_RECORD_DATA *rdata;
+ pitem *item;
+
+ /* Limit the size of the queue to prevent DOS attacks */
+ if (pqueue_size(queue->q) >= 100)
+ return 0;
+
+ rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
+ item = pitem_new(priority, rdata);
+ if (rdata == NULL || item == NULL)
+ {
+ if (rdata != NULL) OPENSSL_free(rdata);
+ if (item != NULL) pitem_free(item);
+
+ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+ return(0);
+ }
+
+ rdata->packet = s->packet;
+ rdata->packet_length = s->packet_length;
+ memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER));
+ memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD));
+
+ item->data = rdata;
+
+ /* insert should not fail, since duplicates are dropped */
+ if (pqueue_insert(queue->q, item) == NULL)
+ {
+ OPENSSL_free(rdata);
+ pitem_free(item);
+ return(0);
+ }
+
+ s->packet = NULL;
+ s->packet_length = 0;
+ memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER));
+ memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD));
+
+ if (!ssl3_setup_buffers(s))
+ {
+ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+ OPENSSL_free(rdata);
+ pitem_free(item);
+ return(0);
+ }
+
+ return(1);
+ }
+
+
+static int
+dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
+ {
+ pitem *item;
+
+ item = pqueue_pop(queue->q);
+ if (item)
+ {
+ dtls1_copy_record(s, item);
+
+ OPENSSL_free(item->data);
+ pitem_free(item);
+
+ return(1);
+ }
+
+ return(0);
+ }
+
+
+/* retrieve a buffered record that belongs to the new epoch, i.e., not processed
+ * yet */
+#define dtls1_get_unprocessed_record(s) \
+ dtls1_retrieve_buffered_record((s), \
+ &((s)->d1->unprocessed_rcds))
+
+/* retrieve a buffered record that belongs to the current epoch, ie, processed */
+#define dtls1_get_processed_record(s) \
+ dtls1_retrieve_buffered_record((s), \
+ &((s)->d1->processed_rcds))
+
+static int
+dtls1_process_buffered_records(SSL *s)
+ {
+ pitem *item;
+
+ item = pqueue_peek(s->d1->unprocessed_rcds.q);
+ if (item)
+ {
+ /* Check if epoch is current. */
+ if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch)
+ return(1); /* Nothing to do. */
+
+ /* Process all the records. */
+ while (pqueue_peek(s->d1->unprocessed_rcds.q))
+ {
+ dtls1_get_unprocessed_record(s);
+ if ( ! dtls1_process_record(s))
+ return(0);
+ dtls1_buffer_record(s, &(s->d1->processed_rcds),
+ s->s3->rrec.seq_num);
+ }
+ }
+
+ /* sync epoch numbers once all the unprocessed records
+ * have been processed */
+ s->d1->processed_rcds.epoch = s->d1->r_epoch;
+ s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1;
+
+ return(1);
+ }
+
+
+#if 0
+
+static int
+dtls1_get_buffered_record(SSL *s)
+ {
+ pitem *item;
+ PQ_64BIT priority =
+ (((PQ_64BIT)s->d1->handshake_read_seq) << 32) |
+ ((PQ_64BIT)s->d1->r_msg_hdr.frag_off);
+
+ if ( ! SSL_in_init(s)) /* if we're not (re)negotiating,
+ nothing buffered */
+ return 0;
+
+
+ item = pqueue_peek(s->d1->rcvd_records);
+ if (item && item->priority == priority)
+ {
+ /* Check if we've received the record of interest. It must be
+ * a handshake record, since data records as passed up without
+ * buffering */
+ DTLS1_RECORD_DATA *rdata;
+ item = pqueue_pop(s->d1->rcvd_records);
+ rdata = (DTLS1_RECORD_DATA *)item->data;
+
+ if (s->s3->rbuf.buf != NULL)
+ OPENSSL_free(s->s3->rbuf.buf);
+
+ s->packet = rdata->packet;
+ s->packet_length = rdata->packet_length;
+ memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
+ memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
+
+ OPENSSL_free(item->data);
+ pitem_free(item);
+
+ /* s->d1->next_expected_seq_num++; */
+ return(1);
+ }
+
+ return 0;
+ }
+
+#endif
+
+static int
+dtls1_process_record(SSL *s)
+{
+ int i,al;
+ int clear=0;
+ int enc_err;
+ SSL_SESSION *sess;
+ SSL3_RECORD *rr;
+ unsigned int mac_size;
+ unsigned char md[EVP_MAX_MD_SIZE];
+
+
+ rr= &(s->s3->rrec);
+ sess = s->session;
+
+ /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
+ * and we have that many bytes in s->packet
+ */
+ rr->input= &(s->packet[DTLS1_RT_HEADER_LENGTH]);
+
+ /* ok, we can now read from 's->packet' data into 'rr'
+ * rr->input points at rr->length bytes, which
+ * need to be copied into rr->data by either
+ * the decryption or by the decompression
+ * When the data is 'copied' into the rr->data buffer,
+ * rr->input will be pointed at the new buffer */
+
+ /* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
+ * rr->length bytes of encrypted compressed stuff. */
+
+ /* check is not needed I believe */
+ if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
+ {
+ al=SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+
+ /* decrypt in place in 'rr->input' */
+ rr->data=rr->input;
+
+ enc_err = s->method->ssl3_enc->enc(s,0);
+ if (enc_err <= 0)
+ {
+ if (enc_err == 0)
+ /* SSLerr() and ssl3_send_alert() have been called */
+ goto err;
+
+ /* otherwise enc_err == -1 */
+ al=SSL_AD_BAD_RECORD_MAC;
+ goto f_err;
+ }
+
+#ifdef TLS_DEBUG
+printf("dec %d\n",rr->length);
+{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
+printf("\n");
+#endif
+
+ /* r->length is now the compressed data plus mac */
+ if ( (sess == NULL) ||
+ (s->enc_read_ctx == NULL) ||
+ (s->read_hash == NULL))
+ clear=1;
+
+ if (!clear)
+ {
+ /* !clear => s->read_hash != NULL => mac_size != -1 */
+ int t;
+ t=EVP_MD_CTX_size(s->read_hash);
+ OPENSSL_assert(t >= 0);
+ mac_size=t;
+
+ if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
+ {
+#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
+ al=SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
+ goto f_err;
+#else
+ goto err;
+#endif
+ }
+ /* check the MAC for rr->input (it's in mac_size bytes at the tail) */
+ if (rr->length < mac_size)
+ {
+#if 0 /* OK only for stream ciphers */
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+#else
+ goto err;
+#endif
+ }
+ rr->length-=mac_size;
+ i=s->method->ssl3_enc->mac(s,md,0);
+ if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
+ {
+ goto err;
+ }
+ }
+
+ /* r->length is now just compressed */
+ if (s->expand != NULL)
+ {
+ if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH)
+ {
+ al=SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+ if (!ssl3_do_uncompress(s))
+ {
+ al=SSL_AD_DECOMPRESSION_FAILURE;
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_BAD_DECOMPRESSION);
+ goto f_err;
+ }
+ }
+
+ if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH)
+ {
+ al=SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+
+ rr->off=0;
+ /* So at this point the following is true
+ * ssl->s3->rrec.type is the type of record
+ * ssl->s3->rrec.length == number of bytes in record
+ * ssl->s3->rrec.off == offset to first valid byte
+ * ssl->s3->rrec.data == where to take bytes from, increment
+ * after use :-).
+ */
+
+ /* we have pulled in a full packet so zero things */
+ s->packet_length=0;
+ dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
+ return(1);
+
+f_err:
+ ssl3_send_alert(s,SSL3_AL_FATAL,al);
+err:
+ return(0);
+}
+
+
+/* Call this to get a new input record.
+ * It will return <= 0 if more data is needed, normally due to an error
+ * or non-blocking IO.
+ * When it finishes, one packet has been decoded and can be found in
+ * ssl->s3->rrec.type - is the type of record
+ * ssl->s3->rrec.data, - data
+ * ssl->s3->rrec.length, - number of bytes
+ */
+/* used only by dtls1_read_bytes */
+int dtls1_get_record(SSL *s)
+ {
+ int ssl_major,ssl_minor;
+ int i,n;
+ SSL3_RECORD *rr;
+ unsigned char *p = NULL;
+ unsigned short version;
+ DTLS1_BITMAP *bitmap;
+ unsigned int is_next_epoch;
+
+ rr= &(s->s3->rrec);
+
+ /* The epoch may have changed. If so, process all the
+ * pending records. This is a non-blocking operation. */
+ dtls1_process_buffered_records(s);
+
+ /* if we're renegotiating, then there may be buffered records */
+ if (dtls1_get_processed_record(s))
+ return 1;
+
+ /* get something from the wire */
+again:
+ /* check if we have the header */
+ if ( (s->rstate != SSL_ST_READ_BODY) ||
+ (s->packet_length < DTLS1_RT_HEADER_LENGTH))
+ {
+ n=ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
+ /* read timeout is handled by dtls1_read_bytes */
+ if (n <= 0) return(n); /* error or non-blocking */
+
+ /* this packet contained a partial record, dump it */
+ if (s->packet_length != DTLS1_RT_HEADER_LENGTH)
+ {
+ s->packet_length = 0;
+ goto again;
+ }
+
+ s->rstate=SSL_ST_READ_BODY;
+
+ p=s->packet;
+
+ /* Pull apart the header into the DTLS1_RECORD */
+ rr->type= *(p++);
+ ssl_major= *(p++);
+ ssl_minor= *(p++);
+ version=(ssl_major<<8)|ssl_minor;
+
+ /* sequence number is 64 bits, with top 2 bytes = epoch */
+ n2s(p,rr->epoch);
+
+ memcpy(&(s->s3->read_sequence[2]), p, 6);
+ p+=6;
+
+ n2s(p,rr->length);
+
+ /* Lets check version */
+ if (!s->first_packet)
+ {
+ if (version != s->version)
+ {
+ /* unexpected version, silently discard */
+ rr->length = 0;
+ s->packet_length = 0;
+ goto again;
+ }
+ }
+
+ if ((version & 0xff00) != (s->version & 0xff00))
+ {
+ /* wrong version, silently discard record */
+ rr->length = 0;
+ s->packet_length = 0;
+ goto again;
+ }
+
+ if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
+ {
+ /* record too long, silently discard it */
+ rr->length = 0;
+ s->packet_length = 0;
+ goto again;
+ }
+
+ /* now s->rstate == SSL_ST_READ_BODY */
+ }
+
+ /* s->rstate == SSL_ST_READ_BODY, get and decode the data */
+
+ if (rr->length > s->packet_length-DTLS1_RT_HEADER_LENGTH)
+ {
+ /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
+ i=rr->length;
+ n=ssl3_read_n(s,i,i,1);
+ if (n <= 0) return(n); /* error or non-blocking io */
+
+ /* this packet contained a partial record, dump it */
+ if ( n != i)
+ {
+ rr->length = 0;
+ s->packet_length = 0;
+ goto again;
+ }
+
+ /* now n == rr->length,
+ * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */
+ }
+ s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */
+
+ /* match epochs. NULL means the packet is dropped on the floor */
+ bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
+ if ( bitmap == NULL)
+ {
+ rr->length = 0;
+ s->packet_length = 0; /* dump this record */
+ goto again; /* get another record */
+ }
+
+ /* Check whether this is a repeat, or aged record.
+ * Don't check if we're listening and this message is
+ * a ClientHello. They can look as if they're replayed,
+ * since they arrive from different connections and
+ * would be dropped unnecessarily.
+ */
+ if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
+ *p == SSL3_MT_CLIENT_HELLO) &&
+ !dtls1_record_replay_check(s, bitmap))
+ {
+ rr->length = 0;
+ s->packet_length=0; /* dump this record */
+ goto again; /* get another record */
+ }
+
+ /* just read a 0 length packet */
+ if (rr->length == 0) goto again;
+
+ /* If this record is from the next epoch (either HM or ALERT),
+ * and a handshake is currently in progress, buffer it since it
+ * cannot be processed at this time. */
+ if (is_next_epoch)
+ {
+ if (SSL_in_init(s) || s->in_handshake)
+ {
+ dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
+ }
+ rr->length = 0;
+ s->packet_length = 0;
+ goto again;
+ }
+
+ if (!dtls1_process_record(s))
+ {
+ rr->length = 0;
+ s->packet_length = 0; /* dump this record */
+ goto again; /* get another record */
+ }
+
+ dtls1_clear_timeouts(s); /* done waiting */
+ return(1);
+
+ }
+
+/* Return up to 'len' payload bytes received in 'type' records.
+ * 'type' is one of the following:
+ *
+ * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
+ * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
+ * - 0 (during a shutdown, no data has to be returned)
+ *
+ * If we don't have stored data to work from, read a SSL/TLS record first
+ * (possibly multiple records if we still don't have anything to return).
+ *
+ * This function must handle any surprises the peer may have for us, such as
+ * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
+ * a surprise, but handled as if it were), or renegotiation requests.
+ * Also if record payloads contain fragments too small to process, we store
+ * them until there is enough for the respective protocol (the record protocol
+ * may use arbitrary fragmentation and even interleaving):
+ * Change cipher spec protocol
+ * just 1 byte needed, no need for keeping anything stored
+ * Alert protocol
+ * 2 bytes needed (AlertLevel, AlertDescription)
+ * Handshake protocol
+ * 4 bytes needed (HandshakeType, uint24 length) -- we just have
+ * to detect unexpected Client Hello and Hello Request messages
+ * here, anything else is handled by higher layers
+ * Application data protocol
+ * none of our business
+ */
+int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
+ {
+ int al,i,j,ret;
+ unsigned int n;
+ SSL3_RECORD *rr;
+ void (*cb)(const SSL *ssl,int type2,int val)=NULL;
+
+ if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
+ if (!ssl3_setup_buffers(s))
+ return(-1);
+
+ /* XXX: check what the second '&& type' is about */
+ if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
+ (type != SSL3_RT_HANDSHAKE) && type) ||
+ (peek && (type != SSL3_RT_APPLICATION_DATA)))
+ {
+ SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ /* check whether there's a handshake message (client hello?) waiting */
+ if ( (ret = have_handshake_fragment(s, type, buf, len, peek)))
+ return ret;
+
+ /* Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */
+
+ if (!s->in_handshake && SSL_in_init(s))
+ {
+ /* type == SSL3_RT_APPLICATION_DATA */
+ i=s->handshake_func(s);
+ if (i < 0) return(i);
+ if (i == 0)
+ {
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+ return(-1);
+ }
+ }
+
+start:
+ s->rwstate=SSL_NOTHING;
+
+ /* s->s3->rrec.type - is the type of record
+ * s->s3->rrec.data, - data
+ * s->s3->rrec.off, - offset into 'data' for next read
+ * s->s3->rrec.length, - number of bytes. */
+ rr = &(s->s3->rrec);
+
+ /* We are not handshaking and have no data yet,
+ * so process data buffered during the last handshake
+ * in advance, if any.
+ */
+ if (s->state == SSL_ST_OK && rr->length == 0)
+ {
+ pitem *item;
+ item = pqueue_pop(s->d1->buffered_app_data.q);
+ if (item)
+ {
+ dtls1_copy_record(s, item);
+
+ OPENSSL_free(item->data);
+ pitem_free(item);
+ }
+ }
+
+ /* Check for timeout */
+ if (dtls1_handle_timeout(s) > 0)
+ goto start;
+
+ /* get new packet if necessary */
+ if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
+ {
+ ret=dtls1_get_record(s);
+ if (ret <= 0)
+ {
+ ret = dtls1_read_failed(s, ret);
+ /* anything other than a timeout is an error */
+ if (ret <= 0)
+ return(ret);
+ else
+ goto start;
+ }
+ }
+
+ /* we now have a packet which can be read and processed */
+
+ if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
+ * reset by ssl3_get_finished */
+ && (rr->type != SSL3_RT_HANDSHAKE))
+ {
+ /* We now have application data between CCS and Finished.
+ * Most likely the packets were reordered on their way, so
+ * buffer the application data for later processing rather
+ * than dropping the connection.
+ */
+ dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num);
+ rr->length = 0;
+ goto start;
+ }
+
+ /* If the other end has shut down, throw anything we read away
+ * (even in 'peek' mode) */
+ if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
+ {
+ rr->length=0;
+ s->rwstate=SSL_NOTHING;
+ return(0);
+ }
+
+
+ if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
+ {
+ /* make sure that we are not getting application data when we
+ * are doing a handshake for the first time */
+ if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
+ (s->enc_read_ctx == NULL))
+ {
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE);
+ goto f_err;
+ }
+
+ if (len <= 0) return(len);
+
+ if ((unsigned int)len > rr->length)
+ n = rr->length;
+ else
+ n = (unsigned int)len;
+
+ memcpy(buf,&(rr->data[rr->off]),n);
+ if (!peek)
+ {
+ rr->length-=n;
+ rr->off+=n;
+ if (rr->length == 0)
+ {
+ s->rstate=SSL_ST_READ_HEADER;
+ rr->off=0;
+ }
+ }
+ return(n);
+ }
+
+
+ /* If we get here, then type != rr->type; if we have a handshake
+ * message, then it was unexpected (Hello Request or Client Hello). */
+
+ /* In case of record types for which we have 'fragment' storage,
+ * fill that so that we can process the data at a fixed place.
+ */
+ {
+ unsigned int k, dest_maxlen = 0;
+ unsigned char *dest = NULL;
+ unsigned int *dest_len = NULL;
+
+ if (rr->type == SSL3_RT_HANDSHAKE)
+ {
+ dest_maxlen = sizeof s->d1->handshake_fragment;
+ dest = s->d1->handshake_fragment;
+ dest_len = &s->d1->handshake_fragment_len;
+ }
+ else if (rr->type == SSL3_RT_ALERT)
+ {
+ dest_maxlen = sizeof(s->d1->alert_fragment);
+ dest = s->d1->alert_fragment;
+ dest_len = &s->d1->alert_fragment_len;
+ }
+ /* else it's a CCS message, or application data or wrong */
+ else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC)
+ {
+ /* Application data while renegotiating
+ * is allowed. Try again reading.
+ */
+ if (rr->type == SSL3_RT_APPLICATION_DATA)
+ {
+ BIO *bio;
+ s->s3->in_read_app_data=2;
+ bio=SSL_get_rbio(s);
+ s->rwstate=SSL_READING;
+ BIO_clear_retry_flags(bio);
+ BIO_set_retry_read(bio);
+ return(-1);
+ }
+
+ /* Not certain if this is the right error handling */
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
+ goto f_err;
+ }
+
+ if (dest_maxlen > 0)
+ {
+ /* XDTLS: In a pathalogical case, the Client Hello
+ * may be fragmented--don't always expect dest_maxlen bytes */
+ if ( rr->length < dest_maxlen)
+ {
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+ /*
+ * for normal alerts rr->length is 2, while
+ * dest_maxlen is 7 if we were to handle this
+ * non-existing alert...
+ */
+ FIX ME
+#endif
+ s->rstate=SSL_ST_READ_HEADER;
+ rr->length = 0;
+ goto start;
+ }
+
+ /* now move 'n' bytes: */
+ for ( k = 0; k < dest_maxlen; k++)
+ {
+ dest[k] = rr->data[rr->off++];
+ rr->length--;
+ }
+ *dest_len = dest_maxlen;
+ }
+ }
+
+ /* s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE;
+ * s->d1->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT.
+ * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */
+
+ /* If we are a client, check for an incoming 'Hello Request': */
+ if ((!s->server) &&
+ (s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
+ (s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
+ (s->session != NULL) && (s->session->cipher != NULL))
+ {
+ s->d1->handshake_fragment_len = 0;
+
+ if ((s->d1->handshake_fragment[1] != 0) ||
+ (s->d1->handshake_fragment[2] != 0) ||
+ (s->d1->handshake_fragment[3] != 0))
+ {
+ al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
+ goto err;
+ }
+
+ /* no need to check sequence number on HELLO REQUEST messages */
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
+ s->d1->handshake_fragment, 4, s, s->msg_callback_arg);
+
+ if (SSL_is_init_finished(s) &&
+ !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
+ !s->s3->renegotiate)
+ {
+ ssl3_renegotiate(s);
+ if (ssl3_renegotiate_check(s))
+ {
+ i=s->handshake_func(s);
+ if (i < 0) return(i);
+ if (i == 0)
+ {
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+ return(-1);
+ }
+
+ if (!(s->mode & SSL_MODE_AUTO_RETRY))
+ {
+ if (s->s3->rbuf.left == 0) /* no read-ahead left? */
+ {
+ BIO *bio;
+ /* In the case where we try to read application data,
+ * but we trigger an SSL handshake, we return -1 with
+ * the retry option set. Otherwise renegotiation may
+ * cause nasty problems in the blocking world */
+ s->rwstate=SSL_READING;
+ bio=SSL_get_rbio(s);
+ BIO_clear_retry_flags(bio);
+ BIO_set_retry_read(bio);
+ return(-1);
+ }
+ }
+ }
+ }
+ /* we either finished a handshake or ignored the request,
+ * now try again to obtain the (application) data we were asked for */
+ goto start;
+ }
+
+ if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH)
+ {
+ int alert_level = s->d1->alert_fragment[0];
+ int alert_descr = s->d1->alert_fragment[1];
+
+ s->d1->alert_fragment_len = 0;
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_ALERT,
+ s->d1->alert_fragment, 2, s, s->msg_callback_arg);
+
+ if (s->info_callback != NULL)
+ cb=s->info_callback;
+ else if (s->ctx->info_callback != NULL)
+ cb=s->ctx->info_callback;
+
+ if (cb != NULL)
+ {
+ j = (alert_level << 8) | alert_descr;
+ cb(s, SSL_CB_READ_ALERT, j);
+ }
+
+ if (alert_level == 1) /* warning */
+ {
+ s->s3->warn_alert = alert_descr;
+ if (alert_descr == SSL_AD_CLOSE_NOTIFY)
+ {
+ s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+ return(0);
+ }
+#if 0
+ /* XXX: this is a possible improvement in the future */
+ /* now check if it's a missing record */
+ if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
+ {
+ unsigned short seq;
+ unsigned int frag_off;
+ unsigned char *p = &(s->d1->alert_fragment[2]);
+
+ n2s(p, seq);
+ n2l3(p, frag_off);
+
+ dtls1_retransmit_message(s,
+ dtls1_get_queue_priority(frag->msg_header.seq, 0),
+ frag_off, &found);
+ if ( ! found && SSL_in_init(s))
+ {
+ /* fprintf( stderr,"in init = %d\n", SSL_in_init(s)); */
+ /* requested a message not yet sent,
+ send an alert ourselves */
+ ssl3_send_alert(s,SSL3_AL_WARNING,
+ DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
+ }
+ }
+#endif
+ }
+ else if (alert_level == 2) /* fatal */
+ {
+ char tmp[16];
+
+ s->rwstate=SSL_NOTHING;
+ s->s3->fatal_alert = alert_descr;
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
+ BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr);
+ ERR_add_error_data(2,"SSL alert number ",tmp);
+ s->shutdown|=SSL_RECEIVED_SHUTDOWN;
+ SSL_CTX_remove_session(s->ctx,s->session);
+ return(0);
+ }
+ else
+ {
+ al=SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);
+ goto f_err;
+ }
+
+ goto start;
+ }
+
+ if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */
+ {
+ s->rwstate=SSL_NOTHING;
+ rr->length=0;
+ return(0);
+ }
+
+ if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
+ {
+ struct ccs_header_st ccs_hdr;
+ unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH;
+
+ dtls1_get_ccs_header(rr->data, &ccs_hdr);
+
+ if (s->version == DTLS1_BAD_VER)
+ ccs_hdr_len = 3;
+
+ /* 'Change Cipher Spec' is just a single byte, so we know
+ * exactly what the record payload has to look like */
+ /* XDTLS: check that epoch is consistent */
+ if ( (rr->length != ccs_hdr_len) ||
+ (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
+ {
+ i=SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
+ goto err;
+ }
+
+ rr->length=0;
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
+ rr->data, 1, s, s->msg_callback_arg);
+
+ /* We can't process a CCS now, because previous handshake
+ * messages are still missing, so just drop it.
+ */
+ if (!s->d1->change_cipher_spec_ok)
+ {
+ goto start;
+ }
+
+ s->d1->change_cipher_spec_ok = 0;
+
+ s->s3->change_cipher_spec=1;
+ if (!ssl3_do_change_cipher_spec(s))
+ goto err;
+
+ /* do this whenever CCS is processed */
+ dtls1_reset_seq_numbers(s, SSL3_CC_READ);
+
+ if (s->version == DTLS1_BAD_VER)
+ s->d1->handshake_read_seq++;
+
+ goto start;
+ }
+
+ /* Unexpected handshake message (Client Hello, or protocol violation) */
+ if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
+ !s->in_handshake)
+ {
+ struct hm_header_st msg_hdr;
+
+ /* this may just be a stale retransmit */
+ dtls1_get_message_header(rr->data, &msg_hdr);
+ if( rr->epoch != s->d1->r_epoch)
+ {
+ rr->length = 0;
+ goto start;
+ }
+
+ /* If we are server, we may have a repeated FINISHED of the
+ * client here, then retransmit our CCS and FINISHED.
+ */
+ if (msg_hdr.type == SSL3_MT_FINISHED)
+ {
+ dtls1_retransmit_buffered_messages(s);
+ rr->length = 0;
+ goto start;
+ }
+
+ if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
+ !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
+ {
+#if 0 /* worked only because C operator preferences are not as expected (and
+ * because this is not really needed for clients except for detecting
+ * protocol violations): */
+ s->state=SSL_ST_BEFORE|(s->server)
+ ?SSL_ST_ACCEPT
+ :SSL_ST_CONNECT;
+#else
+ s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
+#endif
+ s->new_session=1;
+ }
+ i=s->handshake_func(s);
+ if (i < 0) return(i);
+ if (i == 0)
+ {
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+ return(-1);
+ }
+
+ if (!(s->mode & SSL_MODE_AUTO_RETRY))
+ {
+ if (s->s3->rbuf.left == 0) /* no read-ahead left? */
+ {
+ BIO *bio;
+ /* In the case where we try to read application data,
+ * but we trigger an SSL handshake, we return -1 with
+ * the retry option set. Otherwise renegotiation may
+ * cause nasty problems in the blocking world */
+ s->rwstate=SSL_READING;
+ bio=SSL_get_rbio(s);
+ BIO_clear_retry_flags(bio);
+ BIO_set_retry_read(bio);
+ return(-1);
+ }
+ }
+ goto start;
+ }
+
+ switch (rr->type)
+ {
+ default:
+#ifndef OPENSSL_NO_TLS
+ /* TLS just ignores unknown message types */
+ if (s->version == TLS1_VERSION)
+ {
+ rr->length = 0;
+ goto start;
+ }
+#endif
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
+ goto f_err;
+ case SSL3_RT_CHANGE_CIPHER_SPEC:
+ case SSL3_RT_ALERT:
+ case SSL3_RT_HANDSHAKE:
+ /* we already handled all of these, with the possible exception
+ * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that
+ * should not happen when type != rr->type */
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES,ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ case SSL3_RT_APPLICATION_DATA:
+ /* At this point, we were expecting handshake data,
+ * but have application data. If the library was
+ * running inside ssl3_read() (i.e. in_read_app_data
+ * is set) and it makes sense to read application data
+ * at this point (session renegotiation not yet started),
+ * we will indulge it.
+ */
+ if (s->s3->in_read_app_data &&
+ (s->s3->total_renegotiations != 0) &&
+ ((
+ (s->state & SSL_ST_CONNECT) &&
+ (s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
+ (s->state <= SSL3_ST_CR_SRVR_HELLO_A)
+ ) || (
+ (s->state & SSL_ST_ACCEPT) &&
+ (s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
+ (s->state >= SSL3_ST_SR_CLNT_HELLO_A)
+ )
+ ))
+ {
+ s->s3->in_read_app_data=2;
+ return(-1);
+ }
+ else
+ {
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
+ goto f_err;
+ }
+ }
+ /* not reached */
+
+f_err:
+ ssl3_send_alert(s,SSL3_AL_FATAL,al);
+err:
+ return(-1);
+ }
+
+int
+dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
+ {
+ int i;
+
+ if (SSL_in_init(s) && !s->in_handshake)
+ {
+ i=s->handshake_func(s);
+ if (i < 0) return(i);
+ if (i == 0)
+ {
+ SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
+ return -1;
+ }
+ }
+
+ if (len > SSL3_RT_MAX_PLAIN_LENGTH)
+ {
+ SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_DTLS_MESSAGE_TOO_BIG);
+ return -1;
+ }
+
+ i = dtls1_write_bytes(s, type, buf_, len);
+ return i;
+ }
+
+
+ /* this only happens when a client hello is received and a handshake
+ * is started. */
+static int
+have_handshake_fragment(SSL *s, int type, unsigned char *buf,
+ int len, int peek)
+ {
+
+ if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0))
+ /* (partially) satisfy request from storage */
+ {
+ unsigned char *src = s->d1->handshake_fragment;
+ unsigned char *dst = buf;
+ unsigned int k,n;
+
+ /* peek == 0 */
+ n = 0;
+ while ((len > 0) && (s->d1->handshake_fragment_len > 0))
+ {
+ *dst++ = *src++;
+ len--; s->d1->handshake_fragment_len--;
+ n++;
+ }
+ /* move any remaining fragment bytes: */
+ for (k = 0; k < s->d1->handshake_fragment_len; k++)
+ s->d1->handshake_fragment[k] = *src++;
+ return n;
+ }
+
+ return 0;
+ }
+
+
+
+
+/* Call this to write data in records of type 'type'
+ * It will return <= 0 if not all data has been sent or non-blocking IO.
+ */
+int dtls1_write_bytes(SSL *s, int type, const void *buf, int len)
+ {
+ int i;
+
+ OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
+ s->rwstate=SSL_NOTHING;
+ i=do_dtls1_write(s, type, buf, len, 0);
+ return i;
+ }
+
+int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment)
+ {
+ unsigned char *p,*pseq;
+ int i,mac_size,clear=0;
+ int prefix_len = 0;
+ SSL3_RECORD *wr;
+ SSL3_BUFFER *wb;
+ SSL_SESSION *sess;
+ int bs;
+
+ /* first check if there is a SSL3_BUFFER still being written
+ * out. This will happen with non blocking IO */
+ if (s->s3->wbuf.left != 0)
+ {
+ OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */
+ return(ssl3_write_pending(s,type,buf,len));
+ }
+
+ /* If we have an alert to send, lets send it */
+ if (s->s3->alert_dispatch)
+ {
+ i=s->method->ssl_dispatch_alert(s);
+ if (i <= 0)
+ return(i);
+ /* if it went, fall through and send more stuff */
+ }
+
+ if (len == 0 && !create_empty_fragment)
+ return 0;
+
+ wr= &(s->s3->wrec);
+ wb= &(s->s3->wbuf);
+ sess=s->session;
+
+ if ( (sess == NULL) ||
+ (s->enc_write_ctx == NULL) ||
+ (EVP_MD_CTX_md(s->write_hash) == NULL))
+ clear=1;
+
+ if (clear)
+ mac_size=0;
+ else
+ {
+ mac_size=EVP_MD_CTX_size(s->write_hash);
+ if (mac_size < 0)
+ goto err;
+ }
+
+ /* DTLS implements explicit IV, so no need for empty fragments */
+#if 0
+ /* 'create_empty_fragment' is true only when this function calls itself */
+ if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done
+ && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
+ {
+ /* countermeasure against known-IV weakness in CBC ciphersuites
+ * (see http://www.openssl.org/~bodo/tls-cbc.txt)
+ */
+
+ if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)
+ {
+ /* recursive function call with 'create_empty_fragment' set;
+ * this prepares and buffers the data for an empty fragment
+ * (these 'prefix_len' bytes are sent out later
+ * together with the actual payload) */
+ prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1);
+ if (prefix_len <= 0)
+ goto err;
+
+ if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)
+ {
+ /* insufficient space */
+ SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ s->s3->empty_fragment_done = 1;
+ }
+#endif
+ p = wb->buf + prefix_len;
+
+ /* write the header */
+
+ *(p++)=type&0xff;
+ wr->type=type;
+
+ *(p++)=(s->version>>8);
+ *(p++)=s->version&0xff;
+
+ /* field where we are to write out packet epoch, seq num and len */
+ pseq=p;
+ p+=10;
+
+ /* lets setup the record stuff. */
+
+ /* Make space for the explicit IV in case of CBC.
+ * (this is a bit of a boundary violation, but what the heck).
+ */
+ if ( s->enc_write_ctx &&
+ (EVP_CIPHER_mode( s->enc_write_ctx->cipher ) & EVP_CIPH_CBC_MODE))
+ bs = EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
+ else
+ bs = 0;
+
+ wr->data=p + bs; /* make room for IV in case of CBC */
+ wr->length=(int)len;
+ wr->input=(unsigned char *)buf;
+
+ /* we now 'read' from wr->input, wr->length bytes into
+ * wr->data */
+
+ /* first we compress */
+ if (s->compress != NULL)
+ {
+ if (!ssl3_do_compress(s))
+ {
+ SSLerr(SSL_F_DO_DTLS1_WRITE,SSL_R_COMPRESSION_FAILURE);
+ goto err;
+ }
+ }
+ else
+ {
+ memcpy(wr->data,wr->input,wr->length);
+ wr->input=wr->data;
+ }
+
+ /* we should still have the output to wr->data and the input
+ * from wr->input. Length should be wr->length.
+ * wr->data still points in the wb->buf */
+
+ if (mac_size != 0)
+ {
+ if(s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1) < 0)
+ goto err;
+ wr->length+=mac_size;
+ }
+
+ /* this is true regardless of mac size */
+ wr->input=p;
+ wr->data=p;
+
+
+ /* ssl3_enc can only have an error on read */
+ if (bs) /* bs != 0 in case of CBC */
+ {
+ RAND_pseudo_bytes(p,bs);
+ /* master IV and last CBC residue stand for
+ * the rest of randomness */
+ wr->length += bs;
+ }
+
+ s->method->ssl3_enc->enc(s,1);
+
+ /* record length after mac and block padding */
+/* if (type == SSL3_RT_APPLICATION_DATA ||
+ (type == SSL3_RT_ALERT && ! SSL_in_init(s))) */
+
+ /* there's only one epoch between handshake and app data */
+
+ s2n(s->d1->w_epoch, pseq);
+
+ /* XDTLS: ?? */
+/* else
+ s2n(s->d1->handshake_epoch, pseq); */
+
+ memcpy(pseq, &(s->s3->write_sequence[2]), 6);
+ pseq+=6;
+ s2n(wr->length,pseq);
+
+ /* we should now have
+ * wr->data pointing to the encrypted data, which is
+ * wr->length long */
+ wr->type=type; /* not needed but helps for debugging */
+ wr->length+=DTLS1_RT_HEADER_LENGTH;
+
+#if 0 /* this is now done at the message layer */
+ /* buffer the record, making it easy to handle retransmits */
+ if ( type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC)
+ dtls1_buffer_record(s, wr->data, wr->length,
+ *((PQ_64BIT *)&(s->s3->write_sequence[0])));
+#endif
+
+ ssl3_record_sequence_update(&(s->s3->write_sequence[0]));
+
+ if (create_empty_fragment)
+ {
+ /* we are in a recursive call;
+ * just return the length, don't write out anything here
+ */
+ return wr->length;
+ }
+
+ /* now let's set up wb */
+ wb->left = prefix_len + wr->length;
+ wb->offset = 0;
+
+ /* memorize arguments so that ssl3_write_pending can detect bad write retries later */
+ s->s3->wpend_tot=len;
+ s->s3->wpend_buf=buf;
+ s->s3->wpend_type=type;
+ s->s3->wpend_ret=len;
+
+ /* we now just need to write the buffer */
+ return ssl3_write_pending(s,type,buf,len);
+err:
+ return -1;
+ }
+
+
+
+static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
+ {
+ int cmp;
+ unsigned int shift;
+ const unsigned char *seq = s->s3->read_sequence;
+
+ cmp = satsub64be(seq,bitmap->max_seq_num);
+ if (cmp > 0)
+ {
+ memcpy (s->s3->rrec.seq_num,seq,8);
+ return 1; /* this record in new */
+ }
+ shift = -cmp;
+ if (shift >= sizeof(bitmap->map)*8)
+ return 0; /* stale, outside the window */
+ else if (bitmap->map & (1UL<<shift))
+ return 0; /* record previously received */
+
+ memcpy (s->s3->rrec.seq_num,seq,8);
+ return 1;
+ }
+
+
+static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
+ {
+ int cmp;
+ unsigned int shift;
+ const unsigned char *seq = s->s3->read_sequence;
+
+ cmp = satsub64be(seq,bitmap->max_seq_num);
+ if (cmp > 0)
+ {
+ shift = cmp;
+ if (shift < sizeof(bitmap->map)*8)
+ bitmap->map <<= shift, bitmap->map |= 1UL;
+ else
+ bitmap->map = 1UL;
+ memcpy(bitmap->max_seq_num,seq,8);
+ }
+ else {
+ shift = -cmp;
+ if (shift < sizeof(bitmap->map)*8)
+ bitmap->map |= 1UL<<shift;
+ }
+ }
+
+
+int dtls1_dispatch_alert(SSL *s)
+ {
+ int i,j;
+ void (*cb)(const SSL *ssl,int type,int val)=NULL;
+ unsigned char buf[DTLS1_AL_HEADER_LENGTH];
+ unsigned char *ptr = &buf[0];
+
+ s->s3->alert_dispatch=0;
+
+ memset(buf, 0x00, sizeof(buf));
+ *ptr++ = s->s3->send_alert[0];
+ *ptr++ = s->s3->send_alert[1];
+
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+ if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
+ {
+ s2n(s->d1->handshake_read_seq, ptr);
+#if 0
+ if ( s->d1->r_msg_hdr.frag_off == 0) /* waiting for a new msg */
+
+ else
+ s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */
+#endif
+
+#if 0
+ fprintf(stderr, "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n",s->d1->handshake_read_seq,s->d1->r_msg_hdr.seq);
+#endif
+ l2n3(s->d1->r_msg_hdr.frag_off, ptr);
+ }
+#endif
+
+ i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
+ if (i <= 0)
+ {
+ s->s3->alert_dispatch=1;
+ /* fprintf( stderr, "not done with alert\n" ); */
+ }
+ else
+ {
+ if (s->s3->send_alert[0] == SSL3_AL_FATAL
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+ || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+#endif
+ )
+ (void)BIO_flush(s->wbio);
+
+ if (s->msg_callback)
+ s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert,
+ 2, s, s->msg_callback_arg);
+
+ if (s->info_callback != NULL)
+ cb=s->info_callback;
+ else if (s->ctx->info_callback != NULL)
+ cb=s->ctx->info_callback;
+
+ if (cb != NULL)
+ {
+ j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1];
+ cb(s,SSL_CB_WRITE_ALERT,j);
+ }
+ }
+ return(i);
+ }
+
+
+static DTLS1_BITMAP *
+dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch)
+ {
+
+ *is_next_epoch = 0;
+
+ /* In current epoch, accept HM, CCS, DATA, & ALERT */
+ if (rr->epoch == s->d1->r_epoch)
+ return &s->d1->bitmap;
+
+ /* Only HM and ALERT messages can be from the next epoch */
+ else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) &&
+ (rr->type == SSL3_RT_HANDSHAKE ||
+ rr->type == SSL3_RT_ALERT))
+ {
+ *is_next_epoch = 1;
+ return &s->d1->next_bitmap;
+ }
+
+ return NULL;
+ }
+
+#if 0
+static int
+dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, unsigned short *priority,
+ unsigned long *offset)
+ {
+
+ /* alerts are passed up immediately */
+ if ( rr->type == SSL3_RT_APPLICATION_DATA ||
+ rr->type == SSL3_RT_ALERT)
+ return 0;
+
+ /* Only need to buffer if a handshake is underway.
+ * (this implies that Hello Request and Client Hello are passed up
+ * immediately) */
+ if ( SSL_in_init(s))
+ {
+ unsigned char *data = rr->data;
+ /* need to extract the HM/CCS sequence number here */
+ if ( rr->type == SSL3_RT_HANDSHAKE ||
+ rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
+ {
+ unsigned short seq_num;
+ struct hm_header_st msg_hdr;
+ struct ccs_header_st ccs_hdr;
+
+ if ( rr->type == SSL3_RT_HANDSHAKE)
+ {
+ dtls1_get_message_header(data, &msg_hdr);
+ seq_num = msg_hdr.seq;
+ *offset = msg_hdr.frag_off;
+ }
+ else
+ {
+ dtls1_get_ccs_header(data, &ccs_hdr);
+ seq_num = ccs_hdr.seq;
+ *offset = 0;
+ }
+
+ /* this is either a record we're waiting for, or a
+ * retransmit of something we happened to previously
+ * receive (higher layers will drop the repeat silently */
+ if ( seq_num < s->d1->handshake_read_seq)
+ return 0;
+ if (rr->type == SSL3_RT_HANDSHAKE &&
+ seq_num == s->d1->handshake_read_seq &&
+ msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off)
+ return 0;
+ else if ( seq_num == s->d1->handshake_read_seq &&
+ (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC ||
+ msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off))
+ return 0;
+ else
+ {
+ *priority = seq_num;
+ return 1;
+ }
+ }
+ else /* unknown record type */
+ return 0;
+ }
+
+ return 0;
+ }
+#endif
+
+void
+dtls1_reset_seq_numbers(SSL *s, int rw)
+ {
+ unsigned char *seq;
+ unsigned int seq_bytes = sizeof(s->s3->read_sequence);
+
+ if ( rw & SSL3_CC_READ)
+ {
+ seq = s->s3->read_sequence;
+ s->d1->r_epoch++;
+ memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP));
+ memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
+ }
+ else
+ {
+ seq = s->s3->write_sequence;
+ memcpy(s->d1->last_write_sequence, seq, sizeof(s->s3->write_sequence));
+ s->d1->w_epoch++;
+ }
+
+ memset(seq, 0x00, seq_bytes);
+ }
+
+
+static void
+dtls1_clear_timeouts(SSL *s)
+ {
+ memset(&(s->d1->timeout), 0x00, sizeof(struct dtls1_timeout_st));
+ }
diff --git a/openssl/ssl/install.com b/openssl/ssl/install.com
index c79f76ef9..fe1d7268e 100644
--- a/openssl/ssl/install.com
+++ b/openssl/ssl/install.com
@@ -1,90 +1,90 @@
-$! INSTALL.COM -- Installs the files in a given directory tree
-$!
-$! Author: Richard Levitte <richard@levitte.org>
-$! Time of creation: 22-MAY-1998 10:13
-$!
-$! P1 root of the directory tree
-$!
-$ IF P1 .EQS. ""
-$ THEN
-$ WRITE SYS$OUTPUT "First argument missing."
-$ WRITE SYS$OUTPUT -
- "It should be the directory where you want things installed."
-$ EXIT
-$ ENDIF
-$
-$ IF (F$GETSYI("CPU").LT.128)
-$ THEN
-$ ARCH := VAX
-$ ELSE
-$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
-$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
-$ ENDIF
-$
-$ ROOT = F$PARSE(P1,"[]A.;0",,,"SYNTAX_ONLY,NO_CONCEAL") - "A.;0"
-$ ROOT_DEV = F$PARSE(ROOT,,,"DEVICE","SYNTAX_ONLY")
-$ ROOT_DIR = F$PARSE(ROOT,,,"DIRECTORY","SYNTAX_ONLY") -
- - "[000000." - "][" - "[" - "]"
-$ ROOT = ROOT_DEV + "[" + ROOT_DIR
-$
-$ DEFINE/NOLOG WRK_SSLROOT 'ROOT'.] /TRANS=CONC
-$ DEFINE/NOLOG WRK_SSLXLIB WRK_SSLROOT:['ARCH'_LIB]
-$ DEFINE/NOLOG WRK_SSLINCLUDE WRK_SSLROOT:[INCLUDE]
-$ DEFINE/NOLOG WRK_SSLXEXE WRK_SSLROOT:['ARCH'_EXE]
-$
-$ IF F$PARSE("WRK_SSLROOT:[000000]") .EQS. "" THEN -
- CREATE/DIR/LOG WRK_SSLROOT:[000000]
-$ IF F$PARSE("WRK_SSLXLIB:") .EQS. "" THEN -
- CREATE/DIR/LOG WRK_SSLXLIB:
-$ IF F$PARSE("WRK_SSLINCLUDE:") .EQS. "" THEN -
- CREATE/DIR/LOG WRK_SSLINCLUDE:
-$ IF F$PARSE("WRK_SSLXEXE:") .EQS. "" THEN -
- CREATE/DIR/LOG WRK_SSLXEXE:
-$
-$ EXHEADER := ssl.h,ssl2.h,ssl3.h,ssl23.h,tls1.h,dtls1.h,kssl.h
-$ E_EXE := ssl_task
-$ LIBS := LIBSSL,LIBSSL32
-$
-$ XEXE_DIR := [-.'ARCH'.EXE.SSL]
-$
-$ COPY 'EXHEADER' WRK_SSLINCLUDE:/LOG
-$ SET FILE/PROT=WORLD:RE WRK_SSLINCLUDE:'EXHEADER'
-$
-$ I = 0
-$ LOOP_EXE:
-$ E = F$EDIT(F$ELEMENT(I, ",", E_EXE),"TRIM")
-$ I = I + 1
-$ IF E .EQS. "," THEN GOTO LOOP_EXE_END
-$ SET NOON
-$ IF F$SEARCH(XEXE_DIR+E+".EXE") .NES. ""
-$ THEN
-$ COPY 'XEXE_DIR''E'.EXE WRK_SSLXEXE:'E'.EXE/log
-$ SET FILE/PROT=W:RE WRK_SSLXEXE:'E'.EXE
-$ ENDIF
-$ SET ON
-$ GOTO LOOP_EXE
-$ LOOP_EXE_END:
-$
-$ I = 0
-$ LOOP_LIB:
-$ E = F$EDIT(F$ELEMENT(I, ",", LIBS),"TRIM")
-$ I = I + 1
-$ IF E .EQS. "," THEN GOTO LOOP_LIB_END
-$ SET NOON
-$! Object library.
-$ IF F$SEARCH(XEXE_DIR+E+".OLB") .NES. ""
-$ THEN
-$ COPY 'XEXE_DIR''E'.OLB WRK_SSLXLIB:'E'.OLB/log
-$ SET FILE/PROT=W:RE WRK_SSLXLIB:'E'.OLB
-$ ENDIF
-$! Shareable image.
-$ IF F$SEARCH(XEXE_DIR+E+".EXE") .NES. ""
-$ THEN
-$ COPY 'XEXE_DIR''E'.EXE WRK_SSLXLIB:'E'.EXE/log
-$ SET FILE/PROT=W:RE WRK_SSLXLIB:'E'.EXE
-$ ENDIF
-$ SET ON
-$ GOTO LOOP_LIB
-$ LOOP_LIB_END:
-$
-$ EXIT
+$! INSTALL.COM -- Installs the files in a given directory tree
+$!
+$! Author: Richard Levitte <richard@levitte.org>
+$! Time of creation: 22-MAY-1998 10:13
+$!
+$! P1 root of the directory tree
+$!
+$ IF P1 .EQS. ""
+$ THEN
+$ WRITE SYS$OUTPUT "First argument missing."
+$ WRITE SYS$OUTPUT -
+ "It should be the directory where you want things installed."
+$ EXIT
+$ ENDIF
+$
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$ ARCH := VAX
+$ ELSE
+$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$ ENDIF
+$
+$ ROOT = F$PARSE(P1,"[]A.;0",,,"SYNTAX_ONLY,NO_CONCEAL") - "A.;0"
+$ ROOT_DEV = F$PARSE(ROOT,,,"DEVICE","SYNTAX_ONLY")
+$ ROOT_DIR = F$PARSE(ROOT,,,"DIRECTORY","SYNTAX_ONLY") -
+ - "[000000." - "][" - "[" - "]"
+$ ROOT = ROOT_DEV + "[" + ROOT_DIR
+$
+$ DEFINE/NOLOG WRK_SSLROOT 'ROOT'.] /TRANS=CONC
+$ DEFINE/NOLOG WRK_SSLXLIB WRK_SSLROOT:['ARCH'_LIB]
+$ DEFINE/NOLOG WRK_SSLINCLUDE WRK_SSLROOT:[INCLUDE]
+$ DEFINE/NOLOG WRK_SSLXEXE WRK_SSLROOT:['ARCH'_EXE]
+$
+$ IF F$PARSE("WRK_SSLROOT:[000000]") .EQS. "" THEN -
+ CREATE/DIR/LOG WRK_SSLROOT:[000000]
+$ IF F$PARSE("WRK_SSLXLIB:") .EQS. "" THEN -
+ CREATE/DIR/LOG WRK_SSLXLIB:
+$ IF F$PARSE("WRK_SSLINCLUDE:") .EQS. "" THEN -
+ CREATE/DIR/LOG WRK_SSLINCLUDE:
+$ IF F$PARSE("WRK_SSLXEXE:") .EQS. "" THEN -
+ CREATE/DIR/LOG WRK_SSLXEXE:
+$
+$ EXHEADER := ssl.h,ssl2.h,ssl3.h,ssl23.h,tls1.h,dtls1.h,kssl.h
+$ E_EXE := ssl_task
+$ LIBS := LIBSSL,LIBSSL32
+$
+$ XEXE_DIR := [-.'ARCH'.EXE.SSL]
+$
+$ COPY 'EXHEADER' WRK_SSLINCLUDE:/LOG
+$ SET FILE/PROT=WORLD:RE WRK_SSLINCLUDE:'EXHEADER'
+$
+$ I = 0
+$ LOOP_EXE:
+$ E = F$EDIT(F$ELEMENT(I, ",", E_EXE),"TRIM")
+$ I = I + 1
+$ IF E .EQS. "," THEN GOTO LOOP_EXE_END
+$ SET NOON
+$ IF F$SEARCH(XEXE_DIR+E+".EXE") .NES. ""
+$ THEN
+$ COPY 'XEXE_DIR''E'.EXE WRK_SSLXEXE:'E'.EXE/log
+$ SET FILE/PROT=W:RE WRK_SSLXEXE:'E'.EXE
+$ ENDIF
+$ SET ON
+$ GOTO LOOP_EXE
+$ LOOP_EXE_END:
+$
+$ I = 0
+$ LOOP_LIB:
+$ E = F$EDIT(F$ELEMENT(I, ",", LIBS),"TRIM")
+$ I = I + 1
+$ IF E .EQS. "," THEN GOTO LOOP_LIB_END
+$ SET NOON
+$! Object library.
+$ IF F$SEARCH(XEXE_DIR+E+".OLB") .NES. ""
+$ THEN
+$ COPY 'XEXE_DIR''E'.OLB WRK_SSLXLIB:'E'.OLB/log
+$ SET FILE/PROT=W:RE WRK_SSLXLIB:'E'.OLB
+$ ENDIF
+$! Shareable image.
+$ IF F$SEARCH(XEXE_DIR+E+".EXE") .NES. ""
+$ THEN
+$ COPY 'XEXE_DIR''E'.EXE WRK_SSLXLIB:'E'.EXE/log
+$ SET FILE/PROT=W:RE WRK_SSLXLIB:'E'.EXE
+$ ENDIF
+$ SET ON
+$ GOTO LOOP_LIB
+$ LOOP_LIB_END:
+$
+$ EXIT
diff --git a/openssl/ssl/s2_srvr.c b/openssl/ssl/s2_srvr.c
index 6643c787c..bc885e8e7 100644
--- a/openssl/ssl/s2_srvr.c
+++ b/openssl/ssl/s2_srvr.c
@@ -1,1142 +1,1142 @@
-/* ssl/s2_srvr.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-/* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include "ssl_locl.h"
-#ifndef OPENSSL_NO_SSL2
-#include <stdio.h>
-#include <openssl/bio.h>
-#include <openssl/rand.h>
-#include <openssl/objects.h>
-#include <openssl/evp.h>
-
-static const SSL_METHOD *ssl2_get_server_method(int ver);
-static int get_client_master_key(SSL *s);
-static int get_client_hello(SSL *s);
-static int server_hello(SSL *s);
-static int get_client_finished(SSL *s);
-static int server_verify(SSL *s);
-static int server_finish(SSL *s);
-static int request_certificate(SSL *s);
-static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
- unsigned char *to,int padding);
-#define BREAK break
-
-static const SSL_METHOD *ssl2_get_server_method(int ver)
- {
- if (ver == SSL2_VERSION)
- return(SSLv2_server_method());
- else
- return(NULL);
- }
-
-IMPLEMENT_ssl2_meth_func(SSLv2_server_method,
- ssl2_accept,
- ssl_undefined_function,
- ssl2_get_server_method)
-
-int ssl2_accept(SSL *s)
- {
- unsigned long l=(unsigned long)time(NULL);
- BUF_MEM *buf=NULL;
- int ret= -1;
- long num1;
- void (*cb)(const SSL *ssl,int type,int val)=NULL;
- int new_state,state;
-
- RAND_add(&l,sizeof(l),0);
- ERR_clear_error();
- clear_sys_error();
-
- if (s->info_callback != NULL)
- cb=s->info_callback;
- else if (s->ctx->info_callback != NULL)
- cb=s->ctx->info_callback;
-
- /* init things to blank */
- s->in_handshake++;
- if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
-
- if (s->cert == NULL)
- {
- SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
- return(-1);
- }
-
- clear_sys_error();
- for (;;)
- {
- state=s->state;
-
- switch (s->state)
- {
- case SSL_ST_BEFORE:
- case SSL_ST_ACCEPT:
- case SSL_ST_BEFORE|SSL_ST_ACCEPT:
- case SSL_ST_OK|SSL_ST_ACCEPT:
-
- s->server=1;
- if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
-
- s->version=SSL2_VERSION;
- s->type=SSL_ST_ACCEPT;
-
- buf=s->init_buf;
- if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
- { ret= -1; goto end; }
- if (!BUF_MEM_grow(buf,(int)
- SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
- { ret= -1; goto end; }
- s->init_buf=buf;
- s->init_num=0;
- s->ctx->stats.sess_accept++;
- s->handshake_func=ssl2_accept;
- s->state=SSL2_ST_GET_CLIENT_HELLO_A;
- BREAK;
-
- case SSL2_ST_GET_CLIENT_HELLO_A:
- case SSL2_ST_GET_CLIENT_HELLO_B:
- case SSL2_ST_GET_CLIENT_HELLO_C:
- s->shutdown=0;
- ret=get_client_hello(s);
- if (ret <= 0) goto end;
- s->init_num=0;
- s->state=SSL2_ST_SEND_SERVER_HELLO_A;
- BREAK;
-
- case SSL2_ST_SEND_SERVER_HELLO_A:
- case SSL2_ST_SEND_SERVER_HELLO_B:
- ret=server_hello(s);
- if (ret <= 0) goto end;
- s->init_num=0;
- if (!s->hit)
- {
- s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_A;
- BREAK;
- }
- else
- {
- s->state=SSL2_ST_SERVER_START_ENCRYPTION;
- BREAK;
- }
- case SSL2_ST_GET_CLIENT_MASTER_KEY_A:
- case SSL2_ST_GET_CLIENT_MASTER_KEY_B:
- ret=get_client_master_key(s);
- if (ret <= 0) goto end;
- s->init_num=0;
- s->state=SSL2_ST_SERVER_START_ENCRYPTION;
- BREAK;
-
- case SSL2_ST_SERVER_START_ENCRYPTION:
- /* Ok we how have sent all the stuff needed to
- * start encrypting, the next packet back will
- * be encrypted. */
- if (!ssl2_enc_init(s,0))
- { ret= -1; goto end; }
- s->s2->clear_text=0;
- s->state=SSL2_ST_SEND_SERVER_VERIFY_A;
- BREAK;
-
- case SSL2_ST_SEND_SERVER_VERIFY_A:
- case SSL2_ST_SEND_SERVER_VERIFY_B:
- ret=server_verify(s);
- if (ret <= 0) goto end;
- s->init_num=0;
- if (s->hit)
- {
- /* If we are in here, we have been
- * buffering the output, so we need to
- * flush it and remove buffering from
- * future traffic */
- s->state=SSL2_ST_SEND_SERVER_VERIFY_C;
- BREAK;
- }
- else
- {
- s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
- break;
- }
-
- case SSL2_ST_SEND_SERVER_VERIFY_C:
- /* get the number of bytes to write */
- num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
- if (num1 > 0)
- {
- s->rwstate=SSL_WRITING;
- num1=BIO_flush(s->wbio);
- if (num1 <= 0) { ret= -1; goto end; }
- s->rwstate=SSL_NOTHING;
- }
-
- /* flushed and now remove buffering */
- s->wbio=BIO_pop(s->wbio);
-
- s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
- BREAK;
-
- case SSL2_ST_GET_CLIENT_FINISHED_A:
- case SSL2_ST_GET_CLIENT_FINISHED_B:
- ret=get_client_finished(s);
- if (ret <= 0)
- goto end;
- s->init_num=0;
- s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_A;
- BREAK;
-
- case SSL2_ST_SEND_REQUEST_CERTIFICATE_A:
- case SSL2_ST_SEND_REQUEST_CERTIFICATE_B:
- case SSL2_ST_SEND_REQUEST_CERTIFICATE_C:
- case SSL2_ST_SEND_REQUEST_CERTIFICATE_D:
- /* don't do a 'request certificate' if we
- * don't want to, or we already have one, and
- * we only want to do it once. */
- if (!(s->verify_mode & SSL_VERIFY_PEER) ||
- ((s->session->peer != NULL) &&
- (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)))
- {
- s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
- break;
- }
- else
- {
- ret=request_certificate(s);
- if (ret <= 0) goto end;
- s->init_num=0;
- s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
- }
- BREAK;
-
- case SSL2_ST_SEND_SERVER_FINISHED_A:
- case SSL2_ST_SEND_SERVER_FINISHED_B:
- ret=server_finish(s);
- if (ret <= 0) goto end;
- s->init_num=0;
- s->state=SSL_ST_OK;
- break;
-
- case SSL_ST_OK:
- BUF_MEM_free(s->init_buf);
- ssl_free_wbio_buffer(s);
- s->init_buf=NULL;
- s->init_num=0;
- /* ERR_clear_error();*/
-
- ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
-
- s->ctx->stats.sess_accept_good++;
- /* s->server=1; */
- ret=1;
-
- if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
-
- goto end;
- /* BREAK; */
-
- default:
- SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_UNKNOWN_STATE);
- ret= -1;
- goto end;
- /* BREAK; */
- }
-
- if ((cb != NULL) && (s->state != state))
- {
- new_state=s->state;
- s->state=state;
- cb(s,SSL_CB_ACCEPT_LOOP,1);
- s->state=new_state;
- }
- }
-end:
- s->in_handshake--;
- if (cb != NULL)
- cb(s,SSL_CB_ACCEPT_EXIT,ret);
- return(ret);
- }
-
-static int get_client_master_key(SSL *s)
- {
- int is_export,i,n,keya,ek;
- unsigned long len;
- unsigned char *p;
- const SSL_CIPHER *cp;
- const EVP_CIPHER *c;
- const EVP_MD *md;
-
- p=(unsigned char *)s->init_buf->data;
- if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A)
- {
- i=ssl2_read(s,(char *)&(p[s->init_num]),10-s->init_num);
-
- if (i < (10-s->init_num))
- return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
- s->init_num = 10;
-
- if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY)
- {
- if (p[-1] != SSL2_MT_ERROR)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_READ_WRONG_PACKET_TYPE);
- }
- else
- SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR);
- return(-1);
- }
-
- cp=ssl2_get_cipher_by_char(p);
- if (cp == NULL)
- {
- ssl2_return_error(s,SSL2_PE_NO_CIPHER);
- SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH);
- return(-1);
- }
- s->session->cipher= cp;
-
- p+=3;
- n2s(p,i); s->s2->tmp.clear=i;
- n2s(p,i); s->s2->tmp.enc=i;
- n2s(p,i);
- if(i > SSL_MAX_KEY_ARG_LENGTH)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG);
- return -1;
- }
- s->session->key_arg_length=i;
- s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B;
- }
-
- /* SSL2_ST_GET_CLIENT_MASTER_KEY_B */
- p=(unsigned char *)s->init_buf->data;
- if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
- return -1;
- }
- keya=s->session->key_arg_length;
- len = 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + (unsigned long)keya;
- if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_MESSAGE_TOO_LONG);
- return -1;
- }
- n = (int)len - s->init_num;
- i = ssl2_read(s,(char *)&(p[s->init_num]),n);
- if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
- if (s->msg_callback)
- s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-MASTER-KEY */
- p += 10;
-
- memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]),
- (unsigned int)keya);
-
- if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY);
- return(-1);
- }
- i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc,
- &(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]),
- (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
-
- is_export=SSL_C_IS_EXPORT(s->session->cipher);
-
- if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
- {
- ssl2_return_error(s,SSL2_PE_NO_CIPHER);
- SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
- return(0);
- }
-
- if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
- {
- is_export=1;
- ek=8;
- }
- else
- ek=5;
-
- /* bad decrypt */
-#if 1
- /* If a bad decrypt, continue with protocol but with a
- * random master secret (Bleichenbacher attack) */
- if ((i < 0) ||
- ((!is_export && (i != EVP_CIPHER_key_length(c)))
- || (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i !=
- (unsigned int)EVP_CIPHER_key_length(c))))))
- {
- ERR_clear_error();
- if (is_export)
- i=ek;
- else
- i=EVP_CIPHER_key_length(c);
- if (RAND_pseudo_bytes(p,i) <= 0)
- return 0;
- }
-#else
- if (i < 0)
- {
- error=1;
- SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_RSA_DECRYPT);
- }
- /* incorrect number of key bytes for non export cipher */
- else if ((!is_export && (i != EVP_CIPHER_key_length(c)))
- || (is_export && ((i != ek) || (s->s2->tmp.clear+i !=
- EVP_CIPHER_key_length(c)))))
- {
- error=1;
- SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_WRONG_NUMBER_OF_KEY_BITS);
- }
- if (error)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- return(-1);
- }
-#endif
-
- if (is_export) i+=s->s2->tmp.clear;
-
- if (i > SSL_MAX_MASTER_KEY_LENGTH)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
- return -1;
- }
- s->session->master_key_length=i;
- memcpy(s->session->master_key,p,(unsigned int)i);
- return(1);
- }
-
-static int get_client_hello(SSL *s)
- {
- int i,n;
- unsigned long len;
- unsigned char *p;
- STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */
- STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */
- STACK_OF(SSL_CIPHER) *prio, *allow;
- int z;
-
- /* This is a bit of a hack to check for the correct packet
- * type the first time round. */
- if (s->state == SSL2_ST_GET_CLIENT_HELLO_A)
- {
- s->first_packet=1;
- s->state=SSL2_ST_GET_CLIENT_HELLO_B;
- }
-
- p=(unsigned char *)s->init_buf->data;
- if (s->state == SSL2_ST_GET_CLIENT_HELLO_B)
- {
- i=ssl2_read(s,(char *)&(p[s->init_num]),9-s->init_num);
- if (i < (9-s->init_num))
- return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
- s->init_num = 9;
-
- if (*(p++) != SSL2_MT_CLIENT_HELLO)
- {
- if (p[-1] != SSL2_MT_ERROR)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_READ_WRONG_PACKET_TYPE);
- }
- else
- SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_PEER_ERROR);
- return(-1);
- }
- n2s(p,i);
- if (i < s->version) s->version=i;
- n2s(p,i); s->s2->tmp.cipher_spec_length=i;
- n2s(p,i); s->s2->tmp.session_id_length=i;
- n2s(p,i); s->s2->challenge_length=i;
- if ( (i < SSL2_MIN_CHALLENGE_LENGTH) ||
- (i > SSL2_MAX_CHALLENGE_LENGTH))
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_INVALID_CHALLENGE_LENGTH);
- return(-1);
- }
- s->state=SSL2_ST_GET_CLIENT_HELLO_C;
- }
-
- /* SSL2_ST_GET_CLIENT_HELLO_C */
- p=(unsigned char *)s->init_buf->data;
- len = 9 + (unsigned long)s->s2->tmp.cipher_spec_length + (unsigned long)s->s2->challenge_length + (unsigned long)s->s2->tmp.session_id_length;
- if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_MESSAGE_TOO_LONG);
- return -1;
- }
- n = (int)len - s->init_num;
- i = ssl2_read(s,(char *)&(p[s->init_num]),n);
- if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
- if (s->msg_callback)
- s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-HELLO */
- p += 9;
-
- /* get session-id before cipher stuff so we can get out session
- * structure if it is cached */
- /* session-id */
- if ((s->s2->tmp.session_id_length != 0) &&
- (s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH))
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_BAD_SSL_SESSION_ID_LENGTH);
- return(-1);
- }
-
- if (s->s2->tmp.session_id_length == 0)
- {
- if (!ssl_get_new_session(s,1))
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- return(-1);
- }
- }
- else
- {
- i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_spec_length]),
- s->s2->tmp.session_id_length, NULL);
- if (i == 1)
- { /* previous session */
- s->hit=1;
- }
- else if (i == -1)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- return(-1);
- }
- else
- {
- if (s->cert == NULL)
- {
- ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
- SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_NO_CERTIFICATE_SET);
- return(-1);
- }
-
- if (!ssl_get_new_session(s,1))
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- return(-1);
- }
- }
- }
-
- if (!s->hit)
- {
- cs=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.cipher_spec_length,
- &s->session->ciphers);
- if (cs == NULL) goto mem_err;
-
- cl=SSL_get_ciphers(s);
-
- if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
- {
- prio=sk_SSL_CIPHER_dup(cl);
- if (prio == NULL) goto mem_err;
- allow = cs;
- }
- else
- {
- prio = cs;
- allow = cl;
- }
- for (z=0; z<sk_SSL_CIPHER_num(prio); z++)
- {
- if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0)
- {
- (void)sk_SSL_CIPHER_delete(prio,z);
- z--;
- }
- }
- if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
- {
- sk_SSL_CIPHER_free(s->session->ciphers);
- s->session->ciphers = prio;
- }
- /* s->session->ciphers should now have a list of
- * ciphers that are on both the client and server.
- * This list is ordered by the order the client sent
- * the ciphers or in the order of the server's preference
- * if SSL_OP_CIPHER_SERVER_PREFERENCE was set.
- */
- }
- p+=s->s2->tmp.cipher_spec_length;
- /* done cipher selection */
-
- /* session id extracted already */
- p+=s->s2->tmp.session_id_length;
-
- /* challenge */
- if (s->s2->challenge_length > sizeof s->s2->challenge)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
- return -1;
- }
- memcpy(s->s2->challenge,p,(unsigned int)s->s2->challenge_length);
- return(1);
-mem_err:
- SSLerr(SSL_F_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE);
- return(0);
- }
-
-static int server_hello(SSL *s)
- {
- unsigned char *p,*d;
- int n,hit;
-
- p=(unsigned char *)s->init_buf->data;
- if (s->state == SSL2_ST_SEND_SERVER_HELLO_A)
- {
- d=p+11;
- *(p++)=SSL2_MT_SERVER_HELLO; /* type */
- hit=s->hit;
- *(p++)=(unsigned char)hit;
-#if 1
- if (!hit)
- {
- if (s->session->sess_cert != NULL)
- /* This can't really happen because get_client_hello
- * has called ssl_get_new_session, which does not set
- * sess_cert. */
- ssl_sess_cert_free(s->session->sess_cert);
- s->session->sess_cert = ssl_sess_cert_new();
- if (s->session->sess_cert == NULL)
- {
- SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE);
- return(-1);
- }
- }
- /* If 'hit' is set, then s->sess_cert may be non-NULL or NULL,
- * depending on whether it survived in the internal cache
- * or was retrieved from an external cache.
- * If it is NULL, we cannot put any useful data in it anyway,
- * so we don't touch it.
- */
-
-#else /* That's what used to be done when cert_st and sess_cert_st were
- * the same. */
- if (!hit)
- { /* else add cert to session */
- CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
- if (s->session->sess_cert != NULL)
- ssl_cert_free(s->session->sess_cert);
- s->session->sess_cert=s->cert;
- }
- else /* We have a session id-cache hit, if the
- * session-id has no certificate listed against
- * the 'cert' structure, grab the 'old' one
- * listed against the SSL connection */
- {
- if (s->session->sess_cert == NULL)
- {
- CRYPTO_add(&s->cert->references,1,
- CRYPTO_LOCK_SSL_CERT);
- s->session->sess_cert=s->cert;
- }
- }
-#endif
-
- if (s->cert == NULL)
- {
- ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
- SSLerr(SSL_F_SERVER_HELLO,SSL_R_NO_CERTIFICATE_SPECIFIED);
- return(-1);
- }
-
- if (hit)
- {
- *(p++)=0; /* no certificate type */
- s2n(s->version,p); /* version */
- s2n(0,p); /* cert len */
- s2n(0,p); /* ciphers len */
- }
- else
- {
- /* EAY EAY */
- /* put certificate type */
- *(p++)=SSL2_CT_X509_CERTIFICATE;
- s2n(s->version,p); /* version */
- n=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
- s2n(n,p); /* certificate length */
- i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&d);
- n=0;
-
- /* lets send out the ciphers we like in the
- * prefered order */
- n=ssl_cipher_list_to_bytes(s,s->session->ciphers,d,0);
- d+=n;
- s2n(n,p); /* add cipher length */
- }
-
- /* make and send conn_id */
- s2n(SSL2_CONNECTION_ID_LENGTH,p); /* add conn_id length */
- s->s2->conn_id_length=SSL2_CONNECTION_ID_LENGTH;
- if (RAND_pseudo_bytes(s->s2->conn_id,(int)s->s2->conn_id_length) <= 0)
- return -1;
- memcpy(d,s->s2->conn_id,SSL2_CONNECTION_ID_LENGTH);
- d+=SSL2_CONNECTION_ID_LENGTH;
-
- s->state=SSL2_ST_SEND_SERVER_HELLO_B;
- s->init_num=d-(unsigned char *)s->init_buf->data;
- s->init_off=0;
- }
- /* SSL2_ST_SEND_SERVER_HELLO_B */
- /* If we are using TCP/IP, the performance is bad if we do 2
- * writes without a read between them. This occurs when
- * Session-id reuse is used, so I will put in a buffering module
- */
- if (s->hit)
- {
- if (!ssl_init_wbio_buffer(s,1)) return(-1);
- }
-
- return(ssl2_do_write(s));
- }
-
-static int get_client_finished(SSL *s)
- {
- unsigned char *p;
- int i, n;
- unsigned long len;
-
- p=(unsigned char *)s->init_buf->data;
- if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A)
- {
- i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num);
- if (i < 1-s->init_num)
- return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
- s->init_num += i;
-
- if (*p != SSL2_MT_CLIENT_FINISHED)
- {
- if (*p != SSL2_MT_ERROR)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE);
- }
- else
- {
- SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_PEER_ERROR);
- /* try to read the error message */
- i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
- return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
- }
- return(-1);
- }
- s->state=SSL2_ST_GET_CLIENT_FINISHED_B;
- }
-
- /* SSL2_ST_GET_CLIENT_FINISHED_B */
- if (s->s2->conn_id_length > sizeof s->s2->conn_id)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR);
- return -1;
- }
- len = 1 + (unsigned long)s->s2->conn_id_length;
- n = (int)len - s->init_num;
- i = ssl2_read(s,(char *)&(p[s->init_num]),n);
- if (i < n)
- {
- return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
- }
- if (s->msg_callback)
- s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-FINISHED */
- p += 1;
- if (memcmp(p,s->s2->conn_id,s->s2->conn_id_length) != 0)
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_CONNECTION_ID_IS_DIFFERENT);
- return(-1);
- }
- return(1);
- }
-
-static int server_verify(SSL *s)
- {
- unsigned char *p;
-
- if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A)
- {
- p=(unsigned char *)s->init_buf->data;
- *(p++)=SSL2_MT_SERVER_VERIFY;
- if (s->s2->challenge_length > sizeof s->s2->challenge)
- {
- SSLerr(SSL_F_SERVER_VERIFY, ERR_R_INTERNAL_ERROR);
- return -1;
- }
- memcpy(p,s->s2->challenge,(unsigned int)s->s2->challenge_length);
- /* p+=s->s2->challenge_length; */
-
- s->state=SSL2_ST_SEND_SERVER_VERIFY_B;
- s->init_num=s->s2->challenge_length+1;
- s->init_off=0;
- }
- return(ssl2_do_write(s));
- }
-
-static int server_finish(SSL *s)
- {
- unsigned char *p;
-
- if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A)
- {
- p=(unsigned char *)s->init_buf->data;
- *(p++)=SSL2_MT_SERVER_FINISHED;
-
- if (s->session->session_id_length > sizeof s->session->session_id)
- {
- SSLerr(SSL_F_SERVER_FINISH, ERR_R_INTERNAL_ERROR);
- return -1;
- }
- memcpy(p,s->session->session_id, (unsigned int)s->session->session_id_length);
- /* p+=s->session->session_id_length; */
-
- s->state=SSL2_ST_SEND_SERVER_FINISHED_B;
- s->init_num=s->session->session_id_length+1;
- s->init_off=0;
- }
-
- /* SSL2_ST_SEND_SERVER_FINISHED_B */
- return(ssl2_do_write(s));
- }
-
-/* send the request and check the response */
-static int request_certificate(SSL *s)
- {
- const unsigned char *cp;
- unsigned char *p,*p2,*buf2;
- unsigned char *ccd;
- int i,j,ctype,ret= -1;
- unsigned long len;
- X509 *x509=NULL;
- STACK_OF(X509) *sk=NULL;
-
- ccd=s->s2->tmp.ccl;
- if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A)
- {
- p=(unsigned char *)s->init_buf->data;
- *(p++)=SSL2_MT_REQUEST_CERTIFICATE;
- *(p++)=SSL2_AT_MD5_WITH_RSA_ENCRYPTION;
- if (RAND_pseudo_bytes(ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0)
- return -1;
- memcpy(p,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
-
- s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_B;
- s->init_num=SSL2_MIN_CERT_CHALLENGE_LENGTH+2;
- s->init_off=0;
- }
-
- if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B)
- {
- i=ssl2_do_write(s);
- if (i <= 0)
- {
- ret=i;
- goto end;
- }
-
- s->init_num=0;
- s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_C;
- }
-
- if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C)
- {
- p=(unsigned char *)s->init_buf->data;
- i=ssl2_read(s,(char *)&(p[s->init_num]),6-s->init_num); /* try to read 6 octets ... */
- if (i < 3-s->init_num) /* ... but don't call ssl2_part_read now if we got at least 3
- * (probably NO-CERTIFICATE-ERROR) */
- {
- ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
- goto end;
- }
- s->init_num += i;
-
- if ((s->init_num >= 3) && (p[0] == SSL2_MT_ERROR))
- {
- n2s(p,i);
- if (i != SSL2_PE_NO_CERTIFICATE)
- {
- /* not the error message we expected -- let ssl2_part_read handle it */
- s->init_num -= 3;
- ret = ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE, 3);
- goto end;
- }
-
- if (s->msg_callback)
- s->msg_callback(0, s->version, 0, p, 3, s, s->msg_callback_arg); /* ERROR */
-
- /* this is the one place where we can recover from an SSL 2.0 error */
-
- if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
- {
- ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
- SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
- goto end;
- }
- ret=1;
- goto end;
- }
- if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (s->init_num < 6))
- {
- ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
- SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_SHORT_READ);
- goto end;
- }
- if (s->init_num != 6)
- {
- SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_INTERNAL_ERROR);
- goto end;
- }
-
- /* ok we have a response */
- /* certificate type, there is only one right now. */
- ctype= *(p++);
- if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
- {
- ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
- SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_RESPONSE_ARGUMENT);
- goto end;
- }
- n2s(p,i); s->s2->tmp.clen=i;
- n2s(p,i); s->s2->tmp.rlen=i;
- s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_D;
- }
-
- /* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */
- p=(unsigned char *)s->init_buf->data;
- len = 6 + (unsigned long)s->s2->tmp.clen + (unsigned long)s->s2->tmp.rlen;
- if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
- {
- SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_MESSAGE_TOO_LONG);
- goto end;
- }
- j = (int)len - s->init_num;
- i = ssl2_read(s,(char *)&(p[s->init_num]),j);
- if (i < j)
- {
- ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
- goto end;
- }
- if (s->msg_callback)
- s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-CERTIFICATE */
- p += 6;
-
- cp = p;
- x509=(X509 *)d2i_X509(NULL,&cp,(long)s->s2->tmp.clen);
- if (x509 == NULL)
- {
- SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_X509_LIB);
- goto msg_end;
- }
-
- if (((sk=sk_X509_new_null()) == NULL) || (!sk_X509_push(sk,x509)))
- {
- SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
- goto msg_end;
- }
-
- i=ssl_verify_cert_chain(s,sk);
-
- if (i > 0) /* we like the packet, now check the chksum */
- {
- EVP_MD_CTX ctx;
- EVP_PKEY *pkey=NULL;
-
- EVP_MD_CTX_init(&ctx);
- EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL);
- EVP_VerifyUpdate(&ctx,s->s2->key_material,
- s->s2->key_material_length);
- EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
-
- i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
- buf2=OPENSSL_malloc((unsigned int)i);
- if (buf2 == NULL)
- {
- SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
- goto msg_end;
- }
- p2=buf2;
- i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
- EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i);
- OPENSSL_free(buf2);
-
- pkey=X509_get_pubkey(x509);
- if (pkey == NULL) goto end;
- i=EVP_VerifyFinal(&ctx,cp,s->s2->tmp.rlen,pkey);
- EVP_PKEY_free(pkey);
- EVP_MD_CTX_cleanup(&ctx);
-
- if (i > 0)
- {
- if (s->session->peer != NULL)
- X509_free(s->session->peer);
- s->session->peer=x509;
- CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
- s->session->verify_result = s->verify_result;
- ret=1;
- goto end;
- }
- else
- {
- SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_CHECKSUM);
- goto msg_end;
- }
- }
- else
- {
-msg_end:
- ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
- }
-end:
- sk_X509_free(sk);
- X509_free(x509);
- return(ret);
- }
-
-static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
- unsigned char *to, int padding)
- {
- RSA *rsa;
- int i;
-
- if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL))
- {
- SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_NO_PRIVATEKEY);
- return(-1);
- }
- if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA)
- {
- SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
- return(-1);
- }
- rsa=c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa;
-
- /* we have the public key */
- i=RSA_private_decrypt(len,from,to,rsa,padding);
- if (i < 0)
- SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,ERR_R_RSA_LIB);
- return(i);
- }
-#else /* !OPENSSL_NO_SSL2 */
-
-# if PEDANTIC
-static void *dummy=&dummy;
-# endif
-
-#endif
+/* ssl/s2_srvr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_SSL2
+#include <stdio.h>
+#include <openssl/bio.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+
+static const SSL_METHOD *ssl2_get_server_method(int ver);
+static int get_client_master_key(SSL *s);
+static int get_client_hello(SSL *s);
+static int server_hello(SSL *s);
+static int get_client_finished(SSL *s);
+static int server_verify(SSL *s);
+static int server_finish(SSL *s);
+static int request_certificate(SSL *s);
+static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
+ unsigned char *to,int padding);
+#define BREAK break
+
+static const SSL_METHOD *ssl2_get_server_method(int ver)
+ {
+ if (ver == SSL2_VERSION)
+ return(SSLv2_server_method());
+ else
+ return(NULL);
+ }
+
+IMPLEMENT_ssl2_meth_func(SSLv2_server_method,
+ ssl2_accept,
+ ssl_undefined_function,
+ ssl2_get_server_method)
+
+int ssl2_accept(SSL *s)
+ {
+ unsigned long l=(unsigned long)time(NULL);
+ BUF_MEM *buf=NULL;
+ int ret= -1;
+ long num1;
+ void (*cb)(const SSL *ssl,int type,int val)=NULL;
+ int new_state,state;
+
+ RAND_add(&l,sizeof(l),0);
+ ERR_clear_error();
+ clear_sys_error();
+
+ if (s->info_callback != NULL)
+ cb=s->info_callback;
+ else if (s->ctx->info_callback != NULL)
+ cb=s->ctx->info_callback;
+
+ /* init things to blank */
+ s->in_handshake++;
+ if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
+
+ if (s->cert == NULL)
+ {
+ SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
+ return(-1);
+ }
+
+ clear_sys_error();
+ for (;;)
+ {
+ state=s->state;
+
+ switch (s->state)
+ {
+ case SSL_ST_BEFORE:
+ case SSL_ST_ACCEPT:
+ case SSL_ST_BEFORE|SSL_ST_ACCEPT:
+ case SSL_ST_OK|SSL_ST_ACCEPT:
+
+ s->server=1;
+ if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
+
+ s->version=SSL2_VERSION;
+ s->type=SSL_ST_ACCEPT;
+
+ buf=s->init_buf;
+ if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
+ { ret= -1; goto end; }
+ if (!BUF_MEM_grow(buf,(int)
+ SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
+ { ret= -1; goto end; }
+ s->init_buf=buf;
+ s->init_num=0;
+ s->ctx->stats.sess_accept++;
+ s->handshake_func=ssl2_accept;
+ s->state=SSL2_ST_GET_CLIENT_HELLO_A;
+ BREAK;
+
+ case SSL2_ST_GET_CLIENT_HELLO_A:
+ case SSL2_ST_GET_CLIENT_HELLO_B:
+ case SSL2_ST_GET_CLIENT_HELLO_C:
+ s->shutdown=0;
+ ret=get_client_hello(s);
+ if (ret <= 0) goto end;
+ s->init_num=0;
+ s->state=SSL2_ST_SEND_SERVER_HELLO_A;
+ BREAK;
+
+ case SSL2_ST_SEND_SERVER_HELLO_A:
+ case SSL2_ST_SEND_SERVER_HELLO_B:
+ ret=server_hello(s);
+ if (ret <= 0) goto end;
+ s->init_num=0;
+ if (!s->hit)
+ {
+ s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_A;
+ BREAK;
+ }
+ else
+ {
+ s->state=SSL2_ST_SERVER_START_ENCRYPTION;
+ BREAK;
+ }
+ case SSL2_ST_GET_CLIENT_MASTER_KEY_A:
+ case SSL2_ST_GET_CLIENT_MASTER_KEY_B:
+ ret=get_client_master_key(s);
+ if (ret <= 0) goto end;
+ s->init_num=0;
+ s->state=SSL2_ST_SERVER_START_ENCRYPTION;
+ BREAK;
+
+ case SSL2_ST_SERVER_START_ENCRYPTION:
+ /* Ok we how have sent all the stuff needed to
+ * start encrypting, the next packet back will
+ * be encrypted. */
+ if (!ssl2_enc_init(s,0))
+ { ret= -1; goto end; }
+ s->s2->clear_text=0;
+ s->state=SSL2_ST_SEND_SERVER_VERIFY_A;
+ BREAK;
+
+ case SSL2_ST_SEND_SERVER_VERIFY_A:
+ case SSL2_ST_SEND_SERVER_VERIFY_B:
+ ret=server_verify(s);
+ if (ret <= 0) goto end;
+ s->init_num=0;
+ if (s->hit)
+ {
+ /* If we are in here, we have been
+ * buffering the output, so we need to
+ * flush it and remove buffering from
+ * future traffic */
+ s->state=SSL2_ST_SEND_SERVER_VERIFY_C;
+ BREAK;
+ }
+ else
+ {
+ s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
+ break;
+ }
+
+ case SSL2_ST_SEND_SERVER_VERIFY_C:
+ /* get the number of bytes to write */
+ num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
+ if (num1 > 0)
+ {
+ s->rwstate=SSL_WRITING;
+ num1=BIO_flush(s->wbio);
+ if (num1 <= 0) { ret= -1; goto end; }
+ s->rwstate=SSL_NOTHING;
+ }
+
+ /* flushed and now remove buffering */
+ s->wbio=BIO_pop(s->wbio);
+
+ s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
+ BREAK;
+
+ case SSL2_ST_GET_CLIENT_FINISHED_A:
+ case SSL2_ST_GET_CLIENT_FINISHED_B:
+ ret=get_client_finished(s);
+ if (ret <= 0)
+ goto end;
+ s->init_num=0;
+ s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_A;
+ BREAK;
+
+ case SSL2_ST_SEND_REQUEST_CERTIFICATE_A:
+ case SSL2_ST_SEND_REQUEST_CERTIFICATE_B:
+ case SSL2_ST_SEND_REQUEST_CERTIFICATE_C:
+ case SSL2_ST_SEND_REQUEST_CERTIFICATE_D:
+ /* don't do a 'request certificate' if we
+ * don't want to, or we already have one, and
+ * we only want to do it once. */
+ if (!(s->verify_mode & SSL_VERIFY_PEER) ||
+ ((s->session->peer != NULL) &&
+ (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)))
+ {
+ s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
+ break;
+ }
+ else
+ {
+ ret=request_certificate(s);
+ if (ret <= 0) goto end;
+ s->init_num=0;
+ s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
+ }
+ BREAK;
+
+ case SSL2_ST_SEND_SERVER_FINISHED_A:
+ case SSL2_ST_SEND_SERVER_FINISHED_B:
+ ret=server_finish(s);
+ if (ret <= 0) goto end;
+ s->init_num=0;
+ s->state=SSL_ST_OK;
+ break;
+
+ case SSL_ST_OK:
+ BUF_MEM_free(s->init_buf);
+ ssl_free_wbio_buffer(s);
+ s->init_buf=NULL;
+ s->init_num=0;
+ /* ERR_clear_error();*/
+
+ ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
+
+ s->ctx->stats.sess_accept_good++;
+ /* s->server=1; */
+ ret=1;
+
+ if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
+
+ goto end;
+ /* BREAK; */
+
+ default:
+ SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_UNKNOWN_STATE);
+ ret= -1;
+ goto end;
+ /* BREAK; */
+ }
+
+ if ((cb != NULL) && (s->state != state))
+ {
+ new_state=s->state;
+ s->state=state;
+ cb(s,SSL_CB_ACCEPT_LOOP,1);
+ s->state=new_state;
+ }
+ }
+end:
+ s->in_handshake--;
+ if (cb != NULL)
+ cb(s,SSL_CB_ACCEPT_EXIT,ret);
+ return(ret);
+ }
+
+static int get_client_master_key(SSL *s)
+ {
+ int is_export,i,n,keya,ek;
+ unsigned long len;
+ unsigned char *p;
+ const SSL_CIPHER *cp;
+ const EVP_CIPHER *c;
+ const EVP_MD *md;
+
+ p=(unsigned char *)s->init_buf->data;
+ if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A)
+ {
+ i=ssl2_read(s,(char *)&(p[s->init_num]),10-s->init_num);
+
+ if (i < (10-s->init_num))
+ return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
+ s->init_num = 10;
+
+ if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY)
+ {
+ if (p[-1] != SSL2_MT_ERROR)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_READ_WRONG_PACKET_TYPE);
+ }
+ else
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR);
+ return(-1);
+ }
+
+ cp=ssl2_get_cipher_by_char(p);
+ if (cp == NULL)
+ {
+ ssl2_return_error(s,SSL2_PE_NO_CIPHER);
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH);
+ return(-1);
+ }
+ s->session->cipher= cp;
+
+ p+=3;
+ n2s(p,i); s->s2->tmp.clear=i;
+ n2s(p,i); s->s2->tmp.enc=i;
+ n2s(p,i);
+ if(i > SSL_MAX_KEY_ARG_LENGTH)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG);
+ return -1;
+ }
+ s->session->key_arg_length=i;
+ s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B;
+ }
+
+ /* SSL2_ST_GET_CLIENT_MASTER_KEY_B */
+ p=(unsigned char *)s->init_buf->data;
+ if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ keya=s->session->key_arg_length;
+ len = 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + (unsigned long)keya;
+ if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_MESSAGE_TOO_LONG);
+ return -1;
+ }
+ n = (int)len - s->init_num;
+ i = ssl2_read(s,(char *)&(p[s->init_num]),n);
+ if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-MASTER-KEY */
+ p += 10;
+
+ memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]),
+ (unsigned int)keya);
+
+ if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY);
+ return(-1);
+ }
+ i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc,
+ &(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]),
+ (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
+
+ is_export=SSL_C_IS_EXPORT(s->session->cipher);
+
+ if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
+ {
+ ssl2_return_error(s,SSL2_PE_NO_CIPHER);
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
+ return(0);
+ }
+
+ if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
+ {
+ is_export=1;
+ ek=8;
+ }
+ else
+ ek=5;
+
+ /* bad decrypt */
+#if 1
+ /* If a bad decrypt, continue with protocol but with a
+ * random master secret (Bleichenbacher attack) */
+ if ((i < 0) ||
+ ((!is_export && (i != EVP_CIPHER_key_length(c)))
+ || (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i !=
+ (unsigned int)EVP_CIPHER_key_length(c))))))
+ {
+ ERR_clear_error();
+ if (is_export)
+ i=ek;
+ else
+ i=EVP_CIPHER_key_length(c);
+ if (RAND_pseudo_bytes(p,i) <= 0)
+ return 0;
+ }
+#else
+ if (i < 0)
+ {
+ error=1;
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_RSA_DECRYPT);
+ }
+ /* incorrect number of key bytes for non export cipher */
+ else if ((!is_export && (i != EVP_CIPHER_key_length(c)))
+ || (is_export && ((i != ek) || (s->s2->tmp.clear+i !=
+ EVP_CIPHER_key_length(c)))))
+ {
+ error=1;
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_WRONG_NUMBER_OF_KEY_BITS);
+ }
+ if (error)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ return(-1);
+ }
+#endif
+
+ if (is_export) i+=s->s2->tmp.clear;
+
+ if (i > SSL_MAX_MASTER_KEY_LENGTH)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ s->session->master_key_length=i;
+ memcpy(s->session->master_key,p,(unsigned int)i);
+ return(1);
+ }
+
+static int get_client_hello(SSL *s)
+ {
+ int i,n;
+ unsigned long len;
+ unsigned char *p;
+ STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */
+ STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */
+ STACK_OF(SSL_CIPHER) *prio, *allow;
+ int z;
+
+ /* This is a bit of a hack to check for the correct packet
+ * type the first time round. */
+ if (s->state == SSL2_ST_GET_CLIENT_HELLO_A)
+ {
+ s->first_packet=1;
+ s->state=SSL2_ST_GET_CLIENT_HELLO_B;
+ }
+
+ p=(unsigned char *)s->init_buf->data;
+ if (s->state == SSL2_ST_GET_CLIENT_HELLO_B)
+ {
+ i=ssl2_read(s,(char *)&(p[s->init_num]),9-s->init_num);
+ if (i < (9-s->init_num))
+ return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
+ s->init_num = 9;
+
+ if (*(p++) != SSL2_MT_CLIENT_HELLO)
+ {
+ if (p[-1] != SSL2_MT_ERROR)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_READ_WRONG_PACKET_TYPE);
+ }
+ else
+ SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_PEER_ERROR);
+ return(-1);
+ }
+ n2s(p,i);
+ if (i < s->version) s->version=i;
+ n2s(p,i); s->s2->tmp.cipher_spec_length=i;
+ n2s(p,i); s->s2->tmp.session_id_length=i;
+ n2s(p,i); s->s2->challenge_length=i;
+ if ( (i < SSL2_MIN_CHALLENGE_LENGTH) ||
+ (i > SSL2_MAX_CHALLENGE_LENGTH))
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_INVALID_CHALLENGE_LENGTH);
+ return(-1);
+ }
+ s->state=SSL2_ST_GET_CLIENT_HELLO_C;
+ }
+
+ /* SSL2_ST_GET_CLIENT_HELLO_C */
+ p=(unsigned char *)s->init_buf->data;
+ len = 9 + (unsigned long)s->s2->tmp.cipher_spec_length + (unsigned long)s->s2->challenge_length + (unsigned long)s->s2->tmp.session_id_length;
+ if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_MESSAGE_TOO_LONG);
+ return -1;
+ }
+ n = (int)len - s->init_num;
+ i = ssl2_read(s,(char *)&(p[s->init_num]),n);
+ if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, 0, p, (size_t)len, s, s->msg_callback_arg); /* CLIENT-HELLO */
+ p += 9;
+
+ /* get session-id before cipher stuff so we can get out session
+ * structure if it is cached */
+ /* session-id */
+ if ((s->s2->tmp.session_id_length != 0) &&
+ (s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH))
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_BAD_SSL_SESSION_ID_LENGTH);
+ return(-1);
+ }
+
+ if (s->s2->tmp.session_id_length == 0)
+ {
+ if (!ssl_get_new_session(s,1))
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ return(-1);
+ }
+ }
+ else
+ {
+ i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_spec_length]),
+ s->s2->tmp.session_id_length, NULL);
+ if (i == 1)
+ { /* previous session */
+ s->hit=1;
+ }
+ else if (i == -1)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ return(-1);
+ }
+ else
+ {
+ if (s->cert == NULL)
+ {
+ ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
+ SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_NO_CERTIFICATE_SET);
+ return(-1);
+ }
+
+ if (!ssl_get_new_session(s,1))
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ return(-1);
+ }
+ }
+ }
+
+ if (!s->hit)
+ {
+ cs=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.cipher_spec_length,
+ &s->session->ciphers);
+ if (cs == NULL) goto mem_err;
+
+ cl=SSL_get_ciphers(s);
+
+ if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
+ {
+ prio=sk_SSL_CIPHER_dup(cl);
+ if (prio == NULL) goto mem_err;
+ allow = cs;
+ }
+ else
+ {
+ prio = cs;
+ allow = cl;
+ }
+ for (z=0; z<sk_SSL_CIPHER_num(prio); z++)
+ {
+ if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0)
+ {
+ (void)sk_SSL_CIPHER_delete(prio,z);
+ z--;
+ }
+ }
+ if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
+ {
+ sk_SSL_CIPHER_free(s->session->ciphers);
+ s->session->ciphers = prio;
+ }
+ /* s->session->ciphers should now have a list of
+ * ciphers that are on both the client and server.
+ * This list is ordered by the order the client sent
+ * the ciphers or in the order of the server's preference
+ * if SSL_OP_CIPHER_SERVER_PREFERENCE was set.
+ */
+ }
+ p+=s->s2->tmp.cipher_spec_length;
+ /* done cipher selection */
+
+ /* session id extracted already */
+ p+=s->s2->tmp.session_id_length;
+
+ /* challenge */
+ if (s->s2->challenge_length > sizeof s->s2->challenge)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ memcpy(s->s2->challenge,p,(unsigned int)s->s2->challenge_length);
+ return(1);
+mem_err:
+ SSLerr(SSL_F_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE);
+ return(0);
+ }
+
+static int server_hello(SSL *s)
+ {
+ unsigned char *p,*d;
+ int n,hit;
+
+ p=(unsigned char *)s->init_buf->data;
+ if (s->state == SSL2_ST_SEND_SERVER_HELLO_A)
+ {
+ d=p+11;
+ *(p++)=SSL2_MT_SERVER_HELLO; /* type */
+ hit=s->hit;
+ *(p++)=(unsigned char)hit;
+#if 1
+ if (!hit)
+ {
+ if (s->session->sess_cert != NULL)
+ /* This can't really happen because get_client_hello
+ * has called ssl_get_new_session, which does not set
+ * sess_cert. */
+ ssl_sess_cert_free(s->session->sess_cert);
+ s->session->sess_cert = ssl_sess_cert_new();
+ if (s->session->sess_cert == NULL)
+ {
+ SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE);
+ return(-1);
+ }
+ }
+ /* If 'hit' is set, then s->sess_cert may be non-NULL or NULL,
+ * depending on whether it survived in the internal cache
+ * or was retrieved from an external cache.
+ * If it is NULL, we cannot put any useful data in it anyway,
+ * so we don't touch it.
+ */
+
+#else /* That's what used to be done when cert_st and sess_cert_st were
+ * the same. */
+ if (!hit)
+ { /* else add cert to session */
+ CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
+ if (s->session->sess_cert != NULL)
+ ssl_cert_free(s->session->sess_cert);
+ s->session->sess_cert=s->cert;
+ }
+ else /* We have a session id-cache hit, if the
+ * session-id has no certificate listed against
+ * the 'cert' structure, grab the 'old' one
+ * listed against the SSL connection */
+ {
+ if (s->session->sess_cert == NULL)
+ {
+ CRYPTO_add(&s->cert->references,1,
+ CRYPTO_LOCK_SSL_CERT);
+ s->session->sess_cert=s->cert;
+ }
+ }
+#endif
+
+ if (s->cert == NULL)
+ {
+ ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
+ SSLerr(SSL_F_SERVER_HELLO,SSL_R_NO_CERTIFICATE_SPECIFIED);
+ return(-1);
+ }
+
+ if (hit)
+ {
+ *(p++)=0; /* no certificate type */
+ s2n(s->version,p); /* version */
+ s2n(0,p); /* cert len */
+ s2n(0,p); /* ciphers len */
+ }
+ else
+ {
+ /* EAY EAY */
+ /* put certificate type */
+ *(p++)=SSL2_CT_X509_CERTIFICATE;
+ s2n(s->version,p); /* version */
+ n=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
+ s2n(n,p); /* certificate length */
+ i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&d);
+ n=0;
+
+ /* lets send out the ciphers we like in the
+ * prefered order */
+ n=ssl_cipher_list_to_bytes(s,s->session->ciphers,d,0);
+ d+=n;
+ s2n(n,p); /* add cipher length */
+ }
+
+ /* make and send conn_id */
+ s2n(SSL2_CONNECTION_ID_LENGTH,p); /* add conn_id length */
+ s->s2->conn_id_length=SSL2_CONNECTION_ID_LENGTH;
+ if (RAND_pseudo_bytes(s->s2->conn_id,(int)s->s2->conn_id_length) <= 0)
+ return -1;
+ memcpy(d,s->s2->conn_id,SSL2_CONNECTION_ID_LENGTH);
+ d+=SSL2_CONNECTION_ID_LENGTH;
+
+ s->state=SSL2_ST_SEND_SERVER_HELLO_B;
+ s->init_num=d-(unsigned char *)s->init_buf->data;
+ s->init_off=0;
+ }
+ /* SSL2_ST_SEND_SERVER_HELLO_B */
+ /* If we are using TCP/IP, the performance is bad if we do 2
+ * writes without a read between them. This occurs when
+ * Session-id reuse is used, so I will put in a buffering module
+ */
+ if (s->hit)
+ {
+ if (!ssl_init_wbio_buffer(s,1)) return(-1);
+ }
+
+ return(ssl2_do_write(s));
+ }
+
+static int get_client_finished(SSL *s)
+ {
+ unsigned char *p;
+ int i, n;
+ unsigned long len;
+
+ p=(unsigned char *)s->init_buf->data;
+ if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A)
+ {
+ i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num);
+ if (i < 1-s->init_num)
+ return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
+ s->init_num += i;
+
+ if (*p != SSL2_MT_CLIENT_FINISHED)
+ {
+ if (*p != SSL2_MT_ERROR)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE);
+ }
+ else
+ {
+ SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_PEER_ERROR);
+ /* try to read the error message */
+ i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
+ return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
+ }
+ return(-1);
+ }
+ s->state=SSL2_ST_GET_CLIENT_FINISHED_B;
+ }
+
+ /* SSL2_ST_GET_CLIENT_FINISHED_B */
+ if (s->s2->conn_id_length > sizeof s->s2->conn_id)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ len = 1 + (unsigned long)s->s2->conn_id_length;
+ n = (int)len - s->init_num;
+ i = ssl2_read(s,(char *)&(p[s->init_num]),n);
+ if (i < n)
+ {
+ return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
+ }
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-FINISHED */
+ p += 1;
+ if (memcmp(p,s->s2->conn_id,s->s2->conn_id_length) != 0)
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_CONNECTION_ID_IS_DIFFERENT);
+ return(-1);
+ }
+ return(1);
+ }
+
+static int server_verify(SSL *s)
+ {
+ unsigned char *p;
+
+ if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A)
+ {
+ p=(unsigned char *)s->init_buf->data;
+ *(p++)=SSL2_MT_SERVER_VERIFY;
+ if (s->s2->challenge_length > sizeof s->s2->challenge)
+ {
+ SSLerr(SSL_F_SERVER_VERIFY, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ memcpy(p,s->s2->challenge,(unsigned int)s->s2->challenge_length);
+ /* p+=s->s2->challenge_length; */
+
+ s->state=SSL2_ST_SEND_SERVER_VERIFY_B;
+ s->init_num=s->s2->challenge_length+1;
+ s->init_off=0;
+ }
+ return(ssl2_do_write(s));
+ }
+
+static int server_finish(SSL *s)
+ {
+ unsigned char *p;
+
+ if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A)
+ {
+ p=(unsigned char *)s->init_buf->data;
+ *(p++)=SSL2_MT_SERVER_FINISHED;
+
+ if (s->session->session_id_length > sizeof s->session->session_id)
+ {
+ SSLerr(SSL_F_SERVER_FINISH, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ memcpy(p,s->session->session_id, (unsigned int)s->session->session_id_length);
+ /* p+=s->session->session_id_length; */
+
+ s->state=SSL2_ST_SEND_SERVER_FINISHED_B;
+ s->init_num=s->session->session_id_length+1;
+ s->init_off=0;
+ }
+
+ /* SSL2_ST_SEND_SERVER_FINISHED_B */
+ return(ssl2_do_write(s));
+ }
+
+/* send the request and check the response */
+static int request_certificate(SSL *s)
+ {
+ const unsigned char *cp;
+ unsigned char *p,*p2,*buf2;
+ unsigned char *ccd;
+ int i,j,ctype,ret= -1;
+ unsigned long len;
+ X509 *x509=NULL;
+ STACK_OF(X509) *sk=NULL;
+
+ ccd=s->s2->tmp.ccl;
+ if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A)
+ {
+ p=(unsigned char *)s->init_buf->data;
+ *(p++)=SSL2_MT_REQUEST_CERTIFICATE;
+ *(p++)=SSL2_AT_MD5_WITH_RSA_ENCRYPTION;
+ if (RAND_pseudo_bytes(ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0)
+ return -1;
+ memcpy(p,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
+
+ s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_B;
+ s->init_num=SSL2_MIN_CERT_CHALLENGE_LENGTH+2;
+ s->init_off=0;
+ }
+
+ if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B)
+ {
+ i=ssl2_do_write(s);
+ if (i <= 0)
+ {
+ ret=i;
+ goto end;
+ }
+
+ s->init_num=0;
+ s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_C;
+ }
+
+ if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C)
+ {
+ p=(unsigned char *)s->init_buf->data;
+ i=ssl2_read(s,(char *)&(p[s->init_num]),6-s->init_num); /* try to read 6 octets ... */
+ if (i < 3-s->init_num) /* ... but don't call ssl2_part_read now if we got at least 3
+ * (probably NO-CERTIFICATE-ERROR) */
+ {
+ ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
+ goto end;
+ }
+ s->init_num += i;
+
+ if ((s->init_num >= 3) && (p[0] == SSL2_MT_ERROR))
+ {
+ n2s(p,i);
+ if (i != SSL2_PE_NO_CERTIFICATE)
+ {
+ /* not the error message we expected -- let ssl2_part_read handle it */
+ s->init_num -= 3;
+ ret = ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE, 3);
+ goto end;
+ }
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, 0, p, 3, s, s->msg_callback_arg); /* ERROR */
+
+ /* this is the one place where we can recover from an SSL 2.0 error */
+
+ if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
+ {
+ ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
+ SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+ goto end;
+ }
+ ret=1;
+ goto end;
+ }
+ if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (s->init_num < 6))
+ {
+ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
+ SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_SHORT_READ);
+ goto end;
+ }
+ if (s->init_num != 6)
+ {
+ SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+ goto end;
+ }
+
+ /* ok we have a response */
+ /* certificate type, there is only one right now. */
+ ctype= *(p++);
+ if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
+ {
+ ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
+ SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_RESPONSE_ARGUMENT);
+ goto end;
+ }
+ n2s(p,i); s->s2->tmp.clen=i;
+ n2s(p,i); s->s2->tmp.rlen=i;
+ s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_D;
+ }
+
+ /* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */
+ p=(unsigned char *)s->init_buf->data;
+ len = 6 + (unsigned long)s->s2->tmp.clen + (unsigned long)s->s2->tmp.rlen;
+ if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
+ {
+ SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_MESSAGE_TOO_LONG);
+ goto end;
+ }
+ j = (int)len - s->init_num;
+ i = ssl2_read(s,(char *)&(p[s->init_num]),j);
+ if (i < j)
+ {
+ ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
+ goto end;
+ }
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* CLIENT-CERTIFICATE */
+ p += 6;
+
+ cp = p;
+ x509=(X509 *)d2i_X509(NULL,&cp,(long)s->s2->tmp.clen);
+ if (x509 == NULL)
+ {
+ SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_X509_LIB);
+ goto msg_end;
+ }
+
+ if (((sk=sk_X509_new_null()) == NULL) || (!sk_X509_push(sk,x509)))
+ {
+ SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+ goto msg_end;
+ }
+
+ i=ssl_verify_cert_chain(s,sk);
+
+ if (i > 0) /* we like the packet, now check the chksum */
+ {
+ EVP_MD_CTX ctx;
+ EVP_PKEY *pkey=NULL;
+
+ EVP_MD_CTX_init(&ctx);
+ EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL);
+ EVP_VerifyUpdate(&ctx,s->s2->key_material,
+ s->s2->key_material_length);
+ EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
+
+ i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
+ buf2=OPENSSL_malloc((unsigned int)i);
+ if (buf2 == NULL)
+ {
+ SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+ goto msg_end;
+ }
+ p2=buf2;
+ i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
+ EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i);
+ OPENSSL_free(buf2);
+
+ pkey=X509_get_pubkey(x509);
+ if (pkey == NULL) goto end;
+ i=EVP_VerifyFinal(&ctx,cp,s->s2->tmp.rlen,pkey);
+ EVP_PKEY_free(pkey);
+ EVP_MD_CTX_cleanup(&ctx);
+
+ if (i > 0)
+ {
+ if (s->session->peer != NULL)
+ X509_free(s->session->peer);
+ s->session->peer=x509;
+ CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
+ s->session->verify_result = s->verify_result;
+ ret=1;
+ goto end;
+ }
+ else
+ {
+ SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_CHECKSUM);
+ goto msg_end;
+ }
+ }
+ else
+ {
+msg_end:
+ ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
+ }
+end:
+ sk_X509_free(sk);
+ X509_free(x509);
+ return(ret);
+ }
+
+static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
+ unsigned char *to, int padding)
+ {
+ RSA *rsa;
+ int i;
+
+ if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL))
+ {
+ SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_NO_PRIVATEKEY);
+ return(-1);
+ }
+ if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA)
+ {
+ SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
+ return(-1);
+ }
+ rsa=c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa;
+
+ /* we have the public key */
+ i=RSA_private_decrypt(len,from,to,rsa,padding);
+ if (i < 0)
+ SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,ERR_R_RSA_LIB);
+ return(i);
+ }
+#else /* !OPENSSL_NO_SSL2 */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
+#endif
diff --git a/openssl/ssl/ssl-lib.com b/openssl/ssl/ssl-lib.com
index 8847c9bd3..35bdd34de 100644
--- a/openssl/ssl/ssl-lib.com
+++ b/openssl/ssl/ssl-lib.com
@@ -1,1116 +1,1116 @@
-$!
-$! SSL-LIB.COM
-$! Written By: Robert Byer
-$! Vice-President
-$! A-Com Computing, Inc.
-$! byer@mail.all-net.net
-$!
-$! Changes by Richard Levitte <richard@levitte.org>
-$!
-$! This command file compiles and creates the "[.xxx.EXE.SSL]LIBSSL.OLB"
-$! library for OpenSSL. The "xxx" denotes the machine architecture of
-$! ALPHA, IA64 or VAX.
-$!
-$! It is written to detect what type of machine you are compiling on
-$! (i.e. ALPHA or VAX) and which "C" compiler you have (i.e. VAXC, DECC
-$! or GNU C) or you can specify which compiler to use.
-$!
-$! Specify the following as P1 to build just that part or ALL to just
-$! build everything.
-$!
-$! LIBRARY To just compile the [.xxx.EXE.SSL]LIBSSL.OLB Library.
-$! SSL_TASK To just compile the [.xxx.EXE.SSL]SSL_TASK.EXE
-$!
-$! Specify DEBUG or NODEBUG as P2 to compile with or without debugger
-$! information.
-$!
-$! Specify which compiler at P3 to try to compile under.
-$!
-$! VAXC For VAX C.
-$! DECC For DEC C.
-$! GNUC For GNU C.
-$!
-$! If you don't specify a compiler, it will try to determine which
-$! "C" compiler to use.
-$!
-$! P4, if defined, sets a TCP/IP library to use, through one of the following
-$! keywords:
-$!
-$! UCX for UCX
-$! TCPIP for TCPIP (post UCX)
-$! SOCKETSHR for SOCKETSHR+NETLIB
-$!
-$! P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
-$!
-$! For 64 bit architectures (Alpha and IA64), specify the pointer size as P6.
-$! For 32 bit architectures (VAX), P6 is ignored.
-$! Currently supported values are:
-$!
-$! 32 To ge a library compiled with /POINTER_SIZE=32
-$! 64 To ge a library compiled with /POINTER_SIZE=64
-$!
-$!
-$! Define A TCP/IP Library That We Will Need To Link To.
-$! (That Is, If We Need To Link To One.)
-$!
-$ TCPIP_LIB = ""
-$!
-$! Check What Architecture We Are Using.
-$!
-$ IF (F$GETSYI("CPU").LT.128)
-$ THEN
-$!
-$! The Architecture Is VAX.
-$!
-$ ARCH = "VAX"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! The Architecture Is Alpha, IA64 or whatever comes in the future.
-$!
-$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
-$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
-$!
-$! End The Architecture Check.
-$!
-$ ENDIF
-$!
-$! Define The OBJ Directory.
-$!
-$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.SSL]
-$!
-$! Define The EXE Directory.
-$!
-$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.SSL]
-$!
-$! Check To Make Sure We Have Valid Command Line Parameters.
-$!
-$ GOSUB CHECK_OPTIONS
-$!
-$! Initialise logical names and such
-$!
-$ GOSUB INITIALISE
-$!
-$! Tell The User What Kind of Machine We Run On.
-$!
-$ WRITE SYS$OUTPUT "Compiling On A ",ARCH," Machine."
-$!
-$! Check To See If The Architecture Specific OBJ Directory Exists.
-$!
-$ IF (F$PARSE(OBJ_DIR).EQS."")
-$ THEN
-$!
-$! It Dosen't Exist, So Create It.
-$!
-$ CREATE/DIR 'OBJ_DIR'
-$!
-$! End The Architecture Specific OBJ Directory Check.
-$!
-$ ENDIF
-$!
-$! Check To See If The Architecture Specific Directory Exists.
-$!
-$ IF (F$PARSE(EXE_DIR).EQS."")
-$ THEN
-$!
-$! It Dosen't Exist, So Create It.
-$!
-$ CREATE/DIR 'EXE_DIR'
-$!
-$! End The Architecture Specific Directory Check.
-$!
-$ ENDIF
-$!
-$! Define The Library Name.
-$!
-$ SSL_LIB := 'EXE_DIR'LIBSSL'LIB32'.OLB
-$!
-$! Define The CRYPTO-LIB We Are To Use.
-$!
-$ CRYPTO_LIB := SYS$DISK:[-.'ARCH'.EXE.CRYPTO]LIBCRYPTO'LIB32'.OLB
-$!
-$! Check To See What We Are To Do.
-$!
-$ IF (BUILDALL.EQS."TRUE")
-$ THEN
-$!
-$! Since Nothing Special Was Specified, Do Everything.
-$!
-$ GOSUB LIBRARY
-$ GOSUB SSL_TASK
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Build Just What The User Wants Us To Build.
-$!
-$ GOSUB 'BUILDALL'
-$!
-$! End The BUILDALL Check.
-$!
-$ ENDIF
-$!
-$! Time To EXIT.
-$!
-$ EXIT:
-$ GOSUB CLEANUP
-$ EXIT
-$!
-$! Compile The Library.
-$!
-$ LIBRARY:
-$!
-$! Check To See If We Already Have A "[.xxx.EXE.SSL]LIBSSL''LIB32'.OLB" Library...
-$!
-$ IF (F$SEARCH(SSL_LIB).EQS."")
-$ THEN
-$!
-$! Guess Not, Create The Library.
-$!
-$ LIBRARY/CREATE/OBJECT 'SSL_LIB'
-$!
-$! End The Library Exist Check.
-$!
-$ ENDIF
-$!
-$! Define The Different SSL "library" Files.
-$!
-$ LIB_SSL = "s2_meth,s2_srvr,s2_clnt,s2_lib,s2_enc,s2_pkt,"+ -
- "s3_meth,s3_srvr,s3_clnt,s3_lib,s3_enc,s3_pkt,s3_both,"+ -
- "s23_meth,s23_srvr,s23_clnt,s23_lib,s23_pkt,"+ -
- "t1_meth,t1_srvr,t1_clnt,t1_lib,t1_enc,"+ -
- "d1_meth,d1_srvr,d1_clnt,d1_lib,d1_pkt,"+ -
- "d1_both,d1_enc,"+ -
- "ssl_lib,ssl_err2,ssl_cert,ssl_sess,"+ -
- "ssl_ciph,ssl_stat,ssl_rsa,"+ -
- "ssl_asn1,ssl_txt,ssl_algs,"+ -
- "bio_ssl,ssl_err,kssl,t1_reneg"
-$!
-$! Tell The User That We Are Compiling The Library.
-$!
-$ WRITE SYS$OUTPUT "Building The ",SSL_LIB," Library."
-$!
-$! Define A File Counter And Set It To "0"
-$!
-$ FILE_COUNTER = 0
-$!
-$! Top Of The File Loop.
-$!
-$ NEXT_FILE:
-$!
-$! O.K, Extract The File Name From The File List.
-$!
-$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",LIB_SSL)
-$!
-$! Check To See If We Are At The End Of The File List.
-$!
-$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
-$!
-$! Increment The Counter.
-$!
-$ FILE_COUNTER = FILE_COUNTER + 1
-$!
-$! Create The Source File Name.
-$!
-$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
-$!
-$! Create The Object File Name.
-$!
-$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
-$ ON WARNING THEN GOTO NEXT_FILE
-$!
-$! Check To See If The File We Want To Compile Is Actually There.
-$!
-$ IF (F$SEARCH(SOURCE_FILE).EQS."")
-$ THEN
-$!
-$! Tell The User That The File Dosen't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ EXIT
-$!
-$! End The File Exists Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What File We Are Compiling.
-$!
-$ WRITE SYS$OUTPUT " ",FILE_NAME,".c"
-$!
-$! Compile The File.
-$!
-$ ON ERROR THEN GOTO NEXT_FILE
-$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$!
-$! Add It To The Library.
-$!
-$ LIBRARY/REPLACE/OBJECT 'SSL_LIB' 'OBJECT_FILE'
-$!
-$! Time To Clean Up The Object File.
-$!
-$ DELETE 'OBJECT_FILE';*
-$!
-$! Go Back And Get The Next File Name.
-$!
-$ GOTO NEXT_FILE
-$!
-$! All Done With This Library.
-$!
-$ FILE_DONE:
-$!
-$! Tell The User That We Are All Done.
-$!
-$ WRITE SYS$OUTPUT "Library ",SSL_LIB," Compiled."
-$!
-$! Time To RETURN.
-$!
-$ RETURN
-$ SSL_TASK:
-$!
-$! Check To See If We Have The Proper Libraries.
-$!
-$ GOSUB LIB_CHECK
-$!
-$! Check To See If We Have A Linker Option File.
-$!
-$ GOSUB CHECK_OPT_FILE
-$!
-$! Check To See If The File We Want To Compile Is Actually There.
-$!
-$ IF (F$SEARCH("SYS$DISK:[]SSL_TASK.C").EQS."")
-$ THEN
-$!
-$! Tell The User That The File Dosen't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File SSL_TASK.C Dosen't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ EXIT
-$!
-$! End The SSL_TASK.C File Check.
-$!
-$ ENDIF
-$!
-$! Tell The User We Are Creating The SSL_TASK.
-$!
-$ WRITE SYS$OUTPUT "Creating SSL_TASK OSU HTTP SSL Engine."
-$!
-$! Compile The File.
-$!
-$ ON ERROR THEN GOTO SSL_TASK_END
-$ CC5/OBJECT='OBJ_DIR'SSL_TASK.OBJ SYS$DISK:[]SSL_TASK.C
-$!
-$! Link The Program.
-$! Check To See If We Are To Link With A Specific TCP/IP Library.
-$!
-$ IF (TCPIP_LIB.NES."")
-$ THEN
-$!
-$! Link With TCP/IP Library.
-$!
-$ LINK/'DEBUGGER'/'TRACEBACK'/EXE='EXE_DIR'SSL_TASK.EXE -
- 'OBJ_DIR'SSL_TASK.OBJ, -
- 'SSL_LIB'/LIBRARY,'CRYPTO_LIB'/LIBRARY, -
- 'TCPIP_LIB','OPT_FILE'/OPTION
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Don't Link With TCP/IP Library.
-$!
-$ LINK/'DEBUGGER'/'TRACEBACK'/EXE='EXE_DIR'SSL_TASK.EXE -
- 'OBJ_DIR'SSL_TASK.OBJ,-
- 'SSL_LIB'/LIBRARY,'CRYPTO_LIB'/LIBRARY, -
- 'OPT_FILE'/OPTION
-$!
-$! End The TCP/IP Library Check.
-$!
-$ ENDIF
-$!
-$! Time To Return.
-$!
-$SSL_TASK_END:
-$ RETURN
-$!
-$! Check For The Link Option FIle.
-$!
-$ CHECK_OPT_FILE:
-$!
-$! Check To See If We Need To Make A VAX C Option File.
-$!
-$ IF (COMPILER.EQS."VAXC")
-$ THEN
-$!
-$! Check To See If We Already Have A VAX C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A VAX C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable VAX C Runtime Library.
-!
-SYS$SHARE:VAXCRTL.EXE/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The VAXC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A GNU C Option File.
-$!
-$ IF (COMPILER.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If We Already Have A GNU C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A GNU C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable C Runtime Library.
-!
-GNU_CC:[000000]GCCLIB/LIBRARY
-SYS$SHARE:VAXCRTL/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A DEC C Option File.
-$!
-$ IF (COMPILER.EQS."DECC")
-$ THEN
-$!
-$! Check To See If We Already Have A DEC C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! Figure Out If We Need A non-VAX Or A VAX Linker Option File.
-$!
-$ IF (ARCH.EQS."VAX")
-$ THEN
-$!
-$! We Need A DEC C Linker Option File For VAX.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable DEC C Runtime Library.
-!
-SYS$SHARE:DECC$SHR.EXE/SHARE
-$EOD
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Create The non-VAX Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File For non-VAX To Link Agianst
-! The Sharable C Runtime Library.
-!
-SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
-SYS$SHARE:CMA$OPEN_RTL/SHARE
-$EOD
-$!
-$! End The DEC C Option File Check.
-$!
-$ ENDIF
-$!
-$! End The Option File Search.
-$!
-$ ENDIF
-$!
-$! End The DEC C Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What Linker Option File We Are Using.
-$!
-$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
-$!
-$! Time To RETURN.
-$!
-$ RETURN
-$ LIB_CHECK:
-$!
-$! Look For The VAX Library LIBSSL.OLB.
-$!
-$ IF (F$SEARCH(SSL_LIB).EQS."")
-$ THEN
-$!
-$! Tell The User We Can't Find The LIBSSL.OLB Library.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
-$ WRITE SYS$OUTPUT "We Can't Link Without It."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Since We Can't Link Without It, Exit.
-$!
-$ EXIT
-$!
-$! End The LIBSSL.OLB Library Check.
-$!
-$ ENDIF
-$!
-$! Look For The Library LIBCRYPTO.OLB.
-$!
-$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
-$ THEN
-$!
-$! Tell The User We Can't Find The LIBCRYPTO.OLB Library.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
-$ WRITE SYS$OUTPUT "We Can't Link Without It."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Since We Can't Link Without It, Exit.
-$!
-$ EXIT
-$!
-$! End The LIBCRYPTO.OLB Library Check.
-$!
-$ ENDIF
-$!
-$! Time To Return.
-$!
-$ RETURN
-$!
-$! Check The User's Options.
-$!
-$ CHECK_OPTIONS:
-$!
-$! Check To See If P1 Is Blank.
-$!
-$ IF (P1.EQS."ALL")
-$ THEN
-$!
-$! P1 Is Blank, So Build Everything.
-$!
-$ BUILDALL = "TRUE"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Else, Check To See If P1 Has A Valid Argument.
-$!
-$ IF (P1.EQS."LIBRARY").OR.(P1.EQS."SSL_TASK")
-$ THEN
-$!
-$! A Valid Argument.
-$!
-$ BUILDALL = P1
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALL : Just Build Everything."
-$ WRITE SYS$OUTPUT " LIBRARY : To Compile Just The [.xxx.EXE.SSL]LIBSSL.OLB Library."
-$ WRITE SYS$OUTPUT " SSL_TASK : To Compile Just The [.xxx.EXE.SSL]SSL_TASK.EXE Program."
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALPHA : Alpha Architecture."
-$ WRITE SYS$OUTPUT " IA64 : IA64 Architecture."
-$ WRITE SYS$OUTPUT " VAX : VAX Architecture."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P1 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P2 Is Blank.
-$!
-$ IF (P2.EQS."NODEBUG")
-$ THEN
-$!
-$! P2 Is NODEBUG, So Compile Without Debugger Information.
-$!
-$ DEBUGGER = "NODEBUG"
-$ TRACEBACK = "NOTRACEBACK"
-$ GCC_OPTIMIZE = "OPTIMIZE"
-$ CC_OPTIMIZE = "OPTIMIZE"
-$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Check To See If We Are To Compile With Debugger Information.
-$!
-$ IF (P2.EQS."DEBUG")
-$ THEN
-$!
-$! Compile With Debugger Information.
-$!
-$ DEBUGGER = "DEBUG"
-$ TRACEBACK = "TRACEBACK"
-$ GCC_OPTIMIZE = "NOOPTIMIZE"
-$ CC_OPTIMIZE = "NOOPTIMIZE"
-$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
-$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P2 Check.
-$!
-$ ENDIF
-$!
-$! Special Threads For OpenVMS v7.1 Or Later
-$!
-$! Written By: Richard Levitte
-$! richard@levitte.org
-$!
-$!
-$! Check To See If We Have A Option For P5.
-$!
-$ IF (P5.EQS."")
-$ THEN
-$!
-$! Get The Version Of VMS We Are Using.
-$!
-$ ISSEVEN :=
-$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
-$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
-$!
-$! Check To See If The VMS Version Is v7.1 Or Later.
-$!
-$ IF (TMP.GE.71)
-$ THEN
-$!
-$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
-$!
-$ ISSEVEN := ,PTHREAD_USE_D4
-$!
-$! End The VMS Version Check.
-$!
-$ ENDIF
-$!
-$! End The P5 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P6 Is Blank.
-$!
-$ IF (P6.EQS."")
-$ THEN
-$ POINTER_SIZE = ""
-$ ELSE
-$!
-$! Check is P6 Is Valid
-$!
-$ IF (P6.EQS."32")
-$ THEN
-$ POINTER_SIZE = "/POINTER_SIZE=32"
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ LIB32 = ""
-$ ELSE
-$ LIB32 = "32"
-$ ENDIF
-$ ELSE
-$ IF (P6.EQS."64")
-$ THEN
-$ LIB32 = ""
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ POINTER_SIZE = "/POINTER_SIZE=32"
-$ ELSE
-$ POINTER_SIZE = "/POINTER_SIZE=64"
-$ ENDIF
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P6," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " 32 : Compile with 32 bit pointer size"
-$ WRITE SYS$OUTPUT " 64 : Compile with 64 bit pointer size"
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ GOTO TIDY
-$!
-$! End The Valid Arguement Check.
-$!
-$ ENDIF
-$ ENDIF
-$!
-$! End The P6 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P3 Is Blank.
-$!
-$ IF (P3.EQS."")
-$ THEN
-$!
-$! O.K., The User Didn't Specify A Compiler, Let's Try To
-$! Find Out Which One To Use.
-$!
-$! Check To See If We Have GNU C.
-$!
-$ IF (F$TRNLNM("GNU_CC").NES."")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ P3 = "GNUC"
-$!
-$! End The GNU C Compiler Check.
-$!
-$ ELSE
-$!
-$! Check To See If We Have VAXC Or DECC.
-$!
-$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ P3 = "DECC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ P3 = "VAXC"
-$!
-$! End The VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The DECC & VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The Compiler Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Have A Option For P4.
-$!
-$ IF (P4.EQS."")
-$ THEN
-$!
-$! Find out what socket library we have available
-$!
-$ IF F$PARSE("SOCKETSHR:") .NES. ""
-$ THEN
-$!
-$! We have SOCKETSHR, and it is my opinion that it's the best to use.
-$!
-$ P4 = "SOCKETSHR"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
-$!
-$! Else, let's look for something else
-$!
-$ ELSE
-$!
-$! Like UCX (the reason to do this before Multinet is that the UCX
-$! emulation is easier to use...)
-$!
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
- .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
- .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
-$ THEN
-$!
-$! Last resort: a UCX or UCX-compatible library
-$!
-$ P4 = "UCX"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
-$!
-$! That was all...
-$!
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$!
-$! Set Up Initial CC Definitions, Possibly With User Ones
-$!
-$ CCDEFS = "TCPIP_TYPE_''P4'"
-$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
-$ CCEXTRAFLAGS = ""
-$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
-$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
-$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
- CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
-$!
-$! Check To See If The User Entered A Valid Paramter.
-$!
-$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If The User Wanted DECC.
-$!
-$ IF (P3.EQS."DECC")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ COMPILER = "DECC"
-$!
-$! Tell The User We Are Using DECC.
-$!
-$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
-$!
-$! Use DECC...
-$!
-$ CC = "CC"
-$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
- THEN CC = "CC/DECC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89''POINTER_SIZE'" + -
- "/NOLIST/PREFIX=ALL" + -
- "/INCLUDE=(SYS$DISK:[-.CRYPTO],SYS$DISK:[-])" + CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
-$!
-$! End DECC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use VAXC.
-$!
-$ IF (P3.EQS."VAXC")
-$ THEN
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ COMPILER = "VAXC"
-$!
-$! Tell The User We Are Using VAX C.
-$!
-$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
-$!
-$! Compile Using VAXC.
-$!
-$ CC = "CC"
-$ IF ARCH.NES."VAX"
-$ THEN
-$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
-$ EXIT
-$ ENDIF
-$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=(SYS$DISK:[-.CRYPTO],SYS$DISK:[-])" + CCEXTRAFLAGS
-$ CCDEFS = CCDEFS + ",""VAXC"""
-$!
-$! Define <sys> As SYS$COMMON:[SYSLIB]
-$!
-$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
-$!
-$! End VAXC Check
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use GNU C.
-$!
-$ IF (P3.EQS."GNUC")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ COMPILER = "GNUC"
-$!
-$! Tell The User We Are Using GNUC.
-$!
-$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
-$!
-$! Use GNU C...
-$!
-$ IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC
-$ CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=(SYS$DISK:[-.CRYPTO],SYS$DISK:[-])" + CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Set up default defines
-$!
-$ CCDEFS = """FLAT_INC=1""," + CCDEFS
-$!
-$! Finish up the definition of CC.
-$!
-$ IF COMPILER .EQS. "DECC"
-$ THEN
-$ IF CCDISABLEWARNINGS .EQS. ""
-$ THEN
-$ CC4DISABLEWARNINGS = "DOLLARID"
-$ ELSE
-$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
-$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
-$ ENDIF
-$ CC4DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
-$ ELSE
-$ CCDISABLEWARNINGS = ""
-$ CC4DISABLEWARNINGS = ""
-$ ENDIF
-$ CC2 = CC + "/DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS
-$ CC3 = CC + "/DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS
-$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
-$ IF COMPILER .EQS. "DECC"
-$ THEN
-$ CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
-$ CC5 = CC3 - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
-$ ELSE
-$ CC4 = CC
-$ CC5 = CC3
-$ ENDIF
-$!
-$! Show user the result
-$!
-$ WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
-$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
-$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$ ENDIF
-$!
-$! Time to check the contents, and to make sure we get the correct library.
-$!
-$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" -
- .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE"
-$ THEN
-$!
-$! Check to see if SOCKETSHR was chosen
-$!
-$ IF P4.EQS."SOCKETSHR"
-$ THEN
-$!
-$! Set the library to use SOCKETSHR
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT"
-$!
-$! Done with SOCKETSHR
-$!
-$ ENDIF
-$!
-$! Check to see if MULTINET was chosen
-$!
-$ IF P4.EQS."MULTINET"
-$ THEN
-$!
-$! Set the library to use UCX emulation.
-$!
-$ P4 = "UCX"
-$!
-$! Done with MULTINET
-$!
-$ ENDIF
-$!
-$! Check to see if UCX was chosen
-$!
-$ IF P4.EQS."UCX"
-$ THEN
-$!
-$! Set the library to use UCX.
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT"
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
-$ THEN
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT/OPT"
-$ ELSE
-$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
- TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT/OPT"
-$ ENDIF
-$!
-$! Done with UCX
-$!
-$ ENDIF
-$!
-$! Check to see if TCPIP was chosen
-$!
-$ IF P4.EQS."TCPIP"
-$ THEN
-$!
-$! Set the library to use TCPIP (post UCX).
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT"
-$!
-$! Done with TCPIP
-$!
-$ ENDIF
-$!
-$! Check to see if NONE was chosen
-$!
-$ IF P4.EQS."NONE"
-$ THEN
-$!
-$! Do not use a TCPIP library.
-$!
-$ TCPIP_LIB = ""
-$!
-$! Done with NONE
-$!
-$ ENDIF
-$!
-$! Print info
-$!
-$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P4," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
-$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
-$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! Done with TCP/IP libraries
-$!
-$ ENDIF
-$!
-$! Time To RETURN...
-$!
-$ RETURN
-$!
-$ INITIALISE:
-$!
-$! Save old value of the logical name OPENSSL
-$!
-$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
-$!
-$! Save directory information
-$!
-$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
-$ __HERE = F$EDIT(__HERE,"UPCASE")
-$ __TOP = __HERE - "SSL]"
-$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
-$!
-$! Set up the logical name OPENSSL to point at the include directory
-$!
-$ DEFINE OPENSSL/NOLOG '__INCLUDE'
-$!
-$! Done
-$!
-$ RETURN
-$!
-$ CLEANUP:
-$!
-$! Restore the logical name OPENSSL if it had a value
-$!
-$ IF __SAVE_OPENSSL .EQS. ""
-$ THEN
-$ DEASSIGN OPENSSL
-$ ELSE
-$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
-$ ENDIF
-$!
-$! Done
-$!
-$ RETURN
+$!
+$! SSL-LIB.COM
+$! Written By: Robert Byer
+$! Vice-President
+$! A-Com Computing, Inc.
+$! byer@mail.all-net.net
+$!
+$! Changes by Richard Levitte <richard@levitte.org>
+$!
+$! This command file compiles and creates the "[.xxx.EXE.SSL]LIBSSL.OLB"
+$! library for OpenSSL. The "xxx" denotes the machine architecture of
+$! ALPHA, IA64 or VAX.
+$!
+$! It is written to detect what type of machine you are compiling on
+$! (i.e. ALPHA or VAX) and which "C" compiler you have (i.e. VAXC, DECC
+$! or GNU C) or you can specify which compiler to use.
+$!
+$! Specify the following as P1 to build just that part or ALL to just
+$! build everything.
+$!
+$! LIBRARY To just compile the [.xxx.EXE.SSL]LIBSSL.OLB Library.
+$! SSL_TASK To just compile the [.xxx.EXE.SSL]SSL_TASK.EXE
+$!
+$! Specify DEBUG or NODEBUG as P2 to compile with or without debugger
+$! information.
+$!
+$! Specify which compiler at P3 to try to compile under.
+$!
+$! VAXC For VAX C.
+$! DECC For DEC C.
+$! GNUC For GNU C.
+$!
+$! If you don't specify a compiler, it will try to determine which
+$! "C" compiler to use.
+$!
+$! P4, if defined, sets a TCP/IP library to use, through one of the following
+$! keywords:
+$!
+$! UCX for UCX
+$! TCPIP for TCPIP (post UCX)
+$! SOCKETSHR for SOCKETSHR+NETLIB
+$!
+$! P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$! For 64 bit architectures (Alpha and IA64), specify the pointer size as P6.
+$! For 32 bit architectures (VAX), P6 is ignored.
+$! Currently supported values are:
+$!
+$! 32 To ge a library compiled with /POINTER_SIZE=32
+$! 64 To ge a library compiled with /POINTER_SIZE=64
+$!
+$!
+$! Define A TCP/IP Library That We Will Need To Link To.
+$! (That Is, If We Need To Link To One.)
+$!
+$ TCPIP_LIB = ""
+$!
+$! Check What Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$! The Architecture Is VAX.
+$!
+$ ARCH = "VAX"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$! Define The OBJ Directory.
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.SSL]
+$!
+$! Define The EXE Directory.
+$!
+$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.SSL]
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Initialise logical names and such
+$!
+$ GOSUB INITIALISE
+$!
+$! Tell The User What Kind of Machine We Run On.
+$!
+$ WRITE SYS$OUTPUT "Compiling On A ",ARCH," Machine."
+$!
+$! Check To See If The Architecture Specific OBJ Directory Exists.
+$!
+$ IF (F$PARSE(OBJ_DIR).EQS."")
+$ THEN
+$!
+$! It Dosen't Exist, So Create It.
+$!
+$ CREATE/DIR 'OBJ_DIR'
+$!
+$! End The Architecture Specific OBJ Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If The Architecture Specific Directory Exists.
+$!
+$ IF (F$PARSE(EXE_DIR).EQS."")
+$ THEN
+$!
+$! It Dosen't Exist, So Create It.
+$!
+$ CREATE/DIR 'EXE_DIR'
+$!
+$! End The Architecture Specific Directory Check.
+$!
+$ ENDIF
+$!
+$! Define The Library Name.
+$!
+$ SSL_LIB := 'EXE_DIR'LIBSSL'LIB32'.OLB
+$!
+$! Define The CRYPTO-LIB We Are To Use.
+$!
+$ CRYPTO_LIB := SYS$DISK:[-.'ARCH'.EXE.CRYPTO]LIBCRYPTO'LIB32'.OLB
+$!
+$! Check To See What We Are To Do.
+$!
+$ IF (BUILDALL.EQS."TRUE")
+$ THEN
+$!
+$! Since Nothing Special Was Specified, Do Everything.
+$!
+$ GOSUB LIBRARY
+$ GOSUB SSL_TASK
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Build Just What The User Wants Us To Build.
+$!
+$ GOSUB 'BUILDALL'
+$!
+$! End The BUILDALL Check.
+$!
+$ ENDIF
+$!
+$! Time To EXIT.
+$!
+$ EXIT:
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Compile The Library.
+$!
+$ LIBRARY:
+$!
+$! Check To See If We Already Have A "[.xxx.EXE.SSL]LIBSSL''LIB32'.OLB" Library...
+$!
+$ IF (F$SEARCH(SSL_LIB).EQS."")
+$ THEN
+$!
+$! Guess Not, Create The Library.
+$!
+$ LIBRARY/CREATE/OBJECT 'SSL_LIB'
+$!
+$! End The Library Exist Check.
+$!
+$ ENDIF
+$!
+$! Define The Different SSL "library" Files.
+$!
+$ LIB_SSL = "s2_meth,s2_srvr,s2_clnt,s2_lib,s2_enc,s2_pkt,"+ -
+ "s3_meth,s3_srvr,s3_clnt,s3_lib,s3_enc,s3_pkt,s3_both,"+ -
+ "s23_meth,s23_srvr,s23_clnt,s23_lib,s23_pkt,"+ -
+ "t1_meth,t1_srvr,t1_clnt,t1_lib,t1_enc,"+ -
+ "d1_meth,d1_srvr,d1_clnt,d1_lib,d1_pkt,"+ -
+ "d1_both,d1_enc,"+ -
+ "ssl_lib,ssl_err2,ssl_cert,ssl_sess,"+ -
+ "ssl_ciph,ssl_stat,ssl_rsa,"+ -
+ "ssl_asn1,ssl_txt,ssl_algs,"+ -
+ "bio_ssl,ssl_err,kssl,t1_reneg"
+$!
+$! Tell The User That We Are Compiling The Library.
+$!
+$ WRITE SYS$OUTPUT "Building The ",SSL_LIB," Library."
+$!
+$! Define A File Counter And Set It To "0"
+$!
+$ FILE_COUNTER = 0
+$!
+$! Top Of The File Loop.
+$!
+$ NEXT_FILE:
+$!
+$! O.K, Extract The File Name From The File List.
+$!
+$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",LIB_SSL)
+$!
+$! Check To See If We Are At The End Of The File List.
+$!
+$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
+$!
+$! Increment The Counter.
+$!
+$ FILE_COUNTER = FILE_COUNTER + 1
+$!
+$! Create The Source File Name.
+$!
+$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
+$!
+$! Create The Object File Name.
+$!
+$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
+$ ON WARNING THEN GOTO NEXT_FILE
+$!
+$! Check To See If The File We Want To Compile Is Actually There.
+$!
+$ IF (F$SEARCH(SOURCE_FILE).EQS."")
+$ THEN
+$!
+$! Tell The User That The File Dosen't Exist.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Exit The Build.
+$!
+$ EXIT
+$!
+$! End The File Exists Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What File We Are Compiling.
+$!
+$ WRITE SYS$OUTPUT " ",FILE_NAME,".c"
+$!
+$! Compile The File.
+$!
+$ ON ERROR THEN GOTO NEXT_FILE
+$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$!
+$! Add It To The Library.
+$!
+$ LIBRARY/REPLACE/OBJECT 'SSL_LIB' 'OBJECT_FILE'
+$!
+$! Time To Clean Up The Object File.
+$!
+$ DELETE 'OBJECT_FILE';*
+$!
+$! Go Back And Get The Next File Name.
+$!
+$ GOTO NEXT_FILE
+$!
+$! All Done With This Library.
+$!
+$ FILE_DONE:
+$!
+$! Tell The User That We Are All Done.
+$!
+$ WRITE SYS$OUTPUT "Library ",SSL_LIB," Compiled."
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$ SSL_TASK:
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Check To See If The File We Want To Compile Is Actually There.
+$!
+$ IF (F$SEARCH("SYS$DISK:[]SSL_TASK.C").EQS."")
+$ THEN
+$!
+$! Tell The User That The File Dosen't Exist.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The File SSL_TASK.C Dosen't Exist."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Exit The Build.
+$!
+$ EXIT
+$!
+$! End The SSL_TASK.C File Check.
+$!
+$ ENDIF
+$!
+$! Tell The User We Are Creating The SSL_TASK.
+$!
+$ WRITE SYS$OUTPUT "Creating SSL_TASK OSU HTTP SSL Engine."
+$!
+$! Compile The File.
+$!
+$ ON ERROR THEN GOTO SSL_TASK_END
+$ CC5/OBJECT='OBJ_DIR'SSL_TASK.OBJ SYS$DISK:[]SSL_TASK.C
+$!
+$! Link The Program.
+$! Check To See If We Are To Link With A Specific TCP/IP Library.
+$!
+$ IF (TCPIP_LIB.NES."")
+$ THEN
+$!
+$! Link With TCP/IP Library.
+$!
+$ LINK/'DEBUGGER'/'TRACEBACK'/EXE='EXE_DIR'SSL_TASK.EXE -
+ 'OBJ_DIR'SSL_TASK.OBJ, -
+ 'SSL_LIB'/LIBRARY,'CRYPTO_LIB'/LIBRARY, -
+ 'TCPIP_LIB','OPT_FILE'/OPTION
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Don't Link With TCP/IP Library.
+$!
+$ LINK/'DEBUGGER'/'TRACEBACK'/EXE='EXE_DIR'SSL_TASK.EXE -
+ 'OBJ_DIR'SSL_TASK.OBJ,-
+ 'SSL_LIB'/LIBRARY,'CRYPTO_LIB'/LIBRARY, -
+ 'OPT_FILE'/OPTION
+$!
+$! End The TCP/IP Library Check.
+$!
+$ ENDIF
+$!
+$! Time To Return.
+$!
+$SSL_TASK_END:
+$ RETURN
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$! Check To See If We Already Have A VAX C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A VAX C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE/SHARE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If We Already Have A GNU C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A GNU C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB/LIBRARY
+SYS$SHARE:VAXCRTL/SHARE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$! Check To See If We Already Have A DEC C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! Figure Out If We Need A non-VAX Or A VAX Linker Option File.
+$!
+$ IF (ARCH.EQS."VAX")
+$ THEN
+$!
+$! We Need A DEC C Linker Option File For VAX.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE/SHARE
+$EOD
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Create The non-VAX Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Agianst
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
+SYS$SHARE:CMA$OPEN_RTL/SHARE
+$EOD
+$!
+$! End The DEC C Option File Check.
+$!
+$ ENDIF
+$!
+$! End The Option File Search.
+$!
+$ ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$ LIB_CHECK:
+$!
+$! Look For The VAX Library LIBSSL.OLB.
+$!
+$ IF (F$SEARCH(SSL_LIB).EQS."")
+$ THEN
+$!
+$! Tell The User We Can't Find The LIBSSL.OLB Library.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
+$ WRITE SYS$OUTPUT "We Can't Link Without It."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Since We Can't Link Without It, Exit.
+$!
+$ EXIT
+$!
+$! End The LIBSSL.OLB Library Check.
+$!
+$ ENDIF
+$!
+$! Look For The Library LIBCRYPTO.OLB.
+$!
+$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
+$ THEN
+$!
+$! Tell The User We Can't Find The LIBCRYPTO.OLB Library.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
+$ WRITE SYS$OUTPUT "We Can't Link Without It."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Since We Can't Link Without It, Exit.
+$!
+$ EXIT
+$!
+$! End The LIBCRYPTO.OLB Library Check.
+$!
+$ ENDIF
+$!
+$! Time To Return.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."ALL")
+$ THEN
+$!
+$! P1 Is Blank, So Build Everything.
+$!
+$ BUILDALL = "TRUE"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Else, Check To See If P1 Has A Valid Argument.
+$!
+$ IF (P1.EQS."LIBRARY").OR.(P1.EQS."SSL_TASK")
+$ THEN
+$!
+$! A Valid Argument.
+$!
+$ BUILDALL = P1
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " ALL : Just Build Everything."
+$ WRITE SYS$OUTPUT " LIBRARY : To Compile Just The [.xxx.EXE.SSL]LIBSSL.OLB Library."
+$ WRITE SYS$OUTPUT " SSL_TASK : To Compile Just The [.xxx.EXE.SSL]SSL_TASK.EXE Program."
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " ALPHA : Alpha Architecture."
+$ WRITE SYS$OUTPUT " IA64 : IA64 Architecture."
+$ WRITE SYS$OUTPUT " VAX : VAX Architecture."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P2 Is Blank.
+$!
+$ IF (P2.EQS."NODEBUG")
+$ THEN
+$!
+$! P2 Is NODEBUG, So Compile Without Debugger Information.
+$!
+$ DEBUGGER = "NODEBUG"
+$ TRACEBACK = "NOTRACEBACK"
+$ GCC_OPTIMIZE = "OPTIMIZE"
+$ CC_OPTIMIZE = "OPTIMIZE"
+$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Check To See If We Are To Compile With Debugger Information.
+$!
+$ IF (P2.EQS."DEBUG")
+$ THEN
+$!
+$! Compile With Debugger Information.
+$!
+$ DEBUGGER = "DEBUG"
+$ TRACEBACK = "TRACEBACK"
+$ GCC_OPTIMIZE = "NOOPTIMIZE"
+$ CC_OPTIMIZE = "NOOPTIMIZE"
+$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
+$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Argument Check.
+$!
+$ ENDIF
+$!
+$! End The P2 Check.
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By: Richard Levitte
+$! richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P5.
+$!
+$ IF (P5.EQS."")
+$ THEN
+$!
+$! Get The Version Of VMS We Are Using.
+$!
+$ ISSEVEN :=
+$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$! Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$ IF (TMP.GE.71)
+$ THEN
+$!
+$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$ ISSEVEN := ,PTHREAD_USE_D4
+$!
+$! End The VMS Version Check.
+$!
+$ ENDIF
+$!
+$! End The P5 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P6 Is Blank.
+$!
+$ IF (P6.EQS."")
+$ THEN
+$ POINTER_SIZE = ""
+$ ELSE
+$!
+$! Check is P6 Is Valid
+$!
+$ IF (P6.EQS."32")
+$ THEN
+$ POINTER_SIZE = "/POINTER_SIZE=32"
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ LIB32 = ""
+$ ELSE
+$ LIB32 = "32"
+$ ENDIF
+$ ELSE
+$ IF (P6.EQS."64")
+$ THEN
+$ LIB32 = ""
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ POINTER_SIZE = "/POINTER_SIZE=32"
+$ ELSE
+$ POINTER_SIZE = "/POINTER_SIZE=64"
+$ ENDIF
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P6," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " 32 : Compile with 32 bit pointer size"
+$ WRITE SYS$OUTPUT " 64 : Compile with 64 bit pointer size"
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ GOTO TIDY
+$!
+$! End The Valid Arguement Check.
+$!
+$ ENDIF
+$ ENDIF
+$!
+$! End The P6 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P3 Is Blank.
+$!
+$ IF (P3.EQS."")
+$ THEN
+$!
+$! O.K., The User Didn't Specify A Compiler, Let's Try To
+$! Find Out Which One To Use.
+$!
+$! Check To See If We Have GNU C.
+$!
+$ IF (F$TRNLNM("GNU_CC").NES."")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ P3 = "GNUC"
+$!
+$! End The GNU C Compiler Check.
+$!
+$ ELSE
+$!
+$! Check To See If We Have VAXC Or DECC.
+$!
+$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ P3 = "DECC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ P3 = "VAXC"
+$!
+$! End The VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The DECC & VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For P4.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$! Find out what socket library we have available
+$!
+$ IF F$PARSE("SOCKETSHR:") .NES. ""
+$ THEN
+$!
+$! We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$ P4 = "SOCKETSHR"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$! Else, let's look for something else
+$!
+$ ELSE
+$!
+$! Like UCX (the reason to do this before Multinet is that the UCX
+$! emulation is easier to use...)
+$!
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+ .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+ .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$ THEN
+$!
+$! Last resort: a UCX or UCX-compatible library
+$!
+$ P4 = "UCX"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$! That was all...
+$!
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "TCPIP_TYPE_''P4'"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+ CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If The User Entered A Valid Paramter.
+$!
+$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If The User Wanted DECC.
+$!
+$ IF (P3.EQS."DECC")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ COMPILER = "DECC"
+$!
+$! Tell The User We Are Using DECC.
+$!
+$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$! Use DECC...
+$!
+$ CC = "CC"
+$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+ THEN CC = "CC/DECC"
+$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89''POINTER_SIZE'" + -
+ "/NOLIST/PREFIX=ALL" + -
+ "/INCLUDE=(SYS$DISK:[-.CRYPTO],SYS$DISK:[-])" + CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
+$!
+$! End DECC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use VAXC.
+$!
+$ IF (P3.EQS."VAXC")
+$ THEN
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ COMPILER = "VAXC"
+$!
+$! Tell The User We Are Using VAX C.
+$!
+$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$! Compile Using VAXC.
+$!
+$ CC = "CC"
+$ IF ARCH.NES."VAX"
+$ THEN
+$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
+$ EXIT
+$ ENDIF
+$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
+$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[-.CRYPTO],SYS$DISK:[-])" + CCEXTRAFLAGS
+$ CCDEFS = CCDEFS + ",""VAXC"""
+$!
+$! Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
+$!
+$! End VAXC Check
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use GNU C.
+$!
+$ IF (P3.EQS."GNUC")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ COMPILER = "GNUC"
+$!
+$! Tell The User We Are Using GNUC.
+$!
+$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$! Use GNU C...
+$!
+$ IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC
+$ CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[-.CRYPTO],SYS$DISK:[-])" + CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Set up default defines
+$!
+$ CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$! Finish up the definition of CC.
+$!
+$ IF COMPILER .EQS. "DECC"
+$ THEN
+$ IF CCDISABLEWARNINGS .EQS. ""
+$ THEN
+$ CC4DISABLEWARNINGS = "DOLLARID"
+$ ELSE
+$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
+$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$ ENDIF
+$ CC4DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
+$ ELSE
+$ CCDISABLEWARNINGS = ""
+$ CC4DISABLEWARNINGS = ""
+$ ENDIF
+$ CC2 = CC + "/DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS
+$ CC3 = CC + "/DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS
+$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$ IF COMPILER .EQS. "DECC"
+$ THEN
+$ CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
+$ CC5 = CC3 - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
+$ ELSE
+$ CC4 = CC
+$ CC5 = CC3
+$ ENDIF
+$!
+$! Show user the result
+$!
+$ WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
+$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
+$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$ ENDIF
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" -
+ .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE"
+$ THEN
+$!
+$! Check to see if SOCKETSHR was chosen
+$!
+$ IF P4.EQS."SOCKETSHR"
+$ THEN
+$!
+$! Set the library to use SOCKETSHR
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT"
+$!
+$! Done with SOCKETSHR
+$!
+$ ENDIF
+$!
+$! Check to see if MULTINET was chosen
+$!
+$ IF P4.EQS."MULTINET"
+$ THEN
+$!
+$! Set the library to use UCX emulation.
+$!
+$ P4 = "UCX"
+$!
+$! Done with MULTINET
+$!
+$ ENDIF
+$!
+$! Check to see if UCX was chosen
+$!
+$ IF P4.EQS."UCX"
+$ THEN
+$!
+$! Set the library to use UCX.
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT"
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$ THEN
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT/OPT"
+$ ELSE
+$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT/OPT"
+$ ENDIF
+$!
+$! Done with UCX
+$!
+$ ENDIF
+$!
+$! Check to see if TCPIP was chosen
+$!
+$ IF P4.EQS."TCPIP"
+$ THEN
+$!
+$! Set the library to use TCPIP (post UCX).
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT"
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Check to see if NONE was chosen
+$!
+$ IF P4.EQS."NONE"
+$ THEN
+$!
+$! Do not use a TCPIP library.
+$!
+$ TCPIP_LIB = ""
+$!
+$! Done with NONE
+$!
+$ ENDIF
+$!
+$! Print info
+$!
+$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
+$!
+$! Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P4," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
+$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
+$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "SSL]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL/NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the logical name OPENSSL if it had a value
+$!
+$ IF __SAVE_OPENSSL .EQS. ""
+$ THEN
+$ DEASSIGN OPENSSL
+$ ELSE
+$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
+$ ENDIF
+$!
+$! Done
+$!
+$ RETURN
diff --git a/openssl/ssl/t1_lib.c b/openssl/ssl/t1_lib.c
index 1ebad6166..85371c87b 100644
--- a/openssl/ssl/t1_lib.c
+++ b/openssl/ssl/t1_lib.c
@@ -1,1747 +1,1747 @@
-/* ssl/t1_lib.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-/* ====================================================================
- * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stdio.h>
-#include <openssl/objects.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/ocsp.h>
-#include "ssl_locl.h"
-
-const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
-
-#ifndef OPENSSL_NO_TLSEXT
-static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
- const unsigned char *sess_id, int sesslen,
- SSL_SESSION **psess);
-#endif
-
-SSL3_ENC_METHOD TLSv1_enc_data={
- tls1_enc,
- tls1_mac,
- tls1_setup_key_block,
- tls1_generate_master_secret,
- tls1_change_cipher_state,
- tls1_final_finish_mac,
- TLS1_FINISH_MAC_LENGTH,
- tls1_cert_verify_mac,
- TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
- TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
- tls1_alert_code,
- };
-
-long tls1_default_timeout(void)
- {
- /* 2 hours, the 24 hours mentioned in the TLSv1 spec
- * is way too long for http, the cache would over fill */
- return(60*60*2);
- }
-
-int tls1_new(SSL *s)
- {
- if (!ssl3_new(s)) return(0);
- s->method->ssl_clear(s);
- return(1);
- }
-
-void tls1_free(SSL *s)
- {
-#ifndef OPENSSL_NO_TLSEXT
- if (s->tlsext_session_ticket)
- {
- OPENSSL_free(s->tlsext_session_ticket);
- }
-#endif /* OPENSSL_NO_TLSEXT */
- ssl3_free(s);
- }
-
-void tls1_clear(SSL *s)
- {
- ssl3_clear(s);
- s->version=TLS1_VERSION;
- }
-
-#ifndef OPENSSL_NO_EC
-static int nid_list[] =
- {
- NID_sect163k1, /* sect163k1 (1) */
- NID_sect163r1, /* sect163r1 (2) */
- NID_sect163r2, /* sect163r2 (3) */
- NID_sect193r1, /* sect193r1 (4) */
- NID_sect193r2, /* sect193r2 (5) */
- NID_sect233k1, /* sect233k1 (6) */
- NID_sect233r1, /* sect233r1 (7) */
- NID_sect239k1, /* sect239k1 (8) */
- NID_sect283k1, /* sect283k1 (9) */
- NID_sect283r1, /* sect283r1 (10) */
- NID_sect409k1, /* sect409k1 (11) */
- NID_sect409r1, /* sect409r1 (12) */
- NID_sect571k1, /* sect571k1 (13) */
- NID_sect571r1, /* sect571r1 (14) */
- NID_secp160k1, /* secp160k1 (15) */
- NID_secp160r1, /* secp160r1 (16) */
- NID_secp160r2, /* secp160r2 (17) */
- NID_secp192k1, /* secp192k1 (18) */
- NID_X9_62_prime192v1, /* secp192r1 (19) */
- NID_secp224k1, /* secp224k1 (20) */
- NID_secp224r1, /* secp224r1 (21) */
- NID_secp256k1, /* secp256k1 (22) */
- NID_X9_62_prime256v1, /* secp256r1 (23) */
- NID_secp384r1, /* secp384r1 (24) */
- NID_secp521r1 /* secp521r1 (25) */
- };
-
-int tls1_ec_curve_id2nid(int curve_id)
- {
- /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
- if ((curve_id < 1) || ((unsigned int)curve_id >
- sizeof(nid_list)/sizeof(nid_list[0])))
- return 0;
- return nid_list[curve_id-1];
- }
-
-int tls1_ec_nid2curve_id(int nid)
- {
- /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
- switch (nid)
- {
- case NID_sect163k1: /* sect163k1 (1) */
- return 1;
- case NID_sect163r1: /* sect163r1 (2) */
- return 2;
- case NID_sect163r2: /* sect163r2 (3) */
- return 3;
- case NID_sect193r1: /* sect193r1 (4) */
- return 4;
- case NID_sect193r2: /* sect193r2 (5) */
- return 5;
- case NID_sect233k1: /* sect233k1 (6) */
- return 6;
- case NID_sect233r1: /* sect233r1 (7) */
- return 7;
- case NID_sect239k1: /* sect239k1 (8) */
- return 8;
- case NID_sect283k1: /* sect283k1 (9) */
- return 9;
- case NID_sect283r1: /* sect283r1 (10) */
- return 10;
- case NID_sect409k1: /* sect409k1 (11) */
- return 11;
- case NID_sect409r1: /* sect409r1 (12) */
- return 12;
- case NID_sect571k1: /* sect571k1 (13) */
- return 13;
- case NID_sect571r1: /* sect571r1 (14) */
- return 14;
- case NID_secp160k1: /* secp160k1 (15) */
- return 15;
- case NID_secp160r1: /* secp160r1 (16) */
- return 16;
- case NID_secp160r2: /* secp160r2 (17) */
- return 17;
- case NID_secp192k1: /* secp192k1 (18) */
- return 18;
- case NID_X9_62_prime192v1: /* secp192r1 (19) */
- return 19;
- case NID_secp224k1: /* secp224k1 (20) */
- return 20;
- case NID_secp224r1: /* secp224r1 (21) */
- return 21;
- case NID_secp256k1: /* secp256k1 (22) */
- return 22;
- case NID_X9_62_prime256v1: /* secp256r1 (23) */
- return 23;
- case NID_secp384r1: /* secp384r1 (24) */
- return 24;
- case NID_secp521r1: /* secp521r1 (25) */
- return 25;
- default:
- return 0;
- }
- }
-#endif /* OPENSSL_NO_EC */
-
-#ifndef OPENSSL_NO_TLSEXT
-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
- {
- int extdatalen=0;
- unsigned char *ret = p;
-
- /* don't add extensions for SSLv3 unless doing secure renegotiation */
- if (s->client_version == SSL3_VERSION
- && !s->s3->send_connection_binding)
- return p;
-
- ret+=2;
-
- if (ret>=limit) return NULL; /* this really never occurs, but ... */
-
- if (s->tlsext_hostname != NULL)
- {
- /* Add TLS extension servername to the Client Hello message */
- unsigned long size_str;
- long lenmax;
-
- /* check for enough space.
- 4 for the servername type and entension length
- 2 for servernamelist length
- 1 for the hostname type
- 2 for hostname length
- + hostname length
- */
-
- if ((lenmax = limit - ret - 9) < 0
- || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax)
- return NULL;
-
- /* extension type and length */
- s2n(TLSEXT_TYPE_server_name,ret);
- s2n(size_str+5,ret);
-
- /* length of servername list */
- s2n(size_str+3,ret);
-
- /* hostname type, length and hostname */
- *(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name;
- s2n(size_str,ret);
- memcpy(ret, s->tlsext_hostname, size_str);
- ret+=size_str;
- }
-
- /* Add RI if renegotiating */
- if (s->new_session)
- {
- int el;
-
- if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
- {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- if((limit - p - 4 - el) < 0) return NULL;
-
- s2n(TLSEXT_TYPE_renegotiate,ret);
- s2n(el,ret);
-
- if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
- {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- ret += el;
- }
-
-#ifndef OPENSSL_NO_EC
- if (s->tlsext_ecpointformatlist != NULL &&
- s->version != DTLS1_VERSION)
- {
- /* Add TLS extension ECPointFormats to the ClientHello message */
- long lenmax;
-
- if ((lenmax = limit - ret - 5) < 0) return NULL;
- if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
- if (s->tlsext_ecpointformatlist_length > 255)
- {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- s2n(TLSEXT_TYPE_ec_point_formats,ret);
- s2n(s->tlsext_ecpointformatlist_length + 1,ret);
- *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
- memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
- ret+=s->tlsext_ecpointformatlist_length;
- }
- if (s->tlsext_ellipticcurvelist != NULL &&
- s->version != DTLS1_VERSION)
- {
- /* Add TLS extension EllipticCurves to the ClientHello message */
- long lenmax;
-
- if ((lenmax = limit - ret - 6) < 0) return NULL;
- if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) return NULL;
- if (s->tlsext_ellipticcurvelist_length > 65532)
- {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- s2n(TLSEXT_TYPE_elliptic_curves,ret);
- s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
-
- /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
- * elliptic_curve_list, but the examples use two bytes.
- * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
- * resolves this to two bytes.
- */
- s2n(s->tlsext_ellipticcurvelist_length, ret);
- memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
- ret+=s->tlsext_ellipticcurvelist_length;
- }
-#endif /* OPENSSL_NO_EC */
-
- if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
- {
- int ticklen;
- if (!s->new_session && s->session && s->session->tlsext_tick)
- ticklen = s->session->tlsext_ticklen;
- else if (s->session && s->tlsext_session_ticket &&
- s->tlsext_session_ticket->data)
- {
- ticklen = s->tlsext_session_ticket->length;
- s->session->tlsext_tick = OPENSSL_malloc(ticklen);
- if (!s->session->tlsext_tick)
- return NULL;
- memcpy(s->session->tlsext_tick,
- s->tlsext_session_ticket->data,
- ticklen);
- s->session->tlsext_ticklen = ticklen;
- }
- else
- ticklen = 0;
- if (ticklen == 0 && s->tlsext_session_ticket &&
- s->tlsext_session_ticket->data == NULL)
- goto skip_ext;
- /* Check for enough room 2 for extension type, 2 for len
- * rest for ticket
- */
- if ((long)(limit - ret - 4 - ticklen) < 0) return NULL;
- s2n(TLSEXT_TYPE_session_ticket,ret);
- s2n(ticklen,ret);
- if (ticklen)
- {
- memcpy(ret, s->session->tlsext_tick, ticklen);
- ret += ticklen;
- }
- }
- skip_ext:
-
-#ifdef TLSEXT_TYPE_opaque_prf_input
- if (s->s3->client_opaque_prf_input != NULL &&
- s->version != DTLS1_VERSION)
- {
- size_t col = s->s3->client_opaque_prf_input_len;
-
- if ((long)(limit - ret - 6 - col < 0))
- return NULL;
- if (col > 0xFFFD) /* can't happen */
- return NULL;
-
- s2n(TLSEXT_TYPE_opaque_prf_input, ret);
- s2n(col + 2, ret);
- s2n(col, ret);
- memcpy(ret, s->s3->client_opaque_prf_input, col);
- ret += col;
- }
-#endif
-
- if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp &&
- s->version != DTLS1_VERSION)
- {
- int i;
- long extlen, idlen, itmp;
- OCSP_RESPID *id;
-
- idlen = 0;
- for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
- {
- id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
- itmp = i2d_OCSP_RESPID(id, NULL);
- if (itmp <= 0)
- return NULL;
- idlen += itmp + 2;
- }
-
- if (s->tlsext_ocsp_exts)
- {
- extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
- if (extlen < 0)
- return NULL;
- }
- else
- extlen = 0;
-
- if ((long)(limit - ret - 7 - extlen - idlen) < 0) return NULL;
- s2n(TLSEXT_TYPE_status_request, ret);
- if (extlen + idlen > 0xFFF0)
- return NULL;
- s2n(extlen + idlen + 5, ret);
- *(ret++) = TLSEXT_STATUSTYPE_ocsp;
- s2n(idlen, ret);
- for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
- {
- /* save position of id len */
- unsigned char *q = ret;
- id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
- /* skip over id len */
- ret += 2;
- itmp = i2d_OCSP_RESPID(id, &ret);
- /* write id len */
- s2n(itmp, q);
- }
- s2n(extlen, ret);
- if (extlen > 0)
- i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
- }
-
- if ((extdatalen = ret-p-2)== 0)
- return p;
-
- s2n(extdatalen,p);
- return ret;
- }
-
-unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
- {
- int extdatalen=0;
- unsigned char *ret = p;
-
- /* don't add extensions for SSLv3, unless doing secure renegotiation */
- if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
- return p;
-
- ret+=2;
- if (ret>=limit) return NULL; /* this really never occurs, but ... */
-
- if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
- {
- if ((long)(limit - ret - 4) < 0) return NULL;
-
- s2n(TLSEXT_TYPE_server_name,ret);
- s2n(0,ret);
- }
-
- if(s->s3->send_connection_binding)
- {
- int el;
-
- if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0))
- {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- if((limit - p - 4 - el) < 0) return NULL;
-
- s2n(TLSEXT_TYPE_renegotiate,ret);
- s2n(el,ret);
-
- if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el))
- {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- ret += el;
- }
-
-#ifndef OPENSSL_NO_EC
- if (s->tlsext_ecpointformatlist != NULL &&
- s->version != DTLS1_VERSION)
- {
- /* Add TLS extension ECPointFormats to the ServerHello message */
- long lenmax;
-
- if ((lenmax = limit - ret - 5) < 0) return NULL;
- if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
- if (s->tlsext_ecpointformatlist_length > 255)
- {
- SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- s2n(TLSEXT_TYPE_ec_point_formats,ret);
- s2n(s->tlsext_ecpointformatlist_length + 1,ret);
- *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
- memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
- ret+=s->tlsext_ecpointformatlist_length;
-
- }
- /* Currently the server should not respond with a SupportedCurves extension */
-#endif /* OPENSSL_NO_EC */
-
- if (s->tlsext_ticket_expected
- && !(SSL_get_options(s) & SSL_OP_NO_TICKET))
- {
- if ((long)(limit - ret - 4) < 0) return NULL;
- s2n(TLSEXT_TYPE_session_ticket,ret);
- s2n(0,ret);
- }
-
- if (s->tlsext_status_expected)
- {
- if ((long)(limit - ret - 4) < 0) return NULL;
- s2n(TLSEXT_TYPE_status_request,ret);
- s2n(0,ret);
- }
-
-#ifdef TLSEXT_TYPE_opaque_prf_input
- if (s->s3->server_opaque_prf_input != NULL &&
- s->version != DTLS1_VERSION)
- {
- size_t sol = s->s3->server_opaque_prf_input_len;
-
- if ((long)(limit - ret - 6 - sol) < 0)
- return NULL;
- if (sol > 0xFFFD) /* can't happen */
- return NULL;
-
- s2n(TLSEXT_TYPE_opaque_prf_input, ret);
- s2n(sol + 2, ret);
- s2n(sol, ret);
- memcpy(ret, s->s3->server_opaque_prf_input, sol);
- ret += sol;
- }
-#endif
- if (((s->s3->tmp.new_cipher->id & 0xFFFF)==0x80 || (s->s3->tmp.new_cipher->id & 0xFFFF)==0x81)
- && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG))
- { const unsigned char cryptopro_ext[36] = {
- 0xfd, 0xe8, /*65000*/
- 0x00, 0x20, /*32 bytes length*/
- 0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85,
- 0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06,
- 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
- 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17};
- if (limit-ret<36) return NULL;
- memcpy(ret,cryptopro_ext,36);
- ret+=36;
-
- }
-
- if ((extdatalen = ret-p-2)== 0)
- return p;
-
- s2n(extdatalen,p);
- return ret;
- }
-
-int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
- {
- unsigned short type;
- unsigned short size;
- unsigned short len;
- unsigned char *data = *p;
- int renegotiate_seen = 0;
-
- s->servername_done = 0;
- s->tlsext_status_type = -1;
-
- if (data >= (d+n-2))
- goto ri_check;
- n2s(data,len);
-
- if (data > (d+n-len))
- goto ri_check;
-
- while (data <= (d+n-4))
- {
- n2s(data,type);
- n2s(data,size);
-
- if (data+size > (d+n))
- goto ri_check;
-#if 0
- fprintf(stderr,"Received extension type %d size %d\n",type,size);
-#endif
- if (s->tlsext_debug_cb)
- s->tlsext_debug_cb(s, 0, type, data, size,
- s->tlsext_debug_arg);
-/* The servername extension is treated as follows:
-
- - Only the hostname type is supported with a maximum length of 255.
- - The servername is rejected if too long or if it contains zeros,
- in which case an fatal alert is generated.
- - The servername field is maintained together with the session cache.
- - When a session is resumed, the servername call back invoked in order
- to allow the application to position itself to the right context.
- - The servername is acknowledged if it is new for a session or when
- it is identical to a previously used for the same session.
- Applications can control the behaviour. They can at any time
- set a 'desirable' servername for a new SSL object. This can be the
- case for example with HTTPS when a Host: header field is received and
- a renegotiation is requested. In this case, a possible servername
- presented in the new client hello is only acknowledged if it matches
- the value of the Host: field.
- - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
- if they provide for changing an explicit servername context for the session,
- i.e. when the session has been established with a servername extension.
- - On session reconnect, the servername extension may be absent.
-
-*/
-
- if (type == TLSEXT_TYPE_server_name)
- {
- unsigned char *sdata;
- int servname_type;
- int dsize;
-
- if (size < 2)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- n2s(data,dsize);
- size -= 2;
- if (dsize > size )
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- sdata = data;
- while (dsize > 3)
- {
- servname_type = *(sdata++);
- n2s(sdata,len);
- dsize -= 3;
-
- if (len > dsize)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- if (s->servername_done == 0)
- switch (servname_type)
- {
- case TLSEXT_NAMETYPE_host_name:
- if (!s->hit)
- {
- if(s->session->tlsext_hostname)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- if (len > TLSEXT_MAXLEN_host_name)
- {
- *al = TLS1_AD_UNRECOGNIZED_NAME;
- return 0;
- }
- if ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL)
- {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- memcpy(s->session->tlsext_hostname, sdata, len);
- s->session->tlsext_hostname[len]='\0';
- if (strlen(s->session->tlsext_hostname) != len) {
- OPENSSL_free(s->session->tlsext_hostname);
- s->session->tlsext_hostname = NULL;
- *al = TLS1_AD_UNRECOGNIZED_NAME;
- return 0;
- }
- s->servername_done = 1;
-
- }
- else
- s->servername_done = s->session->tlsext_hostname
- && strlen(s->session->tlsext_hostname) == len
- && strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0;
-
- break;
-
- default:
- break;
- }
-
- dsize -= len;
- }
- if (dsize != 0)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- }
-
-#ifndef OPENSSL_NO_EC
- else if (type == TLSEXT_TYPE_ec_point_formats &&
- s->version != DTLS1_VERSION)
- {
- unsigned char *sdata = data;
- int ecpointformatlist_length = *(sdata++);
-
- if (ecpointformatlist_length != size - 1)
- {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
- if (!s->hit)
- {
- if(s->session->tlsext_ecpointformatlist)
- {
- OPENSSL_free(s->session->tlsext_ecpointformatlist);
- s->session->tlsext_ecpointformatlist = NULL;
- }
- s->session->tlsext_ecpointformatlist_length = 0;
- if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
- {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
- memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
- }
-#if 0
- fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", s->session->tlsext_ecpointformatlist_length);
- sdata = s->session->tlsext_ecpointformatlist;
- for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
- fprintf(stderr,"%i ",*(sdata++));
- fprintf(stderr,"\n");
-#endif
- }
- else if (type == TLSEXT_TYPE_elliptic_curves &&
- s->version != DTLS1_VERSION)
- {
- unsigned char *sdata = data;
- int ellipticcurvelist_length = (*(sdata++) << 8);
- ellipticcurvelist_length += (*(sdata++));
-
- if (ellipticcurvelist_length != size - 2)
- {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
- if (!s->hit)
- {
- if(s->session->tlsext_ellipticcurvelist)
- {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
- s->session->tlsext_ellipticcurvelist_length = 0;
- if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL)
- {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length;
- memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length);
- }
-#if 0
- fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", s->session->tlsext_ellipticcurvelist_length);
- sdata = s->session->tlsext_ellipticcurvelist;
- for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++)
- fprintf(stderr,"%i ",*(sdata++));
- fprintf(stderr,"\n");
-#endif
- }
-#endif /* OPENSSL_NO_EC */
-#ifdef TLSEXT_TYPE_opaque_prf_input
- else if (type == TLSEXT_TYPE_opaque_prf_input &&
- s->version != DTLS1_VERSION)
- {
- unsigned char *sdata = data;
-
- if (size < 2)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- n2s(sdata, s->s3->client_opaque_prf_input_len);
- if (s->s3->client_opaque_prf_input_len != size - 2)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */
- OPENSSL_free(s->s3->client_opaque_prf_input);
- if (s->s3->client_opaque_prf_input_len == 0)
- s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
- else
- s->s3->client_opaque_prf_input = BUF_memdup(sdata, s->s3->client_opaque_prf_input_len);
- if (s->s3->client_opaque_prf_input == NULL)
- {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- }
-#endif
- else if (type == TLSEXT_TYPE_session_ticket)
- {
- if (s->tls_session_ticket_ext_cb &&
- !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
- {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- }
- else if (type == TLSEXT_TYPE_renegotiate)
- {
- if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
- return 0;
- renegotiate_seen = 1;
- }
- else if (type == TLSEXT_TYPE_status_request &&
- s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb)
- {
-
- if (size < 5)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- s->tlsext_status_type = *data++;
- size--;
- if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
- {
- const unsigned char *sdata;
- int dsize;
- /* Read in responder_id_list */
- n2s(data,dsize);
- size -= 2;
- if (dsize > size )
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- while (dsize > 0)
- {
- OCSP_RESPID *id;
- int idsize;
- if (dsize < 4)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- n2s(data, idsize);
- dsize -= 2 + idsize;
- size -= 2 + idsize;
- if (dsize < 0)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- sdata = data;
- data += idsize;
- id = d2i_OCSP_RESPID(NULL,
- &sdata, idsize);
- if (!id)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- if (data != sdata)
- {
- OCSP_RESPID_free(id);
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- if (!s->tlsext_ocsp_ids
- && !(s->tlsext_ocsp_ids =
- sk_OCSP_RESPID_new_null()))
- {
- OCSP_RESPID_free(id);
- *al = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- if (!sk_OCSP_RESPID_push(
- s->tlsext_ocsp_ids, id))
- {
- OCSP_RESPID_free(id);
- *al = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- }
-
- /* Read in request_extensions */
- if (size < 2)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- n2s(data,dsize);
- size -= 2;
- if (dsize != size)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- sdata = data;
- if (dsize > 0)
- {
- s->tlsext_ocsp_exts =
- d2i_X509_EXTENSIONS(NULL,
- &sdata, dsize);
- if (!s->tlsext_ocsp_exts
- || (data + dsize != sdata))
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- }
- }
- /* We don't know what to do with any other type
- * so ignore it.
- */
- else
- s->tlsext_status_type = -1;
- }
-
- /* session ticket processed earlier */
- data+=size;
- }
-
- *p = data;
-
- ri_check:
-
- /* Need RI if renegotiating */
-
- if (!renegotiate_seen && s->new_session &&
- !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
- {
- *al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT,
- SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
- return 0;
- }
-
- return 1;
- }
-
-int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
- {
- unsigned short length;
- unsigned short type;
- unsigned short size;
- unsigned char *data = *p;
- int tlsext_servername = 0;
- int renegotiate_seen = 0;
-
- if (data >= (d+n-2))
- goto ri_check;
-
- n2s(data,length);
- if (data+length != d+n)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- while(data <= (d+n-4))
- {
- n2s(data,type);
- n2s(data,size);
-
- if (data+size > (d+n))
- goto ri_check;
-
- if (s->tlsext_debug_cb)
- s->tlsext_debug_cb(s, 1, type, data, size,
- s->tlsext_debug_arg);
-
- if (type == TLSEXT_TYPE_server_name)
- {
- if (s->tlsext_hostname == NULL || size > 0)
- {
- *al = TLS1_AD_UNRECOGNIZED_NAME;
- return 0;
- }
- tlsext_servername = 1;
- }
-
-#ifndef OPENSSL_NO_EC
- else if (type == TLSEXT_TYPE_ec_point_formats &&
- s->version != DTLS1_VERSION)
- {
- unsigned char *sdata = data;
- int ecpointformatlist_length = *(sdata++);
-
- if (ecpointformatlist_length != size - 1)
- {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
- s->session->tlsext_ecpointformatlist_length = 0;
- if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
- if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
- {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
- memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
-#if 0
- fprintf(stderr,"ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
- sdata = s->session->tlsext_ecpointformatlist;
- for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
- fprintf(stderr,"%i ",*(sdata++));
- fprintf(stderr,"\n");
-#endif
- }
-#endif /* OPENSSL_NO_EC */
-
- else if (type == TLSEXT_TYPE_session_ticket)
- {
- if (s->tls_session_ticket_ext_cb &&
- !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
- {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
- || (size > 0))
- {
- *al = TLS1_AD_UNSUPPORTED_EXTENSION;
- return 0;
- }
- s->tlsext_ticket_expected = 1;
- }
-#ifdef TLSEXT_TYPE_opaque_prf_input
- else if (type == TLSEXT_TYPE_opaque_prf_input &&
- s->version != DTLS1_VERSION)
- {
- unsigned char *sdata = data;
-
- if (size < 2)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- n2s(sdata, s->s3->server_opaque_prf_input_len);
- if (s->s3->server_opaque_prf_input_len != size - 2)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- if (s->s3->server_opaque_prf_input != NULL) /* shouldn't really happen */
- OPENSSL_free(s->s3->server_opaque_prf_input);
- if (s->s3->server_opaque_prf_input_len == 0)
- s->s3->server_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
- else
- s->s3->server_opaque_prf_input = BUF_memdup(sdata, s->s3->server_opaque_prf_input_len);
-
- if (s->s3->server_opaque_prf_input == NULL)
- {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- }
-#endif
- else if (type == TLSEXT_TYPE_status_request &&
- s->version != DTLS1_VERSION)
- {
- /* MUST be empty and only sent if we've requested
- * a status request message.
- */
- if ((s->tlsext_status_type == -1) || (size > 0))
- {
- *al = TLS1_AD_UNSUPPORTED_EXTENSION;
- return 0;
- }
- /* Set flag to expect CertificateStatus message */
- s->tlsext_status_expected = 1;
- }
- else if (type == TLSEXT_TYPE_renegotiate)
- {
- if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
- return 0;
- renegotiate_seen = 1;
- }
- data+=size;
- }
-
- if (data != d+n)
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- if (!s->hit && tlsext_servername == 1)
- {
- if (s->tlsext_hostname)
- {
- if (s->session->tlsext_hostname == NULL)
- {
- s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
- if (!s->session->tlsext_hostname)
- {
- *al = SSL_AD_UNRECOGNIZED_NAME;
- return 0;
- }
- }
- else
- {
- *al = SSL_AD_DECODE_ERROR;
- return 0;
- }
- }
- }
-
- *p = data;
-
- ri_check:
-
- /* Determine if we need to see RI. Strictly speaking if we want to
- * avoid an attack we should *always* see RI even on initial server
- * hello because the client doesn't see any renegotiation during an
- * attack. However this would mean we could not connect to any server
- * which doesn't support RI so for the immediate future tolerate RI
- * absence on initial connect only.
- */
- if (!renegotiate_seen
- && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
- && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
- {
- *al = SSL_AD_HANDSHAKE_FAILURE;
- SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT,
- SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
- return 0;
- }
-
- return 1;
- }
-
-
-int ssl_prepare_clienthello_tlsext(SSL *s)
- {
-#ifndef OPENSSL_NO_EC
- /* If we are client and using an elliptic curve cryptography cipher suite, send the point formats
- * and elliptic curves we support.
- */
- int using_ecc = 0;
- int i;
- unsigned char *j;
- unsigned long alg_k, alg_a;
- STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
-
- for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++)
- {
- SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
-
- alg_k = c->algorithm_mkey;
- alg_a = c->algorithm_auth;
- if ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe) || (alg_a & SSL_aECDSA)))
- {
- using_ecc = 1;
- break;
- }
- }
- using_ecc = using_ecc && (s->version == TLS1_VERSION);
- if (using_ecc)
- {
- if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
- if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL)
- {
- SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
- return -1;
- }
- s->tlsext_ecpointformatlist_length = 3;
- s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
- s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
- s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
-
- /* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
- if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist);
- s->tlsext_ellipticcurvelist_length = sizeof(nid_list)/sizeof(nid_list[0]) * 2;
- if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
- {
- s->tlsext_ellipticcurvelist_length = 0;
- SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
- return -1;
- }
- for (i = 1, j = s->tlsext_ellipticcurvelist; (unsigned int)i <=
- sizeof(nid_list)/sizeof(nid_list[0]); i++)
- s2n(i,j);
- }
-#endif /* OPENSSL_NO_EC */
-
-#ifdef TLSEXT_TYPE_opaque_prf_input
- {
- int r = 1;
-
- if (s->ctx->tlsext_opaque_prf_input_callback != 0)
- {
- r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg);
- if (!r)
- return -1;
- }
-
- if (s->tlsext_opaque_prf_input != NULL)
- {
- if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */
- OPENSSL_free(s->s3->client_opaque_prf_input);
-
- if (s->tlsext_opaque_prf_input_len == 0)
- s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
- else
- s->s3->client_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len);
- if (s->s3->client_opaque_prf_input == NULL)
- {
- SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
- return -1;
- }
- s->s3->client_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
- }
-
- if (r == 2)
- /* at callback's request, insist on receiving an appropriate server opaque PRF input */
- s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
- }
-#endif
-
- return 1;
- }
-
-int ssl_prepare_serverhello_tlsext(SSL *s)
- {
-#ifndef OPENSSL_NO_EC
- /* If we are server and using an ECC cipher suite, send the point formats we support
- * if the client sent us an ECPointsFormat extension. Note that the server is not
- * supposed to send an EllipticCurves extension.
- */
-
- unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
- int using_ecc = (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA);
- using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
-
- if (using_ecc)
- {
- if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
- if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL)
- {
- SSLerr(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
- return -1;
- }
- s->tlsext_ecpointformatlist_length = 3;
- s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
- s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
- s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
- }
-#endif /* OPENSSL_NO_EC */
-
- return 1;
- }
-
-int ssl_check_clienthello_tlsext(SSL *s)
- {
- int ret=SSL_TLSEXT_ERR_NOACK;
- int al = SSL_AD_UNRECOGNIZED_NAME;
-
-#ifndef OPENSSL_NO_EC
- /* The handling of the ECPointFormats extension is done elsewhere, namely in
- * ssl3_choose_cipher in s3_lib.c.
- */
- /* The handling of the EllipticCurves extension is done elsewhere, namely in
- * ssl3_choose_cipher in s3_lib.c.
- */
-#endif
-
- if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
- ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
- else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0)
- ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
-
- /* If status request then ask callback what to do.
- * Note: this must be called after servername callbacks in case
- * the certificate has changed.
- */
- if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb)
- {
- int r;
- r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
- switch (r)
- {
- /* We don't want to send a status request response */
- case SSL_TLSEXT_ERR_NOACK:
- s->tlsext_status_expected = 0;
- break;
- /* status request response should be sent */
- case SSL_TLSEXT_ERR_OK:
- if (s->tlsext_ocsp_resp)
- s->tlsext_status_expected = 1;
- else
- s->tlsext_status_expected = 0;
- break;
- /* something bad happened */
- case SSL_TLSEXT_ERR_ALERT_FATAL:
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_INTERNAL_ERROR;
- goto err;
- }
- }
- else
- s->tlsext_status_expected = 0;
-
-#ifdef TLSEXT_TYPE_opaque_prf_input
- {
- /* This sort of belongs into ssl_prepare_serverhello_tlsext(),
- * but we might be sending an alert in response to the client hello,
- * so this has to happen here in ssl_check_clienthello_tlsext(). */
-
- int r = 1;
-
- if (s->ctx->tlsext_opaque_prf_input_callback != 0)
- {
- r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg);
- if (!r)
- {
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_INTERNAL_ERROR;
- goto err;
- }
- }
-
- if (s->s3->server_opaque_prf_input != NULL) /* shouldn't really happen */
- OPENSSL_free(s->s3->server_opaque_prf_input);
- s->s3->server_opaque_prf_input = NULL;
-
- if (s->tlsext_opaque_prf_input != NULL)
- {
- if (s->s3->client_opaque_prf_input != NULL &&
- s->s3->client_opaque_prf_input_len == s->tlsext_opaque_prf_input_len)
- {
- /* can only use this extension if we have a server opaque PRF input
- * of the same length as the client opaque PRF input! */
-
- if (s->tlsext_opaque_prf_input_len == 0)
- s->s3->server_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
- else
- s->s3->server_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len);
- if (s->s3->server_opaque_prf_input == NULL)
- {
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_INTERNAL_ERROR;
- goto err;
- }
- s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
- }
- }
-
- if (r == 2 && s->s3->server_opaque_prf_input == NULL)
- {
- /* The callback wants to enforce use of the extension,
- * but we can't do that with the client opaque PRF input;
- * abort the handshake.
- */
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_HANDSHAKE_FAILURE;
- }
- }
-
-#endif
- err:
- switch (ret)
- {
- case SSL_TLSEXT_ERR_ALERT_FATAL:
- ssl3_send_alert(s,SSL3_AL_FATAL,al);
- return -1;
-
- case SSL_TLSEXT_ERR_ALERT_WARNING:
- ssl3_send_alert(s,SSL3_AL_WARNING,al);
- return 1;
-
- case SSL_TLSEXT_ERR_NOACK:
- s->servername_done=0;
- default:
- return 1;
- }
- }
-
-int ssl_check_serverhello_tlsext(SSL *s)
- {
- int ret=SSL_TLSEXT_ERR_NOACK;
- int al = SSL_AD_UNRECOGNIZED_NAME;
-
-#ifndef OPENSSL_NO_EC
- /* If we are client and using an elliptic curve cryptography cipher
- * suite, then if server returns an EC point formats lists extension
- * it must contain uncompressed.
- */
- unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
- if ((s->tlsext_ecpointformatlist != NULL) && (s->tlsext_ecpointformatlist_length > 0) &&
- (s->session->tlsext_ecpointformatlist != NULL) && (s->session->tlsext_ecpointformatlist_length > 0) &&
- ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA)))
- {
- /* we are using an ECC cipher */
- size_t i;
- unsigned char *list;
- int found_uncompressed = 0;
- list = s->session->tlsext_ecpointformatlist;
- for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
- {
- if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed)
- {
- found_uncompressed = 1;
- break;
- }
- }
- if (!found_uncompressed)
- {
- SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
- return -1;
- }
- }
- ret = SSL_TLSEXT_ERR_OK;
-#endif /* OPENSSL_NO_EC */
-
- if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
- ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
- else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0)
- ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
-
-#ifdef TLSEXT_TYPE_opaque_prf_input
- if (s->s3->server_opaque_prf_input_len > 0)
- {
- /* This case may indicate that we, as a client, want to insist on using opaque PRF inputs.
- * So first verify that we really have a value from the server too. */
-
- if (s->s3->server_opaque_prf_input == NULL)
- {
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_HANDSHAKE_FAILURE;
- }
-
- /* Anytime the server *has* sent an opaque PRF input, we need to check
- * that we have a client opaque PRF input of the same size. */
- if (s->s3->client_opaque_prf_input == NULL ||
- s->s3->client_opaque_prf_input_len != s->s3->server_opaque_prf_input_len)
- {
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_ILLEGAL_PARAMETER;
- }
- }
-#endif
-
- /* If we've requested certificate status and we wont get one
- * tell the callback
- */
- if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
- && s->ctx && s->ctx->tlsext_status_cb)
- {
- int r;
- /* Set resp to NULL, resplen to -1 so callback knows
- * there is no response.
- */
- if (s->tlsext_ocsp_resp)
- {
- OPENSSL_free(s->tlsext_ocsp_resp);
- s->tlsext_ocsp_resp = NULL;
- }
- s->tlsext_ocsp_resplen = -1;
- r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
- if (r == 0)
- {
- al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- }
- if (r < 0)
- {
- al = SSL_AD_INTERNAL_ERROR;
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- }
- }
-
- switch (ret)
- {
- case SSL_TLSEXT_ERR_ALERT_FATAL:
- ssl3_send_alert(s,SSL3_AL_FATAL,al);
- return -1;
-
- case SSL_TLSEXT_ERR_ALERT_WARNING:
- ssl3_send_alert(s,SSL3_AL_WARNING,al);
- return 1;
-
- case SSL_TLSEXT_ERR_NOACK:
- s->servername_done=0;
- default:
- return 1;
- }
- }
-
-/* Since the server cache lookup is done early on in the processing of client
- * hello and other operations depend on the result we need to handle any TLS
- * session ticket extension at the same time.
- */
-
-int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
- const unsigned char *limit, SSL_SESSION **ret)
- {
- /* Point after session ID in client hello */
- const unsigned char *p = session_id + len;
- unsigned short i;
-
- /* If tickets disabled behave as if no ticket present
- * to permit stateful resumption.
- */
- if (SSL_get_options(s) & SSL_OP_NO_TICKET)
- return 1;
-
- if ((s->version <= SSL3_VERSION) || !limit)
- return 1;
- if (p >= limit)
- return -1;
- /* Skip past DTLS cookie */
- if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
- {
- i = *(p++);
- p+= i;
- if (p >= limit)
- return -1;
- }
- /* Skip past cipher list */
- n2s(p, i);
- p+= i;
- if (p >= limit)
- return -1;
- /* Skip past compression algorithm list */
- i = *(p++);
- p += i;
- if (p > limit)
- return -1;
- /* Now at start of extensions */
- if ((p + 2) >= limit)
- return 1;
- n2s(p, i);
- while ((p + 4) <= limit)
- {
- unsigned short type, size;
- n2s(p, type);
- n2s(p, size);
- if (p + size > limit)
- return 1;
- if (type == TLSEXT_TYPE_session_ticket)
- {
- /* If tickets disabled indicate cache miss which will
- * trigger a full handshake
- */
- if (SSL_get_options(s) & SSL_OP_NO_TICKET)
- return 1;
- /* If zero length note client will accept a ticket
- * and indicate cache miss to trigger full handshake
- */
- if (size == 0)
- {
- s->tlsext_ticket_expected = 1;
- return 0; /* Cache miss */
- }
- if (s->tls_session_secret_cb)
- {
- /* Indicate cache miss here and instead of
- * generating the session from ticket now,
- * trigger abbreviated handshake based on
- * external mechanism to calculate the master
- * secret later. */
- return 0;
- }
- return tls_decrypt_ticket(s, p, size, session_id, len,
- ret);
- }
- p += size;
- }
- return 1;
- }
-
-static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
- const unsigned char *sess_id, int sesslen,
- SSL_SESSION **psess)
- {
- SSL_SESSION *sess;
- unsigned char *sdec;
- const unsigned char *p;
- int slen, mlen, renew_ticket = 0;
- unsigned char tick_hmac[EVP_MAX_MD_SIZE];
- HMAC_CTX hctx;
- EVP_CIPHER_CTX ctx;
- SSL_CTX *tctx = s->initial_ctx;
- /* Need at least keyname + iv + some encrypted data */
- if (eticklen < 48)
- goto tickerr;
- /* Initialize session ticket encryption and HMAC contexts */
- HMAC_CTX_init(&hctx);
- EVP_CIPHER_CTX_init(&ctx);
- if (tctx->tlsext_ticket_key_cb)
- {
- unsigned char *nctick = (unsigned char *)etick;
- int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
- &ctx, &hctx, 0);
- if (rv < 0)
- return -1;
- if (rv == 0)
- goto tickerr;
- if (rv == 2)
- renew_ticket = 1;
- }
- else
- {
- /* Check key name matches */
- if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
- goto tickerr;
- HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
- tlsext_tick_md(), NULL);
- EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
- tctx->tlsext_tick_aes_key, etick + 16);
- }
- /* Attempt to process session ticket, first conduct sanity and
- * integrity checks on ticket.
- */
- mlen = HMAC_size(&hctx);
- if (mlen < 0)
- {
- EVP_CIPHER_CTX_cleanup(&ctx);
- return -1;
- }
- eticklen -= mlen;
- /* Check HMAC of encrypted ticket */
- HMAC_Update(&hctx, etick, eticklen);
- HMAC_Final(&hctx, tick_hmac, NULL);
- HMAC_CTX_cleanup(&hctx);
- if (memcmp(tick_hmac, etick + eticklen, mlen))
- goto tickerr;
- /* Attempt to decrypt session data */
- /* Move p after IV to start of encrypted ticket, update length */
- p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
- eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
- sdec = OPENSSL_malloc(eticklen);
- if (!sdec)
- {
- EVP_CIPHER_CTX_cleanup(&ctx);
- return -1;
- }
- EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
- if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0)
- goto tickerr;
- slen += mlen;
- EVP_CIPHER_CTX_cleanup(&ctx);
- p = sdec;
-
- sess = d2i_SSL_SESSION(NULL, &p, slen);
- OPENSSL_free(sdec);
- if (sess)
- {
- /* The session ID if non-empty is used by some clients to
- * detect that the ticket has been accepted. So we copy it to
- * the session structure. If it is empty set length to zero
- * as required by standard.
- */
- if (sesslen)
- memcpy(sess->session_id, sess_id, sesslen);
- sess->session_id_length = sesslen;
- *psess = sess;
- s->tlsext_ticket_expected = renew_ticket;
- return 1;
- }
- /* If session decrypt failure indicate a cache miss and set state to
- * send a new ticket
- */
- tickerr:
- s->tlsext_ticket_expected = 1;
- return 0;
- }
-
-#endif
+/* ssl/t1_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/ocsp.h>
+#include "ssl_locl.h"
+
+const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
+
+#ifndef OPENSSL_NO_TLSEXT
+static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
+ const unsigned char *sess_id, int sesslen,
+ SSL_SESSION **psess);
+#endif
+
+SSL3_ENC_METHOD TLSv1_enc_data={
+ tls1_enc,
+ tls1_mac,
+ tls1_setup_key_block,
+ tls1_generate_master_secret,
+ tls1_change_cipher_state,
+ tls1_final_finish_mac,
+ TLS1_FINISH_MAC_LENGTH,
+ tls1_cert_verify_mac,
+ TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
+ TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
+ tls1_alert_code,
+ };
+
+long tls1_default_timeout(void)
+ {
+ /* 2 hours, the 24 hours mentioned in the TLSv1 spec
+ * is way too long for http, the cache would over fill */
+ return(60*60*2);
+ }
+
+int tls1_new(SSL *s)
+ {
+ if (!ssl3_new(s)) return(0);
+ s->method->ssl_clear(s);
+ return(1);
+ }
+
+void tls1_free(SSL *s)
+ {
+#ifndef OPENSSL_NO_TLSEXT
+ if (s->tlsext_session_ticket)
+ {
+ OPENSSL_free(s->tlsext_session_ticket);
+ }
+#endif /* OPENSSL_NO_TLSEXT */
+ ssl3_free(s);
+ }
+
+void tls1_clear(SSL *s)
+ {
+ ssl3_clear(s);
+ s->version=TLS1_VERSION;
+ }
+
+#ifndef OPENSSL_NO_EC
+static int nid_list[] =
+ {
+ NID_sect163k1, /* sect163k1 (1) */
+ NID_sect163r1, /* sect163r1 (2) */
+ NID_sect163r2, /* sect163r2 (3) */
+ NID_sect193r1, /* sect193r1 (4) */
+ NID_sect193r2, /* sect193r2 (5) */
+ NID_sect233k1, /* sect233k1 (6) */
+ NID_sect233r1, /* sect233r1 (7) */
+ NID_sect239k1, /* sect239k1 (8) */
+ NID_sect283k1, /* sect283k1 (9) */
+ NID_sect283r1, /* sect283r1 (10) */
+ NID_sect409k1, /* sect409k1 (11) */
+ NID_sect409r1, /* sect409r1 (12) */
+ NID_sect571k1, /* sect571k1 (13) */
+ NID_sect571r1, /* sect571r1 (14) */
+ NID_secp160k1, /* secp160k1 (15) */
+ NID_secp160r1, /* secp160r1 (16) */
+ NID_secp160r2, /* secp160r2 (17) */
+ NID_secp192k1, /* secp192k1 (18) */
+ NID_X9_62_prime192v1, /* secp192r1 (19) */
+ NID_secp224k1, /* secp224k1 (20) */
+ NID_secp224r1, /* secp224r1 (21) */
+ NID_secp256k1, /* secp256k1 (22) */
+ NID_X9_62_prime256v1, /* secp256r1 (23) */
+ NID_secp384r1, /* secp384r1 (24) */
+ NID_secp521r1 /* secp521r1 (25) */
+ };
+
+int tls1_ec_curve_id2nid(int curve_id)
+ {
+ /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+ if ((curve_id < 1) || ((unsigned int)curve_id >
+ sizeof(nid_list)/sizeof(nid_list[0])))
+ return 0;
+ return nid_list[curve_id-1];
+ }
+
+int tls1_ec_nid2curve_id(int nid)
+ {
+ /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+ switch (nid)
+ {
+ case NID_sect163k1: /* sect163k1 (1) */
+ return 1;
+ case NID_sect163r1: /* sect163r1 (2) */
+ return 2;
+ case NID_sect163r2: /* sect163r2 (3) */
+ return 3;
+ case NID_sect193r1: /* sect193r1 (4) */
+ return 4;
+ case NID_sect193r2: /* sect193r2 (5) */
+ return 5;
+ case NID_sect233k1: /* sect233k1 (6) */
+ return 6;
+ case NID_sect233r1: /* sect233r1 (7) */
+ return 7;
+ case NID_sect239k1: /* sect239k1 (8) */
+ return 8;
+ case NID_sect283k1: /* sect283k1 (9) */
+ return 9;
+ case NID_sect283r1: /* sect283r1 (10) */
+ return 10;
+ case NID_sect409k1: /* sect409k1 (11) */
+ return 11;
+ case NID_sect409r1: /* sect409r1 (12) */
+ return 12;
+ case NID_sect571k1: /* sect571k1 (13) */
+ return 13;
+ case NID_sect571r1: /* sect571r1 (14) */
+ return 14;
+ case NID_secp160k1: /* secp160k1 (15) */
+ return 15;
+ case NID_secp160r1: /* secp160r1 (16) */
+ return 16;
+ case NID_secp160r2: /* secp160r2 (17) */
+ return 17;
+ case NID_secp192k1: /* secp192k1 (18) */
+ return 18;
+ case NID_X9_62_prime192v1: /* secp192r1 (19) */
+ return 19;
+ case NID_secp224k1: /* secp224k1 (20) */
+ return 20;
+ case NID_secp224r1: /* secp224r1 (21) */
+ return 21;
+ case NID_secp256k1: /* secp256k1 (22) */
+ return 22;
+ case NID_X9_62_prime256v1: /* secp256r1 (23) */
+ return 23;
+ case NID_secp384r1: /* secp384r1 (24) */
+ return 24;
+ case NID_secp521r1: /* secp521r1 (25) */
+ return 25;
+ default:
+ return 0;
+ }
+ }
+#endif /* OPENSSL_NO_EC */
+
+#ifndef OPENSSL_NO_TLSEXT
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
+ {
+ int extdatalen=0;
+ unsigned char *ret = p;
+
+ /* don't add extensions for SSLv3 unless doing secure renegotiation */
+ if (s->client_version == SSL3_VERSION
+ && !s->s3->send_connection_binding)
+ return p;
+
+ ret+=2;
+
+ if (ret>=limit) return NULL; /* this really never occurs, but ... */
+
+ if (s->tlsext_hostname != NULL)
+ {
+ /* Add TLS extension servername to the Client Hello message */
+ unsigned long size_str;
+ long lenmax;
+
+ /* check for enough space.
+ 4 for the servername type and entension length
+ 2 for servernamelist length
+ 1 for the hostname type
+ 2 for hostname length
+ + hostname length
+ */
+
+ if ((lenmax = limit - ret - 9) < 0
+ || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax)
+ return NULL;
+
+ /* extension type and length */
+ s2n(TLSEXT_TYPE_server_name,ret);
+ s2n(size_str+5,ret);
+
+ /* length of servername list */
+ s2n(size_str+3,ret);
+
+ /* hostname type, length and hostname */
+ *(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name;
+ s2n(size_str,ret);
+ memcpy(ret, s->tlsext_hostname, size_str);
+ ret+=size_str;
+ }
+
+ /* Add RI if renegotiating */
+ if (s->new_session)
+ {
+ int el;
+
+ if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ if((limit - p - 4 - el) < 0) return NULL;
+
+ s2n(TLSEXT_TYPE_renegotiate,ret);
+ s2n(el,ret);
+
+ if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ ret += el;
+ }
+
+#ifndef OPENSSL_NO_EC
+ if (s->tlsext_ecpointformatlist != NULL &&
+ s->version != DTLS1_VERSION)
+ {
+ /* Add TLS extension ECPointFormats to the ClientHello message */
+ long lenmax;
+
+ if ((lenmax = limit - ret - 5) < 0) return NULL;
+ if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
+ if (s->tlsext_ecpointformatlist_length > 255)
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ s2n(TLSEXT_TYPE_ec_point_formats,ret);
+ s2n(s->tlsext_ecpointformatlist_length + 1,ret);
+ *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
+ memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
+ ret+=s->tlsext_ecpointformatlist_length;
+ }
+ if (s->tlsext_ellipticcurvelist != NULL &&
+ s->version != DTLS1_VERSION)
+ {
+ /* Add TLS extension EllipticCurves to the ClientHello message */
+ long lenmax;
+
+ if ((lenmax = limit - ret - 6) < 0) return NULL;
+ if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) return NULL;
+ if (s->tlsext_ellipticcurvelist_length > 65532)
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ s2n(TLSEXT_TYPE_elliptic_curves,ret);
+ s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
+
+ /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
+ * elliptic_curve_list, but the examples use two bytes.
+ * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
+ * resolves this to two bytes.
+ */
+ s2n(s->tlsext_ellipticcurvelist_length, ret);
+ memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
+ ret+=s->tlsext_ellipticcurvelist_length;
+ }
+#endif /* OPENSSL_NO_EC */
+
+ if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
+ {
+ int ticklen;
+ if (!s->new_session && s->session && s->session->tlsext_tick)
+ ticklen = s->session->tlsext_ticklen;
+ else if (s->session && s->tlsext_session_ticket &&
+ s->tlsext_session_ticket->data)
+ {
+ ticklen = s->tlsext_session_ticket->length;
+ s->session->tlsext_tick = OPENSSL_malloc(ticklen);
+ if (!s->session->tlsext_tick)
+ return NULL;
+ memcpy(s->session->tlsext_tick,
+ s->tlsext_session_ticket->data,
+ ticklen);
+ s->session->tlsext_ticklen = ticklen;
+ }
+ else
+ ticklen = 0;
+ if (ticklen == 0 && s->tlsext_session_ticket &&
+ s->tlsext_session_ticket->data == NULL)
+ goto skip_ext;
+ /* Check for enough room 2 for extension type, 2 for len
+ * rest for ticket
+ */
+ if ((long)(limit - ret - 4 - ticklen) < 0) return NULL;
+ s2n(TLSEXT_TYPE_session_ticket,ret);
+ s2n(ticklen,ret);
+ if (ticklen)
+ {
+ memcpy(ret, s->session->tlsext_tick, ticklen);
+ ret += ticklen;
+ }
+ }
+ skip_ext:
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ if (s->s3->client_opaque_prf_input != NULL &&
+ s->version != DTLS1_VERSION)
+ {
+ size_t col = s->s3->client_opaque_prf_input_len;
+
+ if ((long)(limit - ret - 6 - col < 0))
+ return NULL;
+ if (col > 0xFFFD) /* can't happen */
+ return NULL;
+
+ s2n(TLSEXT_TYPE_opaque_prf_input, ret);
+ s2n(col + 2, ret);
+ s2n(col, ret);
+ memcpy(ret, s->s3->client_opaque_prf_input, col);
+ ret += col;
+ }
+#endif
+
+ if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp &&
+ s->version != DTLS1_VERSION)
+ {
+ int i;
+ long extlen, idlen, itmp;
+ OCSP_RESPID *id;
+
+ idlen = 0;
+ for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
+ {
+ id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
+ itmp = i2d_OCSP_RESPID(id, NULL);
+ if (itmp <= 0)
+ return NULL;
+ idlen += itmp + 2;
+ }
+
+ if (s->tlsext_ocsp_exts)
+ {
+ extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
+ if (extlen < 0)
+ return NULL;
+ }
+ else
+ extlen = 0;
+
+ if ((long)(limit - ret - 7 - extlen - idlen) < 0) return NULL;
+ s2n(TLSEXT_TYPE_status_request, ret);
+ if (extlen + idlen > 0xFFF0)
+ return NULL;
+ s2n(extlen + idlen + 5, ret);
+ *(ret++) = TLSEXT_STATUSTYPE_ocsp;
+ s2n(idlen, ret);
+ for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++)
+ {
+ /* save position of id len */
+ unsigned char *q = ret;
+ id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
+ /* skip over id len */
+ ret += 2;
+ itmp = i2d_OCSP_RESPID(id, &ret);
+ /* write id len */
+ s2n(itmp, q);
+ }
+ s2n(extlen, ret);
+ if (extlen > 0)
+ i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
+ }
+
+ if ((extdatalen = ret-p-2)== 0)
+ return p;
+
+ s2n(extdatalen,p);
+ return ret;
+ }
+
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
+ {
+ int extdatalen=0;
+ unsigned char *ret = p;
+
+ /* don't add extensions for SSLv3, unless doing secure renegotiation */
+ if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
+ return p;
+
+ ret+=2;
+ if (ret>=limit) return NULL; /* this really never occurs, but ... */
+
+ if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
+ {
+ if ((long)(limit - ret - 4) < 0) return NULL;
+
+ s2n(TLSEXT_TYPE_server_name,ret);
+ s2n(0,ret);
+ }
+
+ if(s->s3->send_connection_binding)
+ {
+ int el;
+
+ if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0))
+ {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ if((limit - p - 4 - el) < 0) return NULL;
+
+ s2n(TLSEXT_TYPE_renegotiate,ret);
+ s2n(el,ret);
+
+ if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el))
+ {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ ret += el;
+ }
+
+#ifndef OPENSSL_NO_EC
+ if (s->tlsext_ecpointformatlist != NULL &&
+ s->version != DTLS1_VERSION)
+ {
+ /* Add TLS extension ECPointFormats to the ServerHello message */
+ long lenmax;
+
+ if ((lenmax = limit - ret - 5) < 0) return NULL;
+ if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
+ if (s->tlsext_ecpointformatlist_length > 255)
+ {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ s2n(TLSEXT_TYPE_ec_point_formats,ret);
+ s2n(s->tlsext_ecpointformatlist_length + 1,ret);
+ *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
+ memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
+ ret+=s->tlsext_ecpointformatlist_length;
+
+ }
+ /* Currently the server should not respond with a SupportedCurves extension */
+#endif /* OPENSSL_NO_EC */
+
+ if (s->tlsext_ticket_expected
+ && !(SSL_get_options(s) & SSL_OP_NO_TICKET))
+ {
+ if ((long)(limit - ret - 4) < 0) return NULL;
+ s2n(TLSEXT_TYPE_session_ticket,ret);
+ s2n(0,ret);
+ }
+
+ if (s->tlsext_status_expected)
+ {
+ if ((long)(limit - ret - 4) < 0) return NULL;
+ s2n(TLSEXT_TYPE_status_request,ret);
+ s2n(0,ret);
+ }
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ if (s->s3->server_opaque_prf_input != NULL &&
+ s->version != DTLS1_VERSION)
+ {
+ size_t sol = s->s3->server_opaque_prf_input_len;
+
+ if ((long)(limit - ret - 6 - sol) < 0)
+ return NULL;
+ if (sol > 0xFFFD) /* can't happen */
+ return NULL;
+
+ s2n(TLSEXT_TYPE_opaque_prf_input, ret);
+ s2n(sol + 2, ret);
+ s2n(sol, ret);
+ memcpy(ret, s->s3->server_opaque_prf_input, sol);
+ ret += sol;
+ }
+#endif
+ if (((s->s3->tmp.new_cipher->id & 0xFFFF)==0x80 || (s->s3->tmp.new_cipher->id & 0xFFFF)==0x81)
+ && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG))
+ { const unsigned char cryptopro_ext[36] = {
+ 0xfd, 0xe8, /*65000*/
+ 0x00, 0x20, /*32 bytes length*/
+ 0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85,
+ 0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06,
+ 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
+ 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17};
+ if (limit-ret<36) return NULL;
+ memcpy(ret,cryptopro_ext,36);
+ ret+=36;
+
+ }
+
+ if ((extdatalen = ret-p-2)== 0)
+ return p;
+
+ s2n(extdatalen,p);
+ return ret;
+ }
+
+int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
+ {
+ unsigned short type;
+ unsigned short size;
+ unsigned short len;
+ unsigned char *data = *p;
+ int renegotiate_seen = 0;
+
+ s->servername_done = 0;
+ s->tlsext_status_type = -1;
+
+ if (data >= (d+n-2))
+ goto ri_check;
+ n2s(data,len);
+
+ if (data > (d+n-len))
+ goto ri_check;
+
+ while (data <= (d+n-4))
+ {
+ n2s(data,type);
+ n2s(data,size);
+
+ if (data+size > (d+n))
+ goto ri_check;
+#if 0
+ fprintf(stderr,"Received extension type %d size %d\n",type,size);
+#endif
+ if (s->tlsext_debug_cb)
+ s->tlsext_debug_cb(s, 0, type, data, size,
+ s->tlsext_debug_arg);
+/* The servername extension is treated as follows:
+
+ - Only the hostname type is supported with a maximum length of 255.
+ - The servername is rejected if too long or if it contains zeros,
+ in which case an fatal alert is generated.
+ - The servername field is maintained together with the session cache.
+ - When a session is resumed, the servername call back invoked in order
+ to allow the application to position itself to the right context.
+ - The servername is acknowledged if it is new for a session or when
+ it is identical to a previously used for the same session.
+ Applications can control the behaviour. They can at any time
+ set a 'desirable' servername for a new SSL object. This can be the
+ case for example with HTTPS when a Host: header field is received and
+ a renegotiation is requested. In this case, a possible servername
+ presented in the new client hello is only acknowledged if it matches
+ the value of the Host: field.
+ - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
+ if they provide for changing an explicit servername context for the session,
+ i.e. when the session has been established with a servername extension.
+ - On session reconnect, the servername extension may be absent.
+
+*/
+
+ if (type == TLSEXT_TYPE_server_name)
+ {
+ unsigned char *sdata;
+ int servname_type;
+ int dsize;
+
+ if (size < 2)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ n2s(data,dsize);
+ size -= 2;
+ if (dsize > size )
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ sdata = data;
+ while (dsize > 3)
+ {
+ servname_type = *(sdata++);
+ n2s(sdata,len);
+ dsize -= 3;
+
+ if (len > dsize)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ if (s->servername_done == 0)
+ switch (servname_type)
+ {
+ case TLSEXT_NAMETYPE_host_name:
+ if (!s->hit)
+ {
+ if(s->session->tlsext_hostname)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ if (len > TLSEXT_MAXLEN_host_name)
+ {
+ *al = TLS1_AD_UNRECOGNIZED_NAME;
+ return 0;
+ }
+ if ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL)
+ {
+ *al = TLS1_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ memcpy(s->session->tlsext_hostname, sdata, len);
+ s->session->tlsext_hostname[len]='\0';
+ if (strlen(s->session->tlsext_hostname) != len) {
+ OPENSSL_free(s->session->tlsext_hostname);
+ s->session->tlsext_hostname = NULL;
+ *al = TLS1_AD_UNRECOGNIZED_NAME;
+ return 0;
+ }
+ s->servername_done = 1;
+
+ }
+ else
+ s->servername_done = s->session->tlsext_hostname
+ && strlen(s->session->tlsext_hostname) == len
+ && strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0;
+
+ break;
+
+ default:
+ break;
+ }
+
+ dsize -= len;
+ }
+ if (dsize != 0)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ }
+
+#ifndef OPENSSL_NO_EC
+ else if (type == TLSEXT_TYPE_ec_point_formats &&
+ s->version != DTLS1_VERSION)
+ {
+ unsigned char *sdata = data;
+ int ecpointformatlist_length = *(sdata++);
+
+ if (ecpointformatlist_length != size - 1)
+ {
+ *al = TLS1_AD_DECODE_ERROR;
+ return 0;
+ }
+ if (!s->hit)
+ {
+ if(s->session->tlsext_ecpointformatlist)
+ {
+ OPENSSL_free(s->session->tlsext_ecpointformatlist);
+ s->session->tlsext_ecpointformatlist = NULL;
+ }
+ s->session->tlsext_ecpointformatlist_length = 0;
+ if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+ {
+ *al = TLS1_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
+ memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
+ }
+#if 0
+ fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", s->session->tlsext_ecpointformatlist_length);
+ sdata = s->session->tlsext_ecpointformatlist;
+ for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
+ fprintf(stderr,"%i ",*(sdata++));
+ fprintf(stderr,"\n");
+#endif
+ }
+ else if (type == TLSEXT_TYPE_elliptic_curves &&
+ s->version != DTLS1_VERSION)
+ {
+ unsigned char *sdata = data;
+ int ellipticcurvelist_length = (*(sdata++) << 8);
+ ellipticcurvelist_length += (*(sdata++));
+
+ if (ellipticcurvelist_length != size - 2)
+ {
+ *al = TLS1_AD_DECODE_ERROR;
+ return 0;
+ }
+ if (!s->hit)
+ {
+ if(s->session->tlsext_ellipticcurvelist)
+ {
+ *al = TLS1_AD_DECODE_ERROR;
+ return 0;
+ }
+ s->session->tlsext_ellipticcurvelist_length = 0;
+ if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL)
+ {
+ *al = TLS1_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length;
+ memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length);
+ }
+#if 0
+ fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", s->session->tlsext_ellipticcurvelist_length);
+ sdata = s->session->tlsext_ellipticcurvelist;
+ for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++)
+ fprintf(stderr,"%i ",*(sdata++));
+ fprintf(stderr,"\n");
+#endif
+ }
+#endif /* OPENSSL_NO_EC */
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ else if (type == TLSEXT_TYPE_opaque_prf_input &&
+ s->version != DTLS1_VERSION)
+ {
+ unsigned char *sdata = data;
+
+ if (size < 2)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ n2s(sdata, s->s3->client_opaque_prf_input_len);
+ if (s->s3->client_opaque_prf_input_len != size - 2)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */
+ OPENSSL_free(s->s3->client_opaque_prf_input);
+ if (s->s3->client_opaque_prf_input_len == 0)
+ s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+ else
+ s->s3->client_opaque_prf_input = BUF_memdup(sdata, s->s3->client_opaque_prf_input_len);
+ if (s->s3->client_opaque_prf_input == NULL)
+ {
+ *al = TLS1_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ }
+#endif
+ else if (type == TLSEXT_TYPE_session_ticket)
+ {
+ if (s->tls_session_ticket_ext_cb &&
+ !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
+ {
+ *al = TLS1_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ }
+ else if (type == TLSEXT_TYPE_renegotiate)
+ {
+ if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
+ return 0;
+ renegotiate_seen = 1;
+ }
+ else if (type == TLSEXT_TYPE_status_request &&
+ s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb)
+ {
+
+ if (size < 5)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ s->tlsext_status_type = *data++;
+ size--;
+ if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
+ {
+ const unsigned char *sdata;
+ int dsize;
+ /* Read in responder_id_list */
+ n2s(data,dsize);
+ size -= 2;
+ if (dsize > size )
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ while (dsize > 0)
+ {
+ OCSP_RESPID *id;
+ int idsize;
+ if (dsize < 4)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ n2s(data, idsize);
+ dsize -= 2 + idsize;
+ size -= 2 + idsize;
+ if (dsize < 0)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ sdata = data;
+ data += idsize;
+ id = d2i_OCSP_RESPID(NULL,
+ &sdata, idsize);
+ if (!id)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ if (data != sdata)
+ {
+ OCSP_RESPID_free(id);
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ if (!s->tlsext_ocsp_ids
+ && !(s->tlsext_ocsp_ids =
+ sk_OCSP_RESPID_new_null()))
+ {
+ OCSP_RESPID_free(id);
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ if (!sk_OCSP_RESPID_push(
+ s->tlsext_ocsp_ids, id))
+ {
+ OCSP_RESPID_free(id);
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ }
+
+ /* Read in request_extensions */
+ if (size < 2)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ n2s(data,dsize);
+ size -= 2;
+ if (dsize != size)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ sdata = data;
+ if (dsize > 0)
+ {
+ s->tlsext_ocsp_exts =
+ d2i_X509_EXTENSIONS(NULL,
+ &sdata, dsize);
+ if (!s->tlsext_ocsp_exts
+ || (data + dsize != sdata))
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ }
+ }
+ /* We don't know what to do with any other type
+ * so ignore it.
+ */
+ else
+ s->tlsext_status_type = -1;
+ }
+
+ /* session ticket processed earlier */
+ data+=size;
+ }
+
+ *p = data;
+
+ ri_check:
+
+ /* Need RI if renegotiating */
+
+ if (!renegotiate_seen && s->new_session &&
+ !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+ {
+ *al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT,
+ SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+ return 0;
+ }
+
+ return 1;
+ }
+
+int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
+ {
+ unsigned short length;
+ unsigned short type;
+ unsigned short size;
+ unsigned char *data = *p;
+ int tlsext_servername = 0;
+ int renegotiate_seen = 0;
+
+ if (data >= (d+n-2))
+ goto ri_check;
+
+ n2s(data,length);
+ if (data+length != d+n)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ while(data <= (d+n-4))
+ {
+ n2s(data,type);
+ n2s(data,size);
+
+ if (data+size > (d+n))
+ goto ri_check;
+
+ if (s->tlsext_debug_cb)
+ s->tlsext_debug_cb(s, 1, type, data, size,
+ s->tlsext_debug_arg);
+
+ if (type == TLSEXT_TYPE_server_name)
+ {
+ if (s->tlsext_hostname == NULL || size > 0)
+ {
+ *al = TLS1_AD_UNRECOGNIZED_NAME;
+ return 0;
+ }
+ tlsext_servername = 1;
+ }
+
+#ifndef OPENSSL_NO_EC
+ else if (type == TLSEXT_TYPE_ec_point_formats &&
+ s->version != DTLS1_VERSION)
+ {
+ unsigned char *sdata = data;
+ int ecpointformatlist_length = *(sdata++);
+
+ if (ecpointformatlist_length != size - 1)
+ {
+ *al = TLS1_AD_DECODE_ERROR;
+ return 0;
+ }
+ s->session->tlsext_ecpointformatlist_length = 0;
+ if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
+ if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+ {
+ *al = TLS1_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
+ memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
+#if 0
+ fprintf(stderr,"ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
+ sdata = s->session->tlsext_ecpointformatlist;
+ for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
+ fprintf(stderr,"%i ",*(sdata++));
+ fprintf(stderr,"\n");
+#endif
+ }
+#endif /* OPENSSL_NO_EC */
+
+ else if (type == TLSEXT_TYPE_session_ticket)
+ {
+ if (s->tls_session_ticket_ext_cb &&
+ !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
+ {
+ *al = TLS1_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
+ || (size > 0))
+ {
+ *al = TLS1_AD_UNSUPPORTED_EXTENSION;
+ return 0;
+ }
+ s->tlsext_ticket_expected = 1;
+ }
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ else if (type == TLSEXT_TYPE_opaque_prf_input &&
+ s->version != DTLS1_VERSION)
+ {
+ unsigned char *sdata = data;
+
+ if (size < 2)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ n2s(sdata, s->s3->server_opaque_prf_input_len);
+ if (s->s3->server_opaque_prf_input_len != size - 2)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ if (s->s3->server_opaque_prf_input != NULL) /* shouldn't really happen */
+ OPENSSL_free(s->s3->server_opaque_prf_input);
+ if (s->s3->server_opaque_prf_input_len == 0)
+ s->s3->server_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+ else
+ s->s3->server_opaque_prf_input = BUF_memdup(sdata, s->s3->server_opaque_prf_input_len);
+
+ if (s->s3->server_opaque_prf_input == NULL)
+ {
+ *al = TLS1_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ }
+#endif
+ else if (type == TLSEXT_TYPE_status_request &&
+ s->version != DTLS1_VERSION)
+ {
+ /* MUST be empty and only sent if we've requested
+ * a status request message.
+ */
+ if ((s->tlsext_status_type == -1) || (size > 0))
+ {
+ *al = TLS1_AD_UNSUPPORTED_EXTENSION;
+ return 0;
+ }
+ /* Set flag to expect CertificateStatus message */
+ s->tlsext_status_expected = 1;
+ }
+ else if (type == TLSEXT_TYPE_renegotiate)
+ {
+ if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
+ return 0;
+ renegotiate_seen = 1;
+ }
+ data+=size;
+ }
+
+ if (data != d+n)
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ if (!s->hit && tlsext_servername == 1)
+ {
+ if (s->tlsext_hostname)
+ {
+ if (s->session->tlsext_hostname == NULL)
+ {
+ s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
+ if (!s->session->tlsext_hostname)
+ {
+ *al = SSL_AD_UNRECOGNIZED_NAME;
+ return 0;
+ }
+ }
+ else
+ {
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+ }
+ }
+
+ *p = data;
+
+ ri_check:
+
+ /* Determine if we need to see RI. Strictly speaking if we want to
+ * avoid an attack we should *always* see RI even on initial server
+ * hello because the client doesn't see any renegotiation during an
+ * attack. However this would mean we could not connect to any server
+ * which doesn't support RI so for the immediate future tolerate RI
+ * absence on initial connect only.
+ */
+ if (!renegotiate_seen
+ && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
+ && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+ {
+ *al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT,
+ SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+ return 0;
+ }
+
+ return 1;
+ }
+
+
+int ssl_prepare_clienthello_tlsext(SSL *s)
+ {
+#ifndef OPENSSL_NO_EC
+ /* If we are client and using an elliptic curve cryptography cipher suite, send the point formats
+ * and elliptic curves we support.
+ */
+ int using_ecc = 0;
+ int i;
+ unsigned char *j;
+ unsigned long alg_k, alg_a;
+ STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
+
+ for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++)
+ {
+ SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
+
+ alg_k = c->algorithm_mkey;
+ alg_a = c->algorithm_auth;
+ if ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe) || (alg_a & SSL_aECDSA)))
+ {
+ using_ecc = 1;
+ break;
+ }
+ }
+ using_ecc = using_ecc && (s->version == TLS1_VERSION);
+ if (using_ecc)
+ {
+ if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
+ if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL)
+ {
+ SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ s->tlsext_ecpointformatlist_length = 3;
+ s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
+ s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
+ s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
+
+ /* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
+ if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist);
+ s->tlsext_ellipticcurvelist_length = sizeof(nid_list)/sizeof(nid_list[0]) * 2;
+ if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
+ {
+ s->tlsext_ellipticcurvelist_length = 0;
+ SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ for (i = 1, j = s->tlsext_ellipticcurvelist; (unsigned int)i <=
+ sizeof(nid_list)/sizeof(nid_list[0]); i++)
+ s2n(i,j);
+ }
+#endif /* OPENSSL_NO_EC */
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ {
+ int r = 1;
+
+ if (s->ctx->tlsext_opaque_prf_input_callback != 0)
+ {
+ r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg);
+ if (!r)
+ return -1;
+ }
+
+ if (s->tlsext_opaque_prf_input != NULL)
+ {
+ if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */
+ OPENSSL_free(s->s3->client_opaque_prf_input);
+
+ if (s->tlsext_opaque_prf_input_len == 0)
+ s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+ else
+ s->s3->client_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len);
+ if (s->s3->client_opaque_prf_input == NULL)
+ {
+ SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ s->s3->client_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
+ }
+
+ if (r == 2)
+ /* at callback's request, insist on receiving an appropriate server opaque PRF input */
+ s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
+ }
+#endif
+
+ return 1;
+ }
+
+int ssl_prepare_serverhello_tlsext(SSL *s)
+ {
+#ifndef OPENSSL_NO_EC
+ /* If we are server and using an ECC cipher suite, send the point formats we support
+ * if the client sent us an ECPointsFormat extension. Note that the server is not
+ * supposed to send an EllipticCurves extension.
+ */
+
+ unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+ unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+ int using_ecc = (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA);
+ using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
+
+ if (using_ecc)
+ {
+ if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
+ if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL)
+ {
+ SSLerr(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ s->tlsext_ecpointformatlist_length = 3;
+ s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
+ s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
+ s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
+ }
+#endif /* OPENSSL_NO_EC */
+
+ return 1;
+ }
+
+int ssl_check_clienthello_tlsext(SSL *s)
+ {
+ int ret=SSL_TLSEXT_ERR_NOACK;
+ int al = SSL_AD_UNRECOGNIZED_NAME;
+
+#ifndef OPENSSL_NO_EC
+ /* The handling of the ECPointFormats extension is done elsewhere, namely in
+ * ssl3_choose_cipher in s3_lib.c.
+ */
+ /* The handling of the EllipticCurves extension is done elsewhere, namely in
+ * ssl3_choose_cipher in s3_lib.c.
+ */
+#endif
+
+ if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
+ ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
+ else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0)
+ ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
+
+ /* If status request then ask callback what to do.
+ * Note: this must be called after servername callbacks in case
+ * the certificate has changed.
+ */
+ if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb)
+ {
+ int r;
+ r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+ switch (r)
+ {
+ /* We don't want to send a status request response */
+ case SSL_TLSEXT_ERR_NOACK:
+ s->tlsext_status_expected = 0;
+ break;
+ /* status request response should be sent */
+ case SSL_TLSEXT_ERR_OK:
+ if (s->tlsext_ocsp_resp)
+ s->tlsext_status_expected = 1;
+ else
+ s->tlsext_status_expected = 0;
+ break;
+ /* something bad happened */
+ case SSL_TLSEXT_ERR_ALERT_FATAL:
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ al = SSL_AD_INTERNAL_ERROR;
+ goto err;
+ }
+ }
+ else
+ s->tlsext_status_expected = 0;
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ {
+ /* This sort of belongs into ssl_prepare_serverhello_tlsext(),
+ * but we might be sending an alert in response to the client hello,
+ * so this has to happen here in ssl_check_clienthello_tlsext(). */
+
+ int r = 1;
+
+ if (s->ctx->tlsext_opaque_prf_input_callback != 0)
+ {
+ r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg);
+ if (!r)
+ {
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ al = SSL_AD_INTERNAL_ERROR;
+ goto err;
+ }
+ }
+
+ if (s->s3->server_opaque_prf_input != NULL) /* shouldn't really happen */
+ OPENSSL_free(s->s3->server_opaque_prf_input);
+ s->s3->server_opaque_prf_input = NULL;
+
+ if (s->tlsext_opaque_prf_input != NULL)
+ {
+ if (s->s3->client_opaque_prf_input != NULL &&
+ s->s3->client_opaque_prf_input_len == s->tlsext_opaque_prf_input_len)
+ {
+ /* can only use this extension if we have a server opaque PRF input
+ * of the same length as the client opaque PRF input! */
+
+ if (s->tlsext_opaque_prf_input_len == 0)
+ s->s3->server_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+ else
+ s->s3->server_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len);
+ if (s->s3->server_opaque_prf_input == NULL)
+ {
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ al = SSL_AD_INTERNAL_ERROR;
+ goto err;
+ }
+ s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
+ }
+ }
+
+ if (r == 2 && s->s3->server_opaque_prf_input == NULL)
+ {
+ /* The callback wants to enforce use of the extension,
+ * but we can't do that with the client opaque PRF input;
+ * abort the handshake.
+ */
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ }
+ }
+
+#endif
+ err:
+ switch (ret)
+ {
+ case SSL_TLSEXT_ERR_ALERT_FATAL:
+ ssl3_send_alert(s,SSL3_AL_FATAL,al);
+ return -1;
+
+ case SSL_TLSEXT_ERR_ALERT_WARNING:
+ ssl3_send_alert(s,SSL3_AL_WARNING,al);
+ return 1;
+
+ case SSL_TLSEXT_ERR_NOACK:
+ s->servername_done=0;
+ default:
+ return 1;
+ }
+ }
+
+int ssl_check_serverhello_tlsext(SSL *s)
+ {
+ int ret=SSL_TLSEXT_ERR_NOACK;
+ int al = SSL_AD_UNRECOGNIZED_NAME;
+
+#ifndef OPENSSL_NO_EC
+ /* If we are client and using an elliptic curve cryptography cipher
+ * suite, then if server returns an EC point formats lists extension
+ * it must contain uncompressed.
+ */
+ unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+ unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+ if ((s->tlsext_ecpointformatlist != NULL) && (s->tlsext_ecpointformatlist_length > 0) &&
+ (s->session->tlsext_ecpointformatlist != NULL) && (s->session->tlsext_ecpointformatlist_length > 0) &&
+ ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA)))
+ {
+ /* we are using an ECC cipher */
+ size_t i;
+ unsigned char *list;
+ int found_uncompressed = 0;
+ list = s->session->tlsext_ecpointformatlist;
+ for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
+ {
+ if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed)
+ {
+ found_uncompressed = 1;
+ break;
+ }
+ }
+ if (!found_uncompressed)
+ {
+ SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
+ return -1;
+ }
+ }
+ ret = SSL_TLSEXT_ERR_OK;
+#endif /* OPENSSL_NO_EC */
+
+ if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
+ ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
+ else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0)
+ ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ if (s->s3->server_opaque_prf_input_len > 0)
+ {
+ /* This case may indicate that we, as a client, want to insist on using opaque PRF inputs.
+ * So first verify that we really have a value from the server too. */
+
+ if (s->s3->server_opaque_prf_input == NULL)
+ {
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ }
+
+ /* Anytime the server *has* sent an opaque PRF input, we need to check
+ * that we have a client opaque PRF input of the same size. */
+ if (s->s3->client_opaque_prf_input == NULL ||
+ s->s3->client_opaque_prf_input_len != s->s3->server_opaque_prf_input_len)
+ {
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ }
+ }
+#endif
+
+ /* If we've requested certificate status and we wont get one
+ * tell the callback
+ */
+ if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
+ && s->ctx && s->ctx->tlsext_status_cb)
+ {
+ int r;
+ /* Set resp to NULL, resplen to -1 so callback knows
+ * there is no response.
+ */
+ if (s->tlsext_ocsp_resp)
+ {
+ OPENSSL_free(s->tlsext_ocsp_resp);
+ s->tlsext_ocsp_resp = NULL;
+ }
+ s->tlsext_ocsp_resplen = -1;
+ r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+ if (r == 0)
+ {
+ al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ }
+ if (r < 0)
+ {
+ al = SSL_AD_INTERNAL_ERROR;
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ }
+ }
+
+ switch (ret)
+ {
+ case SSL_TLSEXT_ERR_ALERT_FATAL:
+ ssl3_send_alert(s,SSL3_AL_FATAL,al);
+ return -1;
+
+ case SSL_TLSEXT_ERR_ALERT_WARNING:
+ ssl3_send_alert(s,SSL3_AL_WARNING,al);
+ return 1;
+
+ case SSL_TLSEXT_ERR_NOACK:
+ s->servername_done=0;
+ default:
+ return 1;
+ }
+ }
+
+/* Since the server cache lookup is done early on in the processing of client
+ * hello and other operations depend on the result we need to handle any TLS
+ * session ticket extension at the same time.
+ */
+
+int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
+ const unsigned char *limit, SSL_SESSION **ret)
+ {
+ /* Point after session ID in client hello */
+ const unsigned char *p = session_id + len;
+ unsigned short i;
+
+ /* If tickets disabled behave as if no ticket present
+ * to permit stateful resumption.
+ */
+ if (SSL_get_options(s) & SSL_OP_NO_TICKET)
+ return 1;
+
+ if ((s->version <= SSL3_VERSION) || !limit)
+ return 1;
+ if (p >= limit)
+ return -1;
+ /* Skip past DTLS cookie */
+ if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
+ {
+ i = *(p++);
+ p+= i;
+ if (p >= limit)
+ return -1;
+ }
+ /* Skip past cipher list */
+ n2s(p, i);
+ p+= i;
+ if (p >= limit)
+ return -1;
+ /* Skip past compression algorithm list */
+ i = *(p++);
+ p += i;
+ if (p > limit)
+ return -1;
+ /* Now at start of extensions */
+ if ((p + 2) >= limit)
+ return 1;
+ n2s(p, i);
+ while ((p + 4) <= limit)
+ {
+ unsigned short type, size;
+ n2s(p, type);
+ n2s(p, size);
+ if (p + size > limit)
+ return 1;
+ if (type == TLSEXT_TYPE_session_ticket)
+ {
+ /* If tickets disabled indicate cache miss which will
+ * trigger a full handshake
+ */
+ if (SSL_get_options(s) & SSL_OP_NO_TICKET)
+ return 1;
+ /* If zero length note client will accept a ticket
+ * and indicate cache miss to trigger full handshake
+ */
+ if (size == 0)
+ {
+ s->tlsext_ticket_expected = 1;
+ return 0; /* Cache miss */
+ }
+ if (s->tls_session_secret_cb)
+ {
+ /* Indicate cache miss here and instead of
+ * generating the session from ticket now,
+ * trigger abbreviated handshake based on
+ * external mechanism to calculate the master
+ * secret later. */
+ return 0;
+ }
+ return tls_decrypt_ticket(s, p, size, session_id, len,
+ ret);
+ }
+ p += size;
+ }
+ return 1;
+ }
+
+static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
+ const unsigned char *sess_id, int sesslen,
+ SSL_SESSION **psess)
+ {
+ SSL_SESSION *sess;
+ unsigned char *sdec;
+ const unsigned char *p;
+ int slen, mlen, renew_ticket = 0;
+ unsigned char tick_hmac[EVP_MAX_MD_SIZE];
+ HMAC_CTX hctx;
+ EVP_CIPHER_CTX ctx;
+ SSL_CTX *tctx = s->initial_ctx;
+ /* Need at least keyname + iv + some encrypted data */
+ if (eticklen < 48)
+ goto tickerr;
+ /* Initialize session ticket encryption and HMAC contexts */
+ HMAC_CTX_init(&hctx);
+ EVP_CIPHER_CTX_init(&ctx);
+ if (tctx->tlsext_ticket_key_cb)
+ {
+ unsigned char *nctick = (unsigned char *)etick;
+ int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
+ &ctx, &hctx, 0);
+ if (rv < 0)
+ return -1;
+ if (rv == 0)
+ goto tickerr;
+ if (rv == 2)
+ renew_ticket = 1;
+ }
+ else
+ {
+ /* Check key name matches */
+ if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
+ goto tickerr;
+ HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+ tlsext_tick_md(), NULL);
+ EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+ tctx->tlsext_tick_aes_key, etick + 16);
+ }
+ /* Attempt to process session ticket, first conduct sanity and
+ * integrity checks on ticket.
+ */
+ mlen = HMAC_size(&hctx);
+ if (mlen < 0)
+ {
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return -1;
+ }
+ eticklen -= mlen;
+ /* Check HMAC of encrypted ticket */
+ HMAC_Update(&hctx, etick, eticklen);
+ HMAC_Final(&hctx, tick_hmac, NULL);
+ HMAC_CTX_cleanup(&hctx);
+ if (memcmp(tick_hmac, etick + eticklen, mlen))
+ goto tickerr;
+ /* Attempt to decrypt session data */
+ /* Move p after IV to start of encrypted ticket, update length */
+ p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
+ eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
+ sdec = OPENSSL_malloc(eticklen);
+ if (!sdec)
+ {
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return -1;
+ }
+ EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
+ if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0)
+ goto tickerr;
+ slen += mlen;
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ p = sdec;
+
+ sess = d2i_SSL_SESSION(NULL, &p, slen);
+ OPENSSL_free(sdec);
+ if (sess)
+ {
+ /* The session ID if non-empty is used by some clients to
+ * detect that the ticket has been accepted. So we copy it to
+ * the session structure. If it is empty set length to zero
+ * as required by standard.
+ */
+ if (sesslen)
+ memcpy(sess->session_id, sess_id, sesslen);
+ sess->session_id_length = sesslen;
+ *psess = sess;
+ s->tlsext_ticket_expected = renew_ticket;
+ return 1;
+ }
+ /* If session decrypt failure indicate a cache miss and set state to
+ * send a new ticket
+ */
+ tickerr:
+ s->tlsext_ticket_expected = 1;
+ return 0;
+ }
+
+#endif
diff --git a/openssl/test/maketests.com b/openssl/test/maketests.com
index cf9eaa117..5dd797e35 100644
--- a/openssl/test/maketests.com
+++ b/openssl/test/maketests.com
@@ -1,986 +1,986 @@
-$!
-$! MAKETESTS.COM
-$! Written By: Robert Byer
-$! Vice-President
-$! A-Com Computing, Inc.
-$! byer@mail.all-net.net
-$!
-$! Changes by Richard Levitte <richard@levitte.org>
-$!
-$! This command files compiles and creates all the various different
-$! "test" programs for the different types of encryption for OpenSSL.
-$! It was written so it would try to determine what "C" compiler to
-$! use or you can specify which "C" compiler to use.
-$!
-$! The test "executables" will be placed in a directory called
-$! [.xxx.EXE.TEST] where "xxx" denotes ALPHA, IA64, or VAX, depending
-$! on your machine architecture.
-$!
-$! Specify DEBUG or NODEBUG P1 to compile with or without debugger
-$! information.
-$!
-$! Specify which compiler at P2 to try to compile under.
-$!
-$! VAXC For VAX C.
-$! DECC For DEC C.
-$! GNUC For GNU C.
-$!
-$! If you don't speficy a compiler, it will try to determine which
-$! "C" compiler to use.
-$!
-$! P3, if defined, sets a TCP/IP library to use, through one of the following
-$! keywords:
-$!
-$! UCX for UCX
-$! SOCKETSHR for SOCKETSHR+NETLIB
-$!
-$! P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
-$!
-$! For 64 bit architectures (Alpha and IA64), specify the pointer size as P5.
-$! For 32 bit architectures (VAX), P5 is ignored.
-$! Currently supported values are:
-$!
-$! 32 To ge a library compiled with /POINTER_SIZE=32
-$! 64 To ge a library compiled with /POINTER_SIZE=64
-$!
-$!
-$! Define A TCP/IP Library That We Will Need To Link To.
-$! (That is, If Wee Need To Link To One.)
-$!
-$ TCPIP_LIB = ""
-$!
-$! Check Which Architecture We Are Using.
-$!
-$ if (f$getsyi( "HW_MODEL") .lt. 1024)
-$ then
-$ arch = "VAX"
-$ else
-$ arch = ""
-$ arch = arch+ f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
-$ if (arch .eqs. "") then arch = "UNK"
-$ endif
-$!
-$! Define The OBJ and EXE Directories (EXE before CHECK_OPTIONS).
-$!
-$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.TEST]
-$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.TEST]
-$!
-$! Check To Make Sure We Have Valid Command Line Parameters.
-$!
-$ GOSUB CHECK_OPTIONS
-$!
-$! Initialise logical names and such
-$!
-$ GOSUB INITIALISE
-$!
-$! Tell The User What Kind of Machine We Run On.
-$!
-$ WRITE SYS$OUTPUT "Compiling On ''ARCH'."
-$!
-$! Define The CRYPTO-LIB We Are To Use.
-$!
-$ CRYPTO_LIB := SYS$DISK:[-.'ARCH'.EXE.CRYPTO]LIBCRYPTO'LIB32'.OLB
-$!
-$! Define The SSL We Are To Use.
-$!
-$ SSL_LIB := SYS$DISK:[-.'ARCH'.EXE.SSL]LIBSSL'LIB32'.OLB
-$!
-$! Create the OBJ and EXE Directories, if needed.
-$!
-$ IF (F$PARSE(OBJ_DIR).EQS."") THEN -
- CREATE /DIRECTORY 'OBJ_DIR'
-$ IF (F$PARSE(EXE_DIR).EQS."") THEN -
- CREATE /DIRECTORY 'EXE_DIR'
-$!
-$! Check To See If We Have The Proper Libraries.
-$!
-$ GOSUB LIB_CHECK
-$!
-$! Check To See If We Have A Linker Option File.
-$!
-$ GOSUB CHECK_OPT_FILE
-$!
-$! Define The TEST Files.
-$! NOTE: Some might think this list ugly. However, it's made this way to
-$! reflect the EXE variable in Makefile as closely as possible,
-$! thereby making it fairly easy to verify that the lists are the same.
-$!
-$ TEST_FILES = "BNTEST,ECTEST,ECDSATEST,ECDHTEST,IDEATEST,"+ -
- "MD2TEST,MD4TEST,MD5TEST,HMACTEST,WP_TEST,"+ -
- "RC2TEST,RC4TEST,RC5TEST,"+ -
- "DESTEST,SHATEST,SHA1TEST,SHA256T,SHA512T,"+ -
- "MDC2TEST,RMDTEST,"+ -
- "RANDTEST,DHTEST,ENGINETEST,"+ -
- "BFTEST,CASTTEST,SSLTEST,EXPTEST,DSATEST,RSA_TEST,"+ -
- "EVP_TEST,IGETEST,JPAKETEST,ASN1TEST"
-$! Should we add MTTEST,PQ_TEST,LH_TEST,DIVTEST,TABTEST as well?
-$!
-$! Additional directory information.
-$ T_D_BNTEST := [-.crypto.bn]
-$ T_D_ECTEST := [-.crypto.ec]
-$ T_D_ECDSATEST := [-.crypto.ecdsa]
-$ T_D_ECDHTEST := [-.crypto.ecdh]
-$ T_D_IDEATEST := [-.crypto.idea]
-$ T_D_MD2TEST := [-.crypto.md2]
-$ T_D_MD4TEST := [-.crypto.md4]
-$ T_D_MD5TEST := [-.crypto.md5]
-$ T_D_HMACTEST := [-.crypto.hmac]
-$ T_D_WP_TEST := [-.crypto.whrlpool]
-$ T_D_RC2TEST := [-.crypto.rc2]
-$ T_D_RC4TEST := [-.crypto.rc4]
-$ T_D_RC5TEST := [-.crypto.rc5]
-$ T_D_DESTEST := [-.crypto.des]
-$ T_D_SHATEST := [-.crypto.sha]
-$ T_D_SHA1TEST := [-.crypto.sha]
-$ T_D_SHA256T := [-.crypto.sha]
-$ T_D_SHA512T := [-.crypto.sha]
-$ T_D_MDC2TEST := [-.crypto.mdc2]
-$ T_D_RMDTEST := [-.crypto.ripemd]
-$ T_D_RANDTEST := [-.crypto.rand]
-$ T_D_DHTEST := [-.crypto.dh]
-$ T_D_ENGINETEST := [-.crypto.engine]
-$ T_D_BFTEST := [-.crypto.bf]
-$ T_D_CASTTEST := [-.crypto.cast]
-$ T_D_SSLTEST := [-.ssl]
-$ T_D_EXPTEST := [-.crypto.bn]
-$ T_D_DSATEST := [-.crypto.dsa]
-$ T_D_RSA_TEST := [-.crypto.rsa]
-$ T_D_EVP_TEST := [-.crypto.evp]
-$ T_D_IGETEST := [-.test]
-$ T_D_JPAKETEST := [-.crypto.jpake]
-$ T_D_ASN1TEST := [-.test]
-$!
-$ TCPIP_PROGRAMS = ",,"
-$ IF COMPILER .EQS. "VAXC" THEN -
- TCPIP_PROGRAMS = ",SSLTEST,"
-$!
-$! Define A File Counter And Set It To "0".
-$!
-$ FILE_COUNTER = 0
-$!
-$! Top Of The File Loop.
-$!
-$ NEXT_FILE:
-$!
-$! O.K, Extract The File Name From The File List.
-$!
-$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",TEST_FILES)
-$!
-$! Check To See If We Are At The End Of The File List.
-$!
-$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
-$!
-$! Increment The Counter.
-$!
-$ FILE_COUNTER = FILE_COUNTER + 1
-$!
-$! Create The Source File Name.
-$!
-$ SOURCE_FILE = "SYS$DISK:" + T_D_'FILE_NAME' + FILE_NAME + ".C"
-$!
-$! Create The Object File Name.
-$!
-$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
-$!
-$! Create The Executable File Name.
-$!
-$ EXE_FILE = EXE_DIR + FILE_NAME + ".EXE"
-$ ON WARNING THEN GOTO NEXT_FILE
-$!
-$! Check To See If The File We Want To Compile Actually Exists.
-$!
-$ IF (F$SEARCH(SOURCE_FILE).EQS."")
-$ THEN
-$!
-$! Tell The User That The File Dosen't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ GOTO EXIT
-$ ENDIF
-$!
-$! Tell The User What We Are Building.
-$!
-$ WRITE SYS$OUTPUT "Building The ",FILE_NAME," Test Program."
-$!
-$! Compile The File.
-$!
-$ ON ERROR THEN GOTO NEXT_FILE
-$ CC /OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ON WARNING THEN GOTO NEXT_FILE
-$!
-$! Check If What We Are About To Compile Works Without A TCP/IP Library.
-$!
-$ IF ((TCPIP_LIB.EQS."").AND.((TCPIP_PROGRAMS-FILE_NAME).NES.TCPIP_PROGRAMS))
-$ THEN
-$!
-$! Inform The User That A TCP/IP Library Is Needed To Compile This Program.
-$!
-$ WRITE SYS$OUTPUT -
- FILE_NAME," Needs A TCP/IP Library. Can't Link. Skipping..."
-$ GOTO NEXT_FILE
-$!
-$! End The TCP/IP Library Check.
-$!
-$ ENDIF
-$!
-$! Link The Program, Check To See If We Need To Link With RSAREF Or Not.
-$! Check To See If We Are To Link With A Specific TCP/IP Library.
-$!
-$ IF (TCPIP_LIB.NES."")
-$ THEN
-$!
-$! Don't Link With The RSAREF Routines And TCP/IP Library.
-$!
-$ LINK /'DEBUGGER' /'TRACEBACK' /EXECTABLE = 'EXE_FILE' -
- 'OBJECT_FILE', -
- 'SSL_LIB' /LIBRARY, -
- 'CRYPTO_LIB' /LIBRARY, -
- 'TCPIP_LIB', -
- 'OPT_FILE' /OPTIONS
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Don't Link With The RSAREF Routines And Link With A TCP/IP Library.
-$!
-$ LINK /'DEBUGGER' /'TRACEBACK' /EXECUTABLE = 'EXE_FILE' -
- 'OBJECT_FILE', -
- 'SSL_LIB' /LIBRARY, -
- 'CRYPTO_LIB' /LIBRARY, -
- 'OPT_FILE' /OPTIONS
-$!
-$! End The TCP/IP Library Check.
-$!
-$ ENDIF
-$!
-$! Go Back And Do It Again.
-$!
-$ GOTO NEXT_FILE
-$!
-$! All Done With This Library Part.
-$!
-$ FILE_DONE:
-$!
-$! All Done, Time To Exit.
-$!
-$ EXIT:
-$ GOSUB CLEANUP
-$ EXIT
-$!
-$! Check For The Link Option FIle.
-$!
-$ CHECK_OPT_FILE:
-$!
-$! Check To See If We Need To Make A VAX C Option File.
-$!
-$ IF (COMPILER.EQS."VAXC")
-$ THEN
-$!
-$! Check To See If We Already Have A VAX C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A VAX C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Against
-! The Sharable VAX C Runtime Library.
-!
-SYS$SHARE:VAXCRTL.EXE /SHAREABLE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The VAXC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A GNU C Option File.
-$!
-$ IF (COMPILER.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If We Already Have A GNU C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A GNU C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable C Runtime Library.
-!
-GNU_CC:[000000]GCCLIB.OLB /LIBRARY
-SYS$SHARE:VAXCRTL.EXE /SHAREABLE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A DEC C Option File.
-$!
-$ IF (COMPILER.EQS."DECC")
-$ THEN
-$!
-$! Check To See If We Already Have A DEC C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! Figure Out If We Need A non-VAX Or A VAX Linker Option File.
-$!
-$ IF (ARCH.EQS."VAX")
-$ THEN
-$!
-$! We Need A DEC C Linker Option File For VAX.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable DEC C Runtime Library.
-!
-SYS$SHARE:DECC$SHR.EXE /SHAREABLE
-$EOD
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Create The non-VAX Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File For non-VAX To Link Agianst
-! The Sharable C Runtime Library.
-!
-SYS$SHARE:CMA$OPEN_LIB_SHR.EXE /SHAREABLE
-SYS$SHARE:CMA$OPEN_RTL.EXE /SHAREABLE
-$EOD
-$!
-$! End The DEC C Option File Check.
-$!
-$ ENDIF
-$!
-$! End The Option File Search.
-$!
-$ ENDIF
-$!
-$! End The DEC C Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What Linker Option File We Are Using.
-$!
-$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
-$!
-$! Time To RETURN.
-$!
-$ RETURN
-$!
-$! Check To See If We Have The Appropiate Libraries.
-$!
-$ LIB_CHECK:
-$!
-$! Look For The Library LIBCRYPTO.OLB.
-$!
-$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
-$ THEN
-$!
-$! Tell The User We Can't Find The LIBCRYPTO.OLB Library.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
-$ WRITE SYS$OUTPUT "We Can't Link Without It."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Since We Can't Link Without It, Exit.
-$!
-$ EXIT
-$!
-$! End The Crypto Library Check.
-$!
-$ ENDIF
-$!
-$! Look For The Library LIBSSL.OLB.
-$!
-$ IF (F$SEARCH(SSL_LIB).EQS."")
-$ THEN
-$!
-$! Tell The User We Can't Find The LIBSSL.OLB Library.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
-$ WRITE SYS$OUTPUT "Some Of The Test Programs Need To Link To It."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Since We Can't Link Without It, Exit.
-$!
-$ EXIT
-$!
-$! End The SSL Library Check.
-$!
-$ ENDIF
-$!
-$! Time To Return.
-$!
-$ RETURN
-$!
-$! Check The User's Options.
-$!
-$ CHECK_OPTIONS:
-$!
-$! Check To See If P1 Is Blank.
-$!
-$ IF (P1.EQS."NODEBUG")
-$ THEN
-$!
-$! P1 Is NODEBUG, So Compile Without Debugger Information.
-$!
-$ DEBUGGER = "NODEBUG"
-$ TRACEBACK = "NOTRACEBACK"
-$ GCC_OPTIMIZE = "OPTIMIZE"
-$ CC_OPTIMIZE = "OPTIMIZE"
-$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Check To See If We Are To Compile With Debugger Information.
-$!
-$ IF (P1.EQS."DEBUG")
-$ THEN
-$!
-$! Compile With Debugger Information.
-$!
-$ DEBUGGER = "DEBUG"
-$ TRACEBACK = "TRACEBACK"
-$ GCC_OPTIMIZE = "NOOPTIMIZE"
-$ CC_OPTIMIZE = "NOOPTIMIZE"
-$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
-$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Arguement Check.
-$!
-$ ENDIF
-$!
-$! End The P1 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P5 Is Blank.
-$!
-$ IF (P5.EQS."")
-$ THEN
-$ POINTER_SIZE = ""
-$ ELSE
-$!
-$! Check is P5 Is Valid
-$!
-$ IF (P5.EQS."32")
-$ THEN
-$ POINTER_SIZE = "/POINTER_SIZE=32"
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ LIB32 = ""
-$ ELSE
-$ LIB32 = "32"
-$ ENDIF
-$ ELSE
-$ IF (P5.EQS."64")
-$ THEN
-$ LIB32 = ""
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$ POINTER_SIZE = "/POINTER_SIZE=32"
-$ ELSE
-$ POINTER_SIZE = "/POINTER_SIZE=64"
-$ ENDIF
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P5," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " 32 : Compile with 32 bit pointer size"
-$ WRITE SYS$OUTPUT " 64 : Compile with 64 bit pointer size"
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ GOTO TIDY
-$!
-$! End The Valid Arguement Check.
-$!
-$ ENDIF
-$ ENDIF
-$!
-$! End The P5 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P2 Is Blank.
-$!
-$ IF (P2.EQS."")
-$ THEN
-$!
-$! O.K., The User Didn't Specify A Compiler, Let's Try To
-$! Find Out Which One To Use.
-$!
-$! Check To See If We Have GNU C.
-$!
-$ IF (F$TRNLNM("GNU_CC").NES."")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ P2 = "GNUC"
-$!
-$! End The GNU C Compiler Check.
-$!
-$ ELSE
-$!
-$! Check To See If We Have VAXC Or DECC.
-$!
-$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ P2 = "DECC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ P2 = "VAXC"
-$!
-$! End The VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The DECC & VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The Compiler Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Have A Option For P3.
-$!
-$ IF (P3.EQS."")
-$ THEN
-$!
-$! Find out what socket library we have available
-$!
-$ IF F$PARSE("SOCKETSHR:") .NES. ""
-$ THEN
-$!
-$! We have SOCKETSHR, and it is my opinion that it's the best to use.
-$!
-$ P3 = "SOCKETSHR"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
-$!
-$! Else, let's look for something else
-$!
-$ ELSE
-$!
-$! Like UCX (the reason to do this before Multinet is that the UCX
-$! emulation is easier to use...)
-$!
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
- .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
- .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
-$ THEN
-$!
-$! Last resort: a UCX or UCX-compatible library
-$!
-$ P3 = "UCX"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
-$!
-$! That was all...
-$!
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$!
-$! Set Up Initial CC Definitions, Possibly With User Ones
-$!
-$ CCDEFS = "TCPIP_TYPE_''P3'"
-$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
-$ CCEXTRAFLAGS = ""
-$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
-$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
-$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
- CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
-$!
-$! Check To See If The User Entered A Valid Paramter.
-$!
-$ IF (P2.EQS."VAXC").OR.(P2.EQS."DECC").OR.(P2.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If The User Wanted DECC.
-$!
-$ IF (P2.EQS."DECC")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ COMPILER = "DECC"
-$!
-$! Tell The User We Are Using DECC.
-$!
-$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
-$!
-$! Use DECC...
-$!
-$ CC = "CC"
-$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
- THEN CC = "CC /DECC"
-$ CC = CC + "/''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=ANSI89 ''POINTER_SIZE'" + -
- "/NOLIST /PREFIX=ALL" + -
- "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
-$!
-$! End DECC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use VAXC.
-$!
-$ IF (P2.EQS."VAXC")
-$ THEN
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ COMPILER = "VAXC"
-$!
-$! Tell The User We Are Using VAX C.
-$!
-$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
-$!
-$! Compile Using VAXC.
-$!
-$ CC = "CC"
-$ IF ARCH.NES."VAX"
-$ THEN
-$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
-$ EXIT
-$ ENDIF
-$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC /VAXC"
-$ CC = CC + "/''CC_OPTIMIZE' /''DEBUGGER' /NOLIST" + -
- "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
-$ CCDEFS = CCDEFS + ",""VAXC"""
-$!
-$! Define <sys> As SYS$COMMON:[SYSLIB]
-$!
-$ DEFINE /NOLOG SYS SYS$COMMON:[SYSLIB]
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
-$!
-$! End VAXC Check
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use GNU C.
-$!
-$ IF (P2.EQS."GNUC")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ COMPILER = "GNUC"
-$!
-$! Tell The User We Are Using GNUC.
-$!
-$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
-$!
-$! Use GNU C...
-$!
-$ CC = "GCC /NOCASE_HACK /''GCC_OPTIMIZE' /''DEBUGGER' /NOLIST" + -
- "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Set up default defines
-$!
-$ CCDEFS = """FLAT_INC=1""," + CCDEFS
-$!
-$! Finish up the definition of CC.
-$!
-$ IF COMPILER .EQS. "DECC"
-$ THEN
-$ IF CCDISABLEWARNINGS .EQS. ""
-$ THEN
-$ CC4DISABLEWARNINGS = "DOLLARID"
-$ ELSE
-$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
-$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
-$ ENDIF
-$ CC4DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
-$ ELSE
-$ CCDISABLEWARNINGS = ""
-$ CC4DISABLEWARNINGS = ""
-$ ENDIF
-$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
-$!
-$! Show user the result
-$!
-$ WRITE /SYMBOL SYS$OUTPUT "Main Compiling Command: ", CC
-$!
-$! Else The User Entered An Invalid Arguement.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
-$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
-$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$ ENDIF
-$!
-$! Time to check the contents, and to make sure we get the correct library.
-$!
-$ IF P3.EQS."SOCKETSHR" .OR. P3.EQS."MULTINET" .OR. P3.EQS."UCX" -
- .OR. P3.EQS."TCPIP" .OR. P3.EQS."NONE"
-$ THEN
-$!
-$! Check to see if SOCKETSHR was chosen
-$!
-$ IF P3.EQS."SOCKETSHR"
-$ THEN
-$!
-$! Set the library to use SOCKETSHR
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
-$!
-$! Done with SOCKETSHR
-$!
-$ ENDIF
-$!
-$! Check to see if MULTINET was chosen
-$!
-$ IF P3.EQS."MULTINET"
-$ THEN
-$!
-$! Set the library to use UCX emulation.
-$!
-$ P3 = "UCX"
-$!
-$! Done with MULTINET
-$!
-$ ENDIF
-$!
-$! Check to see if UCX was chosen
-$!
-$ IF P3.EQS."UCX"
-$ THEN
-$!
-$! Set the library to use UCX.
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
-$ THEN
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
-$ ELSE
-$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
- TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
-$ ENDIF
-$!
-$! Done with UCX
-$!
-$ ENDIF
-$!
-$! Check to see if TCPIP was chosen
-$!
-$ IF P3.EQS."TCPIP"
-$ THEN
-$!
-$! Set the library to use TCPIP (post UCX).
-$!
-$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
-$!
-$! Done with TCPIP
-$!
-$ ENDIF
-$!
-$! Check to see if NONE was chosen
-$!
-$ IF P3.EQS."NONE"
-$ THEN
-$!
-$! Do not use a TCPIP library.
-$!
-$ TCPIP_LIB = ""
-$!
-$! Done with NONE
-$!
-$ ENDIF
-$!
-$! Print info
-$!
-$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
-$!
-$! Else The User Entered An Invalid Arguement.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
-$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
-$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! Done with TCP/IP libraries
-$!
-$ ENDIF
-$!
-$! Special Threads For OpenVMS v7.1 Or Later
-$!
-$! Written By: Richard Levitte
-$! richard@levitte.org
-$!
-$!
-$! Check To See If We Have A Option For P4.
-$!
-$ IF (P4.EQS."")
-$ THEN
-$!
-$! Get The Version Of VMS We Are Using.
-$!
-$ ISSEVEN :=
-$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
-$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
-$!
-$! Check To See If The VMS Version Is v7.1 Or Later.
-$!
-$ IF (TMP.GE.71)
-$ THEN
-$!
-$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
-$!
-$ ISSEVEN := ,PTHREAD_USE_D4
-$!
-$! End The VMS Version Check.
-$!
-$ ENDIF
-$!
-$! End The P4 Check.
-$!
-$ ENDIF
-$!
-$! Time To RETURN...
-$!
-$ RETURN
-$!
-$ INITIALISE:
-$!
-$! Save old value of the logical name OPENSSL
-$!
-$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
-$!
-$! Save directory information
-$!
-$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
-$ __HERE = F$EDIT(__HERE,"UPCASE")
-$ __TOP = __HERE - "TEST]"
-$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
-$!
-$! Set up the logical name OPENSSL to point at the include directory
-$!
-$ DEFINE OPENSSL /NOLOG '__INCLUDE'
-$!
-$! Done
-$!
-$ RETURN
-$!
-$ CLEANUP:
-$!
-$! Restore the logical name OPENSSL if it had a value
-$!
-$ IF __SAVE_OPENSSL .EQS. ""
-$ THEN
-$ DEASSIGN OPENSSL
-$ ELSE
-$ DEFINE /NOLOG OPENSSL '__SAVE_OPENSSL'
-$ ENDIF
-$!
-$! Done
-$!
-$ RETURN
+$!
+$! MAKETESTS.COM
+$! Written By: Robert Byer
+$! Vice-President
+$! A-Com Computing, Inc.
+$! byer@mail.all-net.net
+$!
+$! Changes by Richard Levitte <richard@levitte.org>
+$!
+$! This command files compiles and creates all the various different
+$! "test" programs for the different types of encryption for OpenSSL.
+$! It was written so it would try to determine what "C" compiler to
+$! use or you can specify which "C" compiler to use.
+$!
+$! The test "executables" will be placed in a directory called
+$! [.xxx.EXE.TEST] where "xxx" denotes ALPHA, IA64, or VAX, depending
+$! on your machine architecture.
+$!
+$! Specify DEBUG or NODEBUG P1 to compile with or without debugger
+$! information.
+$!
+$! Specify which compiler at P2 to try to compile under.
+$!
+$! VAXC For VAX C.
+$! DECC For DEC C.
+$! GNUC For GNU C.
+$!
+$! If you don't speficy a compiler, it will try to determine which
+$! "C" compiler to use.
+$!
+$! P3, if defined, sets a TCP/IP library to use, through one of the following
+$! keywords:
+$!
+$! UCX for UCX
+$! SOCKETSHR for SOCKETSHR+NETLIB
+$!
+$! P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$! For 64 bit architectures (Alpha and IA64), specify the pointer size as P5.
+$! For 32 bit architectures (VAX), P5 is ignored.
+$! Currently supported values are:
+$!
+$! 32 To ge a library compiled with /POINTER_SIZE=32
+$! 64 To ge a library compiled with /POINTER_SIZE=64
+$!
+$!
+$! Define A TCP/IP Library That We Will Need To Link To.
+$! (That is, If Wee Need To Link To One.)
+$!
+$ TCPIP_LIB = ""
+$!
+$! Check Which Architecture We Are Using.
+$!
+$ if (f$getsyi( "HW_MODEL") .lt. 1024)
+$ then
+$ arch = "VAX"
+$ else
+$ arch = ""
+$ arch = arch+ f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
+$ if (arch .eqs. "") then arch = "UNK"
+$ endif
+$!
+$! Define The OBJ and EXE Directories (EXE before CHECK_OPTIONS).
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.TEST]
+$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.TEST]
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Initialise logical names and such
+$!
+$ GOSUB INITIALISE
+$!
+$! Tell The User What Kind of Machine We Run On.
+$!
+$ WRITE SYS$OUTPUT "Compiling On ''ARCH'."
+$!
+$! Define The CRYPTO-LIB We Are To Use.
+$!
+$ CRYPTO_LIB := SYS$DISK:[-.'ARCH'.EXE.CRYPTO]LIBCRYPTO'LIB32'.OLB
+$!
+$! Define The SSL We Are To Use.
+$!
+$ SSL_LIB := SYS$DISK:[-.'ARCH'.EXE.SSL]LIBSSL'LIB32'.OLB
+$!
+$! Create the OBJ and EXE Directories, if needed.
+$!
+$ IF (F$PARSE(OBJ_DIR).EQS."") THEN -
+ CREATE /DIRECTORY 'OBJ_DIR'
+$ IF (F$PARSE(EXE_DIR).EQS."") THEN -
+ CREATE /DIRECTORY 'EXE_DIR'
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Define The TEST Files.
+$! NOTE: Some might think this list ugly. However, it's made this way to
+$! reflect the EXE variable in Makefile as closely as possible,
+$! thereby making it fairly easy to verify that the lists are the same.
+$!
+$ TEST_FILES = "BNTEST,ECTEST,ECDSATEST,ECDHTEST,IDEATEST,"+ -
+ "MD2TEST,MD4TEST,MD5TEST,HMACTEST,WP_TEST,"+ -
+ "RC2TEST,RC4TEST,RC5TEST,"+ -
+ "DESTEST,SHATEST,SHA1TEST,SHA256T,SHA512T,"+ -
+ "MDC2TEST,RMDTEST,"+ -
+ "RANDTEST,DHTEST,ENGINETEST,"+ -
+ "BFTEST,CASTTEST,SSLTEST,EXPTEST,DSATEST,RSA_TEST,"+ -
+ "EVP_TEST,IGETEST,JPAKETEST,ASN1TEST"
+$! Should we add MTTEST,PQ_TEST,LH_TEST,DIVTEST,TABTEST as well?
+$!
+$! Additional directory information.
+$ T_D_BNTEST := [-.crypto.bn]
+$ T_D_ECTEST := [-.crypto.ec]
+$ T_D_ECDSATEST := [-.crypto.ecdsa]
+$ T_D_ECDHTEST := [-.crypto.ecdh]
+$ T_D_IDEATEST := [-.crypto.idea]
+$ T_D_MD2TEST := [-.crypto.md2]
+$ T_D_MD4TEST := [-.crypto.md4]
+$ T_D_MD5TEST := [-.crypto.md5]
+$ T_D_HMACTEST := [-.crypto.hmac]
+$ T_D_WP_TEST := [-.crypto.whrlpool]
+$ T_D_RC2TEST := [-.crypto.rc2]
+$ T_D_RC4TEST := [-.crypto.rc4]
+$ T_D_RC5TEST := [-.crypto.rc5]
+$ T_D_DESTEST := [-.crypto.des]
+$ T_D_SHATEST := [-.crypto.sha]
+$ T_D_SHA1TEST := [-.crypto.sha]
+$ T_D_SHA256T := [-.crypto.sha]
+$ T_D_SHA512T := [-.crypto.sha]
+$ T_D_MDC2TEST := [-.crypto.mdc2]
+$ T_D_RMDTEST := [-.crypto.ripemd]
+$ T_D_RANDTEST := [-.crypto.rand]
+$ T_D_DHTEST := [-.crypto.dh]
+$ T_D_ENGINETEST := [-.crypto.engine]
+$ T_D_BFTEST := [-.crypto.bf]
+$ T_D_CASTTEST := [-.crypto.cast]
+$ T_D_SSLTEST := [-.ssl]
+$ T_D_EXPTEST := [-.crypto.bn]
+$ T_D_DSATEST := [-.crypto.dsa]
+$ T_D_RSA_TEST := [-.crypto.rsa]
+$ T_D_EVP_TEST := [-.crypto.evp]
+$ T_D_IGETEST := [-.test]
+$ T_D_JPAKETEST := [-.crypto.jpake]
+$ T_D_ASN1TEST := [-.test]
+$!
+$ TCPIP_PROGRAMS = ",,"
+$ IF COMPILER .EQS. "VAXC" THEN -
+ TCPIP_PROGRAMS = ",SSLTEST,"
+$!
+$! Define A File Counter And Set It To "0".
+$!
+$ FILE_COUNTER = 0
+$!
+$! Top Of The File Loop.
+$!
+$ NEXT_FILE:
+$!
+$! O.K, Extract The File Name From The File List.
+$!
+$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",TEST_FILES)
+$!
+$! Check To See If We Are At The End Of The File List.
+$!
+$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
+$!
+$! Increment The Counter.
+$!
+$ FILE_COUNTER = FILE_COUNTER + 1
+$!
+$! Create The Source File Name.
+$!
+$ SOURCE_FILE = "SYS$DISK:" + T_D_'FILE_NAME' + FILE_NAME + ".C"
+$!
+$! Create The Object File Name.
+$!
+$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
+$!
+$! Create The Executable File Name.
+$!
+$ EXE_FILE = EXE_DIR + FILE_NAME + ".EXE"
+$ ON WARNING THEN GOTO NEXT_FILE
+$!
+$! Check To See If The File We Want To Compile Actually Exists.
+$!
+$ IF (F$SEARCH(SOURCE_FILE).EQS."")
+$ THEN
+$!
+$! Tell The User That The File Dosen't Exist.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Exit The Build.
+$!
+$ GOTO EXIT
+$ ENDIF
+$!
+$! Tell The User What We Are Building.
+$!
+$ WRITE SYS$OUTPUT "Building The ",FILE_NAME," Test Program."
+$!
+$! Compile The File.
+$!
+$ ON ERROR THEN GOTO NEXT_FILE
+$ CC /OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ON WARNING THEN GOTO NEXT_FILE
+$!
+$! Check If What We Are About To Compile Works Without A TCP/IP Library.
+$!
+$ IF ((TCPIP_LIB.EQS."").AND.((TCPIP_PROGRAMS-FILE_NAME).NES.TCPIP_PROGRAMS))
+$ THEN
+$!
+$! Inform The User That A TCP/IP Library Is Needed To Compile This Program.
+$!
+$ WRITE SYS$OUTPUT -
+ FILE_NAME," Needs A TCP/IP Library. Can't Link. Skipping..."
+$ GOTO NEXT_FILE
+$!
+$! End The TCP/IP Library Check.
+$!
+$ ENDIF
+$!
+$! Link The Program, Check To See If We Need To Link With RSAREF Or Not.
+$! Check To See If We Are To Link With A Specific TCP/IP Library.
+$!
+$ IF (TCPIP_LIB.NES."")
+$ THEN
+$!
+$! Don't Link With The RSAREF Routines And TCP/IP Library.
+$!
+$ LINK /'DEBUGGER' /'TRACEBACK' /EXECTABLE = 'EXE_FILE' -
+ 'OBJECT_FILE', -
+ 'SSL_LIB' /LIBRARY, -
+ 'CRYPTO_LIB' /LIBRARY, -
+ 'TCPIP_LIB', -
+ 'OPT_FILE' /OPTIONS
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Don't Link With The RSAREF Routines And Link With A TCP/IP Library.
+$!
+$ LINK /'DEBUGGER' /'TRACEBACK' /EXECUTABLE = 'EXE_FILE' -
+ 'OBJECT_FILE', -
+ 'SSL_LIB' /LIBRARY, -
+ 'CRYPTO_LIB' /LIBRARY, -
+ 'OPT_FILE' /OPTIONS
+$!
+$! End The TCP/IP Library Check.
+$!
+$ ENDIF
+$!
+$! Go Back And Do It Again.
+$!
+$ GOTO NEXT_FILE
+$!
+$! All Done With This Library Part.
+$!
+$ FILE_DONE:
+$!
+$! All Done, Time To Exit.
+$!
+$ EXIT:
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$! Check To See If We Already Have A VAX C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A VAX C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Against
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE /SHAREABLE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If We Already Have A GNU C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A GNU C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB.OLB /LIBRARY
+SYS$SHARE:VAXCRTL.EXE /SHAREABLE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$! Check To See If We Already Have A DEC C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! Figure Out If We Need A non-VAX Or A VAX Linker Option File.
+$!
+$ IF (ARCH.EQS."VAX")
+$ THEN
+$!
+$! We Need A DEC C Linker Option File For VAX.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE /SHAREABLE
+$EOD
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Create The non-VAX Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Agianst
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR.EXE /SHAREABLE
+SYS$SHARE:CMA$OPEN_RTL.EXE /SHAREABLE
+$EOD
+$!
+$! End The DEC C Option File Check.
+$!
+$ ENDIF
+$!
+$! End The Option File Search.
+$!
+$ ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check To See If We Have The Appropiate Libraries.
+$!
+$ LIB_CHECK:
+$!
+$! Look For The Library LIBCRYPTO.OLB.
+$!
+$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
+$ THEN
+$!
+$! Tell The User We Can't Find The LIBCRYPTO.OLB Library.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
+$ WRITE SYS$OUTPUT "We Can't Link Without It."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Since We Can't Link Without It, Exit.
+$!
+$ EXIT
+$!
+$! End The Crypto Library Check.
+$!
+$ ENDIF
+$!
+$! Look For The Library LIBSSL.OLB.
+$!
+$ IF (F$SEARCH(SSL_LIB).EQS."")
+$ THEN
+$!
+$! Tell The User We Can't Find The LIBSSL.OLB Library.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
+$ WRITE SYS$OUTPUT "Some Of The Test Programs Need To Link To It."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Since We Can't Link Without It, Exit.
+$!
+$ EXIT
+$!
+$! End The SSL Library Check.
+$!
+$ ENDIF
+$!
+$! Time To Return.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."NODEBUG")
+$ THEN
+$!
+$! P1 Is NODEBUG, So Compile Without Debugger Information.
+$!
+$ DEBUGGER = "NODEBUG"
+$ TRACEBACK = "NOTRACEBACK"
+$ GCC_OPTIMIZE = "OPTIMIZE"
+$ CC_OPTIMIZE = "OPTIMIZE"
+$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Check To See If We Are To Compile With Debugger Information.
+$!
+$ IF (P1.EQS."DEBUG")
+$ THEN
+$!
+$! Compile With Debugger Information.
+$!
+$ DEBUGGER = "DEBUG"
+$ TRACEBACK = "TRACEBACK"
+$ GCC_OPTIMIZE = "NOOPTIMIZE"
+$ CC_OPTIMIZE = "NOOPTIMIZE"
+$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
+$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Arguement Check.
+$!
+$ ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P5 Is Blank.
+$!
+$ IF (P5.EQS."")
+$ THEN
+$ POINTER_SIZE = ""
+$ ELSE
+$!
+$! Check is P5 Is Valid
+$!
+$ IF (P5.EQS."32")
+$ THEN
+$ POINTER_SIZE = "/POINTER_SIZE=32"
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ LIB32 = ""
+$ ELSE
+$ LIB32 = "32"
+$ ENDIF
+$ ELSE
+$ IF (P5.EQS."64")
+$ THEN
+$ LIB32 = ""
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ POINTER_SIZE = "/POINTER_SIZE=32"
+$ ELSE
+$ POINTER_SIZE = "/POINTER_SIZE=64"
+$ ENDIF
+$ ELSE
+$!
+$! Tell The User Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P5," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " 32 : Compile with 32 bit pointer size"
+$ WRITE SYS$OUTPUT " 64 : Compile with 64 bit pointer size"
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ GOTO TIDY
+$!
+$! End The Valid Arguement Check.
+$!
+$ ENDIF
+$ ENDIF
+$!
+$! End The P5 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P2 Is Blank.
+$!
+$ IF (P2.EQS."")
+$ THEN
+$!
+$! O.K., The User Didn't Specify A Compiler, Let's Try To
+$! Find Out Which One To Use.
+$!
+$! Check To See If We Have GNU C.
+$!
+$ IF (F$TRNLNM("GNU_CC").NES."")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ P2 = "GNUC"
+$!
+$! End The GNU C Compiler Check.
+$!
+$ ELSE
+$!
+$! Check To See If We Have VAXC Or DECC.
+$!
+$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ P2 = "DECC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ P2 = "VAXC"
+$!
+$! End The VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The DECC & VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For P3.
+$!
+$ IF (P3.EQS."")
+$ THEN
+$!
+$! Find out what socket library we have available
+$!
+$ IF F$PARSE("SOCKETSHR:") .NES. ""
+$ THEN
+$!
+$! We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$ P3 = "SOCKETSHR"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$! Else, let's look for something else
+$!
+$ ELSE
+$!
+$! Like UCX (the reason to do this before Multinet is that the UCX
+$! emulation is easier to use...)
+$!
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+ .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+ .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$ THEN
+$!
+$! Last resort: a UCX or UCX-compatible library
+$!
+$ P3 = "UCX"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$! That was all...
+$!
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "TCPIP_TYPE_''P3'"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+ CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If The User Entered A Valid Paramter.
+$!
+$ IF (P2.EQS."VAXC").OR.(P2.EQS."DECC").OR.(P2.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If The User Wanted DECC.
+$!
+$ IF (P2.EQS."DECC")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ COMPILER = "DECC"
+$!
+$! Tell The User We Are Using DECC.
+$!
+$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$! Use DECC...
+$!
+$ CC = "CC"
+$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+ THEN CC = "CC /DECC"
+$ CC = CC + "/''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=ANSI89 ''POINTER_SIZE'" + -
+ "/NOLIST /PREFIX=ALL" + -
+ "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
+$!
+$! End DECC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use VAXC.
+$!
+$ IF (P2.EQS."VAXC")
+$ THEN
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ COMPILER = "VAXC"
+$!
+$! Tell The User We Are Using VAX C.
+$!
+$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$! Compile Using VAXC.
+$!
+$ CC = "CC"
+$ IF ARCH.NES."VAX"
+$ THEN
+$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
+$ EXIT
+$ ENDIF
+$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC /VAXC"
+$ CC = CC + "/''CC_OPTIMIZE' /''DEBUGGER' /NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
+$ CCDEFS = CCDEFS + ",""VAXC"""
+$!
+$! Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$ DEFINE /NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
+$!
+$! End VAXC Check
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use GNU C.
+$!
+$ IF (P2.EQS."GNUC")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ COMPILER = "GNUC"
+$!
+$! Tell The User We Are Using GNUC.
+$!
+$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$! Use GNU C...
+$!
+$ CC = "GCC /NOCASE_HACK /''GCC_OPTIMIZE' /''DEBUGGER' /NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Set up default defines
+$!
+$ CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$! Finish up the definition of CC.
+$!
+$ IF COMPILER .EQS. "DECC"
+$ THEN
+$ IF CCDISABLEWARNINGS .EQS. ""
+$ THEN
+$ CC4DISABLEWARNINGS = "DOLLARID"
+$ ELSE
+$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
+$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$ ENDIF
+$ CC4DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
+$ ELSE
+$ CCDISABLEWARNINGS = ""
+$ CC4DISABLEWARNINGS = ""
+$ ENDIF
+$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$!
+$! Show user the result
+$!
+$ WRITE /SYMBOL SYS$OUTPUT "Main Compiling Command: ", CC
+$!
+$! Else The User Entered An Invalid Arguement.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
+$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
+$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$ ENDIF
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF P3.EQS."SOCKETSHR" .OR. P3.EQS."MULTINET" .OR. P3.EQS."UCX" -
+ .OR. P3.EQS."TCPIP" .OR. P3.EQS."NONE"
+$ THEN
+$!
+$! Check to see if SOCKETSHR was chosen
+$!
+$ IF P3.EQS."SOCKETSHR"
+$ THEN
+$!
+$! Set the library to use SOCKETSHR
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
+$!
+$! Done with SOCKETSHR
+$!
+$ ENDIF
+$!
+$! Check to see if MULTINET was chosen
+$!
+$ IF P3.EQS."MULTINET"
+$ THEN
+$!
+$! Set the library to use UCX emulation.
+$!
+$ P3 = "UCX"
+$!
+$! Done with MULTINET
+$!
+$ ENDIF
+$!
+$! Check to see if UCX was chosen
+$!
+$ IF P3.EQS."UCX"
+$ THEN
+$!
+$! Set the library to use UCX.
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$ THEN
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
+$ ELSE
+$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
+$ ENDIF
+$!
+$! Done with UCX
+$!
+$ ENDIF
+$!
+$! Check to see if TCPIP was chosen
+$!
+$ IF P3.EQS."TCPIP"
+$ THEN
+$!
+$! Set the library to use TCPIP (post UCX).
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Check to see if NONE was chosen
+$!
+$ IF P3.EQS."NONE"
+$ THEN
+$!
+$! Do not use a TCPIP library.
+$!
+$ TCPIP_LIB = ""
+$!
+$! Done with NONE
+$!
+$ ENDIF
+$!
+$! Print info
+$!
+$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
+$!
+$! Else The User Entered An Invalid Arguement.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
+$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
+$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By: Richard Levitte
+$! richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P4.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$! Get The Version Of VMS We Are Using.
+$!
+$ ISSEVEN :=
+$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$! Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$ IF (TMP.GE.71)
+$ THEN
+$!
+$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$ ISSEVEN := ,PTHREAD_USE_D4
+$!
+$! End The VMS Version Check.
+$!
+$ ENDIF
+$!
+$! End The P4 Check.
+$!
+$ ENDIF
+$!
+$! Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "TEST]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL /NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the logical name OPENSSL if it had a value
+$!
+$ IF __SAVE_OPENSSL .EQS. ""
+$ THEN
+$ DEASSIGN OPENSSL
+$ ELSE
+$ DEFINE /NOLOG OPENSSL '__SAVE_OPENSSL'
+$ ENDIF
+$!
+$! Done
+$!
+$ RETURN
diff --git a/openssl/util/mk1mf.pl b/openssl/util/mk1mf.pl
index 2387cebb3..e3db14b62 100644
--- a/openssl/util/mk1mf.pl
+++ b/openssl/util/mk1mf.pl
@@ -1,1224 +1,1224 @@
-#!/usr/local/bin/perl
-# A bit of an evil hack but it post processes the file ../MINFO which
-# is generated by `make files` in the top directory.
-# This script outputs one mega makefile that has no shell stuff or any
-# funny stuff
-#
-
-$INSTALLTOP="/usr/local/ssl";
-$OPENSSLDIR="/usr/local/ssl";
-$OPTIONS="";
-$ssl_version="";
-$banner="\t\@echo Building OpenSSL";
-
-my $no_static_engine = 1;
-my $engines = "";
-my $otherlibs = "";
-local $zlib_opt = 0; # 0 = no zlib, 1 = static, 2 = dynamic
-local $zlib_lib = "";
-local $perl_asm = 0; # 1 to autobuild asm files from perl scripts
-
-# Options to import from top level Makefile
-
-my %mf_import = (
- VERSION => \$ssl_version,
- OPTIONS => \$OPTIONS,
- INSTALLTOP => \$INSTALLTOP,
- OPENSSLDIR => \$OPENSSLDIR,
- PLATFORM => \$mf_platform,
- CFLAG => \$mf_cflag,
- DEPFLAG => \$mf_depflag,
- CPUID_OBJ => \$mf_cpuid_asm,
- BN_ASM => \$mf_bn_asm,
- DES_ENC => \$mf_des_asm,
- AES_ENC => \$mf_aes_asm,
- BF_ENC => \$mf_bf_asm,
- CAST_ENC => \$mf_cast_asm,
- RC4_ENC => \$mf_rc4_asm,
- RC5_ENC => \$mf_rc5_asm,
- MD5_ASM_OBJ => \$mf_md5_asm,
- SHA1_ASM_OBJ => \$mf_sha_asm,
- RMD160_ASM_OBJ => \$mf_rmd_asm,
- WP_ASM_OBJ => \$mf_wp_asm,
- CMLL_ENC => \$mf_cm_asm
-);
-
-
-open(IN,"<Makefile") || die "unable to open Makefile!\n";
-while(<IN>) {
- my ($mf_opt, $mf_ref);
- while (($mf_opt, $mf_ref) = each %mf_import) {
- if (/^$mf_opt\s*=\s*(.*)$/) {
- $$mf_ref = $1;
- }
- }
-}
-close(IN);
-
-$debug = 1 if $mf_platform =~ /^debug-/;
-
-die "Makefile is not the toplevel Makefile!\n" if $ssl_version eq "";
-
-$infile="MINFO";
-
-%ops=(
- "VC-WIN32", "Microsoft Visual C++ [4-6] - Windows NT or 9X",
- "VC-WIN64I", "Microsoft C/C++ - Win64/IA-64",
- "VC-WIN64A", "Microsoft C/C++ - Win64/x64",
- "VC-CE", "Microsoft eMbedded Visual C++ 3.0 - Windows CE ONLY",
- "VC-NT", "Microsoft Visual C++ [4-6] - Windows NT ONLY",
- "Mingw32", "GNU C++ - Windows NT or 9x",
- "Mingw32-files", "Create files with DOS copy ...",
- "BC-NT", "Borland C++ 4.5 - Windows NT",
- "linux-elf","Linux elf",
- "ultrix-mips","DEC mips ultrix",
- "FreeBSD","FreeBSD distribution",
- "OS2-EMX", "EMX GCC OS/2",
- "netware-clib", "CodeWarrior for NetWare - CLib - with WinSock Sockets",
- "netware-clib-bsdsock", "CodeWarrior for NetWare - CLib - with BSD Sockets",
- "netware-libc", "CodeWarrior for NetWare - LibC - with WinSock Sockets",
- "netware-libc-bsdsock", "CodeWarrior for NetWare - LibC - with BSD Sockets",
- "default","cc under unix",
- "auto", "auto detect from top level Makefile"
- );
-
-$platform="";
-my $xcflags="";
-foreach (@ARGV)
- {
- if (!&read_options && !defined($ops{$_}))
- {
- print STDERR "unknown option - $_\n";
- print STDERR "usage: perl mk1mf.pl [options] [system]\n";
- print STDERR "\nwhere [system] can be one of the following\n";
- foreach $i (sort keys %ops)
- { printf STDERR "\t%-10s\t%s\n",$i,$ops{$i}; }
- print STDERR <<"EOF";
-and [options] can be one of
- no-md2 no-md4 no-md5 no-sha no-mdc2 - Skip this digest
- no-ripemd
- no-rc2 no-rc4 no-rc5 no-idea no-des - Skip this symetric cipher
- no-bf no-cast no-aes no-camellia no-seed
- no-rsa no-dsa no-dh - Skip this public key cipher
- no-ssl2 no-ssl3 - Skip this version of SSL
- just-ssl - remove all non-ssl keys/digest
- no-asm - No x86 asm
- no-krb5 - No KRB5
- no-ec - No EC
- no-ecdsa - No ECDSA
- no-ecdh - No ECDH
- no-engine - No engine
- no-hw - No hw
- nasm - Use NASM for x86 asm
- nw-nasm - Use NASM x86 asm for NetWare
- nw-mwasm - Use Metrowerks x86 asm for NetWare
- gaswin - Use GNU as with Mingw32
- no-socks - No socket code
- no-err - No error strings
- dll/shlib - Build shared libraries (MS)
- debug - Debug build
- profile - Profiling build
- gcc - Use Gcc (unix)
-
-Values that can be set
-TMP=tmpdir OUT=outdir SRC=srcdir BIN=binpath INC=header-outdir CC=C-compiler
-
--L<ex_lib_path> -l<ex_lib> - extra library flags (unix)
--<ex_cc_flags> - extra 'cc' flags,
- added (MS), or replace (unix)
-EOF
- exit(1);
- }
- $platform=$_;
- }
-foreach (grep(!/^$/, split(/ /, $OPTIONS)))
- {
- print STDERR "unknown option - $_\n" if !&read_options;
- }
-
-$no_static_engine = 0 if (!$shlib);
-
-$no_mdc2=1 if ($no_des);
-
-$no_ssl3=1 if ($no_md5 || $no_sha);
-$no_ssl3=1 if ($no_rsa && $no_dh);
-
-$no_ssl2=1 if ($no_md5);
-$no_ssl2=1 if ($no_rsa);
-
-$out_def="out";
-$inc_def="outinc";
-$tmp_def="tmp";
-
-$perl="perl" unless defined $perl;
-$mkdir="-mkdir" unless defined $mkdir;
-
-($ssl,$crypto)=("ssl","crypto");
-$ranlib="echo ranlib";
-
-$cc=(defined($VARS{'CC'}))?$VARS{'CC'}:'cc';
-$src_dir=(defined($VARS{'SRC'}))?$VARS{'SRC'}:'.';
-$bin_dir=(defined($VARS{'BIN'}))?$VARS{'BIN'}:'';
-
-# $bin_dir.=$o causes a core dump on my sparc :-(
-
-
-$NT=0;
-
-push(@INC,"util/pl","pl");
-
-if ($platform eq "auto") {
- $platform = $mf_platform;
- print STDERR "Imported platform $mf_platform\n";
-}
-
-if (($platform =~ /VC-(.+)/))
- {
- $FLAVOR=$1;
- $NT = 1 if $1 eq "NT";
- require 'VC-32.pl';
- }
-elsif ($platform eq "Mingw32")
- {
- require 'Mingw32.pl';
- }
-elsif ($platform eq "Mingw32-files")
- {
- require 'Mingw32f.pl';
- }
-elsif ($platform eq "BC-NT")
- {
- $bc=1;
- require 'BC-32.pl';
- }
-elsif ($platform eq "FreeBSD")
- {
- require 'unix.pl';
- $cflags='-DTERMIO -D_ANSI_SOURCE -O2 -fomit-frame-pointer';
- }
-elsif ($platform eq "linux-elf")
- {
- require "unix.pl";
- require "linux.pl";
- $unix=1;
- }
-elsif ($platform eq "ultrix-mips")
- {
- require "unix.pl";
- require "ultrix.pl";
- $unix=1;
- }
-elsif ($platform eq "OS2-EMX")
- {
- $wc=1;
- require 'OS2-EMX.pl';
- }
-elsif (($platform eq "netware-clib") || ($platform eq "netware-libc") ||
- ($platform eq "netware-clib-bsdsock") || ($platform eq "netware-libc-bsdsock"))
- {
- $LIBC=1 if $platform eq "netware-libc" || $platform eq "netware-libc-bsdsock";
- $BSDSOCK=1 if ($platform eq "netware-libc-bsdsock") || ($platform eq "netware-clib-bsdsock");
- require 'netware.pl';
- }
-else
- {
- require "unix.pl";
-
- $unix=1;
- $cflags.=' -DTERMIO';
- }
-
-$out_dir=(defined($VARS{'OUT'}))?$VARS{'OUT'}:$out_def.($debug?".dbg":"");
-$tmp_dir=(defined($VARS{'TMP'}))?$VARS{'TMP'}:$tmp_def.($debug?".dbg":"");
-$inc_dir=(defined($VARS{'INC'}))?$VARS{'INC'}:$inc_def;
-
-$bin_dir=$bin_dir.$o unless ((substr($bin_dir,-1,1) eq $o) || ($bin_dir eq ''));
-
-$cflags= "$xcflags$cflags" if $xcflags ne "";
-$cdflags= "$xcflags$cflags" if $xcdflags ne "";
-
-$cflags.=" -DOPENSSL_NO_IDEA" if $no_idea;
-$cdflags.=" -DOPENSSL_NO_IDEA" if $no_idea;
-$cflags.=" -DOPENSSL_NO_AES" if $no_aes;
-$cdflags.=" -DOPENSSL_NO_AES" if $no_aes;
-$cflags.=" -DOPENSSL_NO_CAMELLIA" if $no_camellia;
-$cdflags.=" -DOPENSSL_NO_CAMELLIA" if $no_camellia;
-$cflags.=" -DOPENSSL_NO_SEED" if $no_seed;
-$cdflags.=" -DOPENSSL_NO_SEED" if $no_seed;
-$cflags.=" -DOPENSSL_NO_RC2" if $no_rc2;
-$cdflags.=" -DOPENSSL_NO_RC2" if $no_rc2;
-$cflags.=" -DOPENSSL_NO_RC4" if $no_rc4;
-$cdflags.=" -DOPENSSL_NO_RC4" if $no_rc4;
-$cflags.=" -DOPENSSL_NO_RC5" if $no_rc5;
-$cdflags.=" -DOPENSSL_NO_RC5" if $no_rc5;
-$cflags.=" -DOPENSSL_NO_MD2" if $no_md2;
-$cdflags.=" -DOPENSSL_NO_MD2" if $no_md2;
-$cflags.=" -DOPENSSL_NO_MD4" if $no_md4;
-$cdflags.=" -DOPENSSL_NO_MD4" if $no_md4;
-$cflags.=" -DOPENSSL_NO_MD5" if $no_md5;
-$cdflags.=" -DOPENSSL_NO_MD5" if $no_md5;
-$cflags.=" -DOPENSSL_NO_SHA" if $no_sha;
-$cdflags.=" -DOPENSSL_NO_SHA" if $no_sha;
-$cflags.=" -DOPENSSL_NO_SHA1" if $no_sha1;
-$cdflags.=" -DOPENSSL_NO_SHA1" if $no_sha1;
-$cflags.=" -DOPENSSL_NO_RIPEMD" if $no_ripemd;
-$cdflags.=" -DOPENSSL_NO_RIPEMD" if $no_ripemd;
-$cflags.=" -DOPENSSL_NO_MDC2" if $no_mdc2;
-$cdflags.=" -DOPENSSL_NO_MDC2" if $no_mdc2;
-$cflags.=" -DOPENSSL_NO_BF" if $no_bf;
-$cdflags.=" -DOPENSSL_NO_BF" if $no_bf;
-$cflags.=" -DOPENSSL_NO_CAST" if $no_cast;
-$cdflags.=" -DOPENSSL_NO_CAST" if $no_cast;
-$cflags.=" -DOPENSSL_NO_DES" if $no_des;
-$cdflags.=" -DOPENSSL_NO_DES" if $no_des;
-$cflags.=" -DOPENSSL_NO_RSA" if $no_rsa;
-$cdflags.=" -DOPENSSL_NO_RSA" if $no_rsa;
-$cflags.=" -DOPENSSL_NO_DSA" if $no_dsa;
-$cdflags.=" -DOPENSSL_NO_DSA" if $no_dsa;
-$cflags.=" -DOPENSSL_NO_DH" if $no_dh;
-$cdflags.=" -DOPENSSL_NO_DH" if $no_dh;
-$cflags.=" -DOPENSSL_NO_WHIRLPOOL" if $no_whirlpool;
-$cdflags.=" -DOPENSSL_NO_WHIRLPOOL" if $no_whirlpool;
-$cflags.=" -DOPENSSL_NO_SOCK" if $no_sock;
-$cdflags.=" -DOPENSSL_NO_SOCK" if $no_sock;
-$cflags.=" -DOPENSSL_NO_SSL2" if $no_ssl2;
-$cdflags.=" -DOPENSSL_NO_SSL2" if $no_ssl2;
-$cflags.=" -DOPENSSL_NO_SSL3" if $no_ssl3;
-$cdflags.=" -DOPENSSL_NO_SSL3" if $no_ssl3;
-$cflags.=" -DOPENSSL_NO_TLSEXT" if $no_tlsext;
-$cdflags.=" -DOPENSSL_NO_TLSEXT" if $no_tlsext;
-$cflags.=" -DOPENSSL_NO_CMS" if $no_cms;
-$cdflags.=" -DOPENSSL_NO_CMS" if $no_cms;
-$cflags.=" -DOPENSSL_NO_ERR" if $no_err;
-$cdflags.=" -DOPENSSL_NO_ERR" if $no_err;
-$cflags.=" -DOPENSSL_NO_KRB5" if $no_krb5;
-$cdflags.=" -DOPENSSL_NO_KRB5" if $no_krb5;
-$cflags.=" -DOPENSSL_NO_EC" if $no_ec;
-$cdflags.=" -DOPENSSL_NO_EC" if $no_ec;
-$cflags.=" -DOPENSSL_NO_ECDSA" if $no_ecdsa;
-$cdflags.=" -DOPENSSL_NO_ECDSA" if $no_ecdsa;
-$cflags.=" -DOPENSSL_NO_ECDH" if $no_ecdh;
-$cdflags.=" -DOPENSSL_NO_ECDH" if $no_ecdh;
-$cflags.=" -DOPENSSL_NO_GOST" if $no_gost;
-$cdflags.=" -DOPENSSL_NO_GOST" if $no_gost;
-$cflags.=" -DOPENSSL_NO_ENGINE" if $no_engine;
-$cdflags.=" -DOPENSSL_NO_ENGINE" if $no_engine;
-$cflags.=" -DOPENSSL_NO_HW" if $no_hw;
-$cdflags.=" -DOPENSSL_NO_HW" if $no_hw;
-$cflags.=" -DOPENSSL_NO_JPAKE" if $no_jpake;
-$cdflags.=" -DOPENSSL_NO_JPAKE" if $no_jpake;
-$cflags.= " -DZLIB" if $zlib_opt;
-$cdflags.= " -DZLIB" if $zlib_opt;
-$cflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
-$cdflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
-
-if ($no_static_engine)
- {
- $cflags .= " -DOPENSSL_NO_STATIC_ENGINE";
- $cdflags .= " -DOPENSSL_NO_STATIC_ENGINE";
- }
-else
- {
- $cflags .= " -DOPENSSL_NO_DYNAMIC_ENGINE";
- $cdflags .= " -DOPENSSL_NO_DYNAMIC_ENGINE";
- }
-
-#$cflags.=" -DRSAref" if $rsaref ne "";
-
-## if ($unix)
-## { $cflags="$c_flags" if ($c_flags ne ""); }
-##else
- { $cflags="$c_flags$cflags" if ($c_flags ne ""); }
-
-$ex_libs="$l_flags$ex_libs" if ($l_flags ne "");
-
-
-%shlib_ex_cflags=("SSL" => " -DOPENSSL_BUILD_SHLIBSSL",
- "CRYPTO" => " -DOPENSSL_BUILD_SHLIBCRYPTO");
-
-if ($msdos)
- {
- $banner ="\t\@echo Make sure you have run 'perl Configure $platform' in the\n";
- $banner.="\t\@echo top level directory, if you don't have perl, you will\n";
- $banner.="\t\@echo need to probably edit crypto/bn/bn.h, check the\n";
- $banner.="\t\@echo documentation for details.\n";
- }
-
-# have to do this to allow $(CC) under unix
-$link="$bin_dir$link" if ($link !~ /^\$/);
-
-$INSTALLTOP =~ s|/|$o|g;
-$OPENSSLDIR =~ s|/|$o|g;
-
-#############################################
-# We parse in input file and 'store' info for later printing.
-open(IN,"<$infile") || die "unable to open $infile:$!\n";
-$_=<IN>;
-for (;;)
- {
- chop;
-
- ($key,$val)=/^([^=]+)=(.*)/;
- if ($key eq "RELATIVE_DIRECTORY")
- {
- if ($lib ne "")
- {
- $uc=$lib;
- $uc =~ s/^lib(.*)\.a/$1/;
- $uc =~ tr/a-z/A-Z/;
- $lib_nam{$uc}=$uc;
- $lib_obj{$uc}.=$libobj." ";
- }
- last if ($val eq "FINISHED");
- $lib="";
- $libobj="";
- $dir=$val;
- }
-
- if ($key eq "KRB5_INCLUDES")
- { $cflags .= " $val";}
-
- if ($key eq "ZLIB_INCLUDE")
- { $cflags .= " $val" if $val ne "";}
-
- if ($key eq "LIBZLIB")
- { $zlib_lib = "$val" if $val ne "";}
-
- if ($key eq "LIBKRB5")
- { $ex_libs .= " $val" if $val ne "";}
-
- if ($key eq "TEST")
- { $test.=&var_add($dir,$val, 0); }
-
- if (($key eq "PROGS") || ($key eq "E_OBJ"))
- { $e_exe.=&var_add($dir,$val, 0); }
-
- if ($key eq "LIB")
- {
- $lib=$val;
- $lib =~ s/^.*\/([^\/]+)$/$1/;
- }
- if ($key eq "LIBNAME" && $no_static_engine)
- {
- $lib=$val;
- $lib =~ s/^.*\/([^\/]+)$/$1/;
- $otherlibs .= " $lib";
- }
-
- if ($key eq "EXHEADER")
- { $exheader.=&var_add($dir,$val, 1); }
-
- if ($key eq "HEADER")
- { $header.=&var_add($dir,$val, 1); }
-
- if ($key eq "LIBOBJ" && ($dir ne "engines" || !$no_static_engine))
- { $libobj=&var_add($dir,$val, 0); }
- if ($key eq "LIBNAMES" && $dir eq "engines" && $no_static_engine)
- { $engines.=$val }
-
- if (!($_=<IN>))
- { $_="RELATIVE_DIRECTORY=FINISHED\n"; }
- }
-close(IN);
-
-if ($shlib)
- {
- $extra_install= <<"EOF";
- \$(CP) \"\$(O_SSL)\" \"\$(INSTALLTOP)${o}bin\"
- \$(CP) \"\$(O_CRYPTO)\" \"\$(INSTALLTOP)${o}bin\"
- \$(CP) \"\$(L_SSL)\" \"\$(INSTALLTOP)${o}lib\"
- \$(CP) \"\$(L_CRYPTO)\" \"\$(INSTALLTOP)${o}lib\"
-EOF
- if ($no_static_engine)
- {
- $extra_install .= <<"EOF"
- \$(MKDIR) \"\$(INSTALLTOP)${o}lib${o}engines\"
- \$(CP) \"\$(E_SHLIB)\" \"\$(INSTALLTOP)${o}lib${o}engines\"
-EOF
- }
- }
-else
- {
- $extra_install= <<"EOF";
- \$(CP) \"\$(O_SSL)\" \"\$(INSTALLTOP)${o}lib\"
- \$(CP) \"\$(O_CRYPTO)\" \"\$(INSTALLTOP)${o}lib\"
-EOF
- $ex_libs .= " $zlib_lib" if $zlib_opt == 1;
- }
-
-$defs= <<"EOF";
-# This makefile has been automatically generated from the OpenSSL distribution.
-# This single makefile will build the complete OpenSSL distribution and
-# by default leave the 'intertesting' output files in .${o}out and the stuff
-# that needs deleting in .${o}tmp.
-# The file was generated by running 'make makefile.one', which
-# does a 'make files', which writes all the environment variables from all
-# the makefiles to the file call MINFO. This file is used by
-# util${o}mk1mf.pl to generate makefile.one.
-# The 'makefile per directory' system suites me when developing this
-# library and also so I can 'distribute' indervidual library sections.
-# The one monster makefile better suits building in non-unix
-# environments.
-
-EOF
-
-$defs .= $preamble if defined $preamble;
-
-$defs.= <<"EOF";
-INSTALLTOP=$INSTALLTOP
-OPENSSLDIR=$OPENSSLDIR
-
-!ifdef DEBUG
-# The output directory for everything intersting
-OUT_D=out32_d
-# The output directory for all the temporary muck
-TMP_D=tmp32_d
-!else
-# The output directory for everything intersting
-OUT_D=out32
-# The output directory for all the temporary muck
-TMP_D=tmp32
-!endif
-
-# Set your compiler options
-PLATFORM=$platform
-CC=$bin_dir${cc}
-!ifdef DEBUG
-CFLAG=$cdflags
-!else
-CFLAG=$cflags
-!endif
-APP_CFLAG=$app_cflag
-LIB_CFLAG=$lib_cflag
-SHLIB_CFLAG=$shl_cflag
-APP_EX_OBJ=$app_ex_obj
-SHLIB_EX_OBJ=$shlib_ex_obj
-# add extra libraries to this define, for solaris -lsocket -lnsl would
-# be added
-EX_LIBS=$ex_libs
-
-# The OpenSSL directory
-SRC_D=$src_dir
-
-LINK=$link
-!ifdef DEBUG
-LFLAGS=$lflagsd
-!else
-LFLAGS=$lflags
-!endif
-RSC=$rsc
-
-# The output directory for the header files
-INC_D=$inc_dir
-INCO_D=$inc_dir${o}openssl
-
-PERL=$perl
-CP=$cp
-RM=$rm
-RANLIB=$ranlib
-MKDIR=$mkdir
-!ifdef DEBUG
-MKLIB=$bin_dir$mklibd
-!else
-MKLIB=$bin_dir$mklib
-!endif
-MLFLAGS=$mlflags
-ASM=$bin_dir$asm
-
-######################################################
-# You should not need to touch anything below this point
-######################################################
-
-E_EXE=openssl
-SSL=$ssl
-CRYPTO=$crypto
-
-# BIN_D - Binary output directory
-# TEST_D - Binary test file output directory
-# LIB_D - library output directory
-# ENG_D - dynamic engine output directory
-# Note: if you change these point to different directories then uncomment out
-# the lines around the 'NB' comment below.
-#
-BIN_D=\$(OUT_D)
-TEST_D=\$(OUT_D)
-LIB_D=\$(OUT_D)
-ENG_D=\$(OUT_D)
-
-# INCL_D - local library directory
-# OBJ_D - temp object file directory
-OBJ_D=\$(TMP_D)
-INCL_D=\$(TMP_D)
-
-O_SSL= \$(LIB_D)$o$plib\$(SSL)$shlibp
-O_CRYPTO= \$(LIB_D)$o$plib\$(CRYPTO)$shlibp
-SO_SSL= $plib\$(SSL)$so_shlibp
-SO_CRYPTO= $plib\$(CRYPTO)$so_shlibp
-L_SSL= \$(LIB_D)$o$plib\$(SSL)$libp
-L_CRYPTO= \$(LIB_D)$o$plib\$(CRYPTO)$libp
-
-L_LIBS= \$(L_SSL) \$(L_CRYPTO)
-
-######################################################
-# Don't touch anything below this point
-######################################################
-
-INC=-I\$(INC_D) -I\$(INCL_D)
-APP_CFLAGS=\$(INC) \$(CFLAG) \$(APP_CFLAG)
-LIB_CFLAGS=\$(INC) \$(CFLAG) \$(LIB_CFLAG)
-SHLIB_CFLAGS=\$(INC) \$(CFLAG) \$(LIB_CFLAG) \$(SHLIB_CFLAG)
-LIBS_DEP=\$(O_CRYPTO) \$(O_SSL)
-
-#############################################
-EOF
-
-$rules=<<"EOF";
-all: banner \$(TMP_D) \$(BIN_D) \$(TEST_D) \$(LIB_D) \$(INCO_D) headers lib exe
-
-banner:
-$banner
-
-\$(TMP_D):
- \$(MKDIR) \"\$(TMP_D)\"
-# NB: uncomment out these lines if BIN_D, TEST_D and LIB_D are different
-#\$(BIN_D):
-# \$(MKDIR) \$(BIN_D)
-#
-#\$(TEST_D):
-# \$(MKDIR) \$(TEST_D)
-
-\$(LIB_D):
- \$(MKDIR) \"\$(LIB_D)\"
-
-\$(INCO_D): \$(INC_D)
- \$(MKDIR) \"\$(INCO_D)\"
-
-\$(INC_D):
- \$(MKDIR) \"\$(INC_D)\"
-
-headers: \$(HEADER) \$(EXHEADER)
- @
-
-lib: \$(LIBS_DEP) \$(E_SHLIB)
-
-exe: \$(T_EXE) \$(BIN_D)$o\$(E_EXE)$exep
-
-install: all
- \$(MKDIR) \"\$(INSTALLTOP)\"
- \$(MKDIR) \"\$(INSTALLTOP)${o}bin\"
- \$(MKDIR) \"\$(INSTALLTOP)${o}include\"
- \$(MKDIR) \"\$(INSTALLTOP)${o}include${o}openssl\"
- \$(MKDIR) \"\$(INSTALLTOP)${o}lib\"
- \$(CP) \"\$(INCO_D)${o}*.\[ch\]\" \"\$(INSTALLTOP)${o}include${o}openssl\"
- \$(CP) \"\$(BIN_D)$o\$(E_EXE)$exep \$(INSTALLTOP)${o}bin\"
- \$(MKDIR) \"\$(OPENSSLDIR)\"
- \$(CP) apps${o}openssl.cnf \"\$(OPENSSLDIR)\"
-$extra_install
-
-
-test: \$(T_EXE)
- cd \$(BIN_D)
- ..${o}ms${o}test
-
-clean:
- \$(RM) \$(TMP_D)$o*.*
-
-vclean:
- \$(RM) \$(TMP_D)$o*.*
- \$(RM) \$(OUT_D)$o*.*
-
-EOF
-
-my $platform_cpp_symbol = "MK1MF_PLATFORM_$platform";
-$platform_cpp_symbol =~ s/-/_/g;
-if (open(IN,"crypto/buildinf.h"))
- {
- # Remove entry for this platform in existing file buildinf.h.
-
- my $old_buildinf_h = "";
- while (<IN>)
- {
- if (/^\#ifdef $platform_cpp_symbol$/)
- {
- while (<IN>) { last if (/^\#endif/); }
- }
- else
- {
- $old_buildinf_h .= $_;
- }
- }
- close(IN);
-
- open(OUT,">crypto/buildinf.h") || die "Can't open buildinf.h";
- print OUT $old_buildinf_h;
- close(OUT);
- }
-
-open (OUT,">>crypto/buildinf.h") || die "Can't open buildinf.h";
-printf OUT <<EOF;
-#ifdef $platform_cpp_symbol
- /* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
- #define CFLAGS "$cc $cflags"
- #define PLATFORM "$platform"
-EOF
-printf OUT " #define DATE \"%s\"\n", scalar gmtime();
-printf OUT "#endif\n";
-close(OUT);
-
-# Strip of trailing ' '
-foreach (keys %lib_obj) { $lib_obj{$_}=&clean_up_ws($lib_obj{$_}); }
-$test=&clean_up_ws($test);
-$e_exe=&clean_up_ws($e_exe);
-$exheader=&clean_up_ws($exheader);
-$header=&clean_up_ws($header);
-
-# First we strip the exheaders from the headers list
-foreach (split(/\s+/,$exheader)){ $h{$_}=1; }
-foreach (split(/\s+/,$header)) { $h.=$_." " unless $h{$_}; }
-chop($h); $header=$h;
-
-$defs.=&do_defs("HEADER",$header,"\$(INCL_D)","");
-$rules.=&do_copy_rule("\$(INCL_D)",$header,"");
-
-$defs.=&do_defs("EXHEADER",$exheader,"\$(INCO_D)","");
-$rules.=&do_copy_rule("\$(INCO_D)",$exheader,"");
-
-$defs.=&do_defs("T_OBJ",$test,"\$(OBJ_D)",$obj);
-$rules.=&do_compile_rule("\$(OBJ_D)",$test,"\$(APP_CFLAGS)");
-
-$defs.=&do_defs("E_OBJ",$e_exe,"\$(OBJ_D)",$obj);
-$rules.=&do_compile_rule("\$(OBJ_D)",$e_exe,'-DMONOLITH $(APP_CFLAGS)');
-
-foreach (values %lib_nam)
- {
- $lib_obj=$lib_obj{$_};
- local($slib)=$shlib;
-
- if (($_ eq "SSL") && $no_ssl2 && $no_ssl3)
- {
- $rules.="\$(O_SSL):\n\n";
- next;
- }
-
- $defs.=&do_defs(${_}."OBJ",$lib_obj,"\$(OBJ_D)",$obj);
- $lib=($slib)?" \$(SHLIB_CFLAGS)".$shlib_ex_cflags{$_}:" \$(LIB_CFLAGS)";
- $rules.=&do_compile_rule("\$(OBJ_D)",$lib_obj{$_},$lib);
- }
-
-# hack to add version info on MSVC
-if (($platform eq "VC-WIN32") || ($platform eq "VC-WIN64A")
- || ($platform eq "VC-WIN64I") || ($platform eq "VC-NT")) {
- $rules.= <<"EOF";
-\$(OBJ_D)\\\$(CRYPTO).res: ms\\version32.rc
- \$(RSC) /fo"\$(OBJ_D)\\\$(CRYPTO).res" /d CRYPTO ms\\version32.rc
-
-\$(OBJ_D)\\\$(SSL).res: ms\\version32.rc
- \$(RSC) /fo"\$(OBJ_D)\\\$(SSL).res" /d SSL ms\\version32.rc
-
-EOF
-}
-
-$defs.=&do_defs("T_EXE",$test,"\$(TEST_D)",$exep);
-foreach (split(/\s+/,$test))
- {
- $t=&bname($_);
- $tt="\$(OBJ_D)${o}$t${obj}";
- $rules.=&do_link_rule("\$(TEST_D)$o$t$exep",$tt,"\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)");
- }
-
-$defs.=&do_defs("E_SHLIB",$engines . $otherlibs,"\$(ENG_D)",$shlibp);
-
-foreach (split(/\s+/,$engines))
- {
- $rules.=&do_compile_rule("\$(OBJ_D)","engines${o}e_$_",$lib);
- $rules.= &do_lib_rule("\$(OBJ_D)${o}e_${_}.obj","\$(ENG_D)$o$_$shlibp","",$shlib,"");
- }
-
-
-
-$rules.= &do_lib_rule("\$(SSLOBJ)","\$(O_SSL)",$ssl,$shlib,"\$(SO_SSL)");
-$rules.= &do_lib_rule("\$(CRYPTOOBJ)","\$(O_CRYPTO)",$crypto,$shlib,"\$(SO_CRYPTO)");
-
-foreach (split(" ",$otherlibs))
- {
- my $uc = $_;
- $uc =~ tr /a-z/A-Z/;
- $rules.= &do_lib_rule("\$(${uc}OBJ)","\$(ENG_D)$o$_$shlibp", "", $shlib, "");
-
- }
-
-$rules.=&do_link_rule("\$(BIN_D)$o\$(E_EXE)$exep","\$(E_OBJ)","\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)");
-
-print $defs;
-
-if ($platform eq "linux-elf") {
- print <<"EOF";
-# Generate perlasm output files
-%.cpp:
- (cd \$(\@D)/..; PERL=perl make -f Makefile asm/\$(\@F))
-EOF
-}
-print "###################################################################\n";
-print $rules;
-
-###############################################
-# strip off any trailing .[och] and append the relative directory
-# also remembering to do nothing if we are in one of the dropped
-# directories
-sub var_add
- {
- local($dir,$val,$keepext)=@_;
- local(@a,$_,$ret);
-
- return("") if $no_engine && $dir =~ /\/engine/;
- return("") if $no_hw && $dir =~ /\/hw/;
- return("") if $no_idea && $dir =~ /\/idea/;
- return("") if $no_aes && $dir =~ /\/aes/;
- return("") if $no_camellia && $dir =~ /\/camellia/;
- return("") if $no_seed && $dir =~ /\/seed/;
- return("") if $no_rc2 && $dir =~ /\/rc2/;
- return("") if $no_rc4 && $dir =~ /\/rc4/;
- return("") if $no_rc5 && $dir =~ /\/rc5/;
- return("") if $no_rsa && $dir =~ /\/rsa/;
- return("") if $no_rsa && $dir =~ /^rsaref/;
- return("") if $no_dsa && $dir =~ /\/dsa/;
- return("") if $no_dh && $dir =~ /\/dh/;
- return("") if $no_ec && $dir =~ /\/ec/;
- return("") if $no_gost && $dir =~ /\/ccgost/;
- return("") if $no_cms && $dir =~ /\/cms/;
- return("") if $no_jpake && $dir =~ /\/jpake/;
- if ($no_des && $dir =~ /\/des/)
- {
- if ($val =~ /read_pwd/)
- { return("$dir/read_pwd "); }
- else
- { return(""); }
- }
- return("") if $no_mdc2 && $dir =~ /\/mdc2/;
- return("") if $no_sock && $dir =~ /\/proxy/;
- return("") if $no_bf && $dir =~ /\/bf/;
- return("") if $no_cast && $dir =~ /\/cast/;
- return("") if $no_whirlpool && $dir =~ /\/whrlpool/;
-
- $val =~ s/^\s*(.*)\s*$/$1/;
- @a=split(/\s+/,$val);
- grep(s/\.[och]$//,@a) unless $keepext;
-
- @a=grep(!/^e_.*_3d$/,@a) if $no_des;
- @a=grep(!/^e_.*_d$/,@a) if $no_des;
- @a=grep(!/^e_.*_ae$/,@a) if $no_idea;
- @a=grep(!/^e_.*_i$/,@a) if $no_aes;
- @a=grep(!/^e_.*_r2$/,@a) if $no_rc2;
- @a=grep(!/^e_.*_r5$/,@a) if $no_rc5;
- @a=grep(!/^e_.*_bf$/,@a) if $no_bf;
- @a=grep(!/^e_.*_c$/,@a) if $no_cast;
- @a=grep(!/^e_rc4$/,@a) if $no_rc4;
- @a=grep(!/^e_camellia$/,@a) if $no_camellia;
- @a=grep(!/^e_seed$/,@a) if $no_seed;
-
- #@a=grep(!/(^s2_)|(^s23_)/,@a) if $no_ssl2;
- #@a=grep(!/(^s3_)|(^s23_)/,@a) if $no_ssl3;
-
- @a=grep(!/(_sock$)|(_acpt$)|(_conn$)|(^pxy_)/,@a) if $no_sock;
-
- @a=grep(!/(^md2)|(_md2$)/,@a) if $no_md2;
- @a=grep(!/(^md4)|(_md4$)/,@a) if $no_md4;
- @a=grep(!/(^md5)|(_md5$)/,@a) if $no_md5;
- @a=grep(!/(rmd)|(ripemd)/,@a) if $no_ripemd;
-
- @a=grep(!/(^d2i_r_)|(^i2d_r_)/,@a) if $no_rsa;
- @a=grep(!/(^p_open$)|(^p_seal$)/,@a) if $no_rsa;
- @a=grep(!/(^pem_seal$)/,@a) if $no_rsa;
-
- @a=grep(!/(m_dss$)|(m_dss1$)/,@a) if $no_dsa;
- @a=grep(!/(^d2i_s_)|(^i2d_s_)|(_dsap$)/,@a) if $no_dsa;
-
- @a=grep(!/^n_pkey$/,@a) if $no_rsa || $no_rc4;
-
- @a=grep(!/_dhp$/,@a) if $no_dh;
-
- @a=grep(!/(^sha[^1])|(_sha$)|(m_dss$)/,@a) if $no_sha;
- @a=grep(!/(^sha1)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
- @a=grep(!/_mdc2$/,@a) if $no_mdc2;
-
- @a=grep(!/^engine$/,@a) if $no_engine;
- @a=grep(!/^hw$/,@a) if $no_hw;
- @a=grep(!/(^rsa$)|(^genrsa$)/,@a) if $no_rsa;
- @a=grep(!/(^dsa$)|(^gendsa$)|(^dsaparam$)/,@a) if $no_dsa;
- @a=grep(!/^gendsa$/,@a) if $no_sha1;
- @a=grep(!/(^dh$)|(^gendh$)/,@a) if $no_dh;
-
- @a=grep(!/(^dh)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
-
- grep($_="$dir/$_",@a);
- @a=grep(!/(^|\/)s_/,@a) if $no_sock;
- @a=grep(!/(^|\/)bio_sock/,@a) if $no_sock;
- $ret=join(' ',@a)." ";
- return($ret);
- }
-
-# change things so that each 'token' is only separated by one space
-sub clean_up_ws
- {
- local($w)=@_;
-
- $w =~ s/^\s*(.*)\s*$/$1/;
- $w =~ s/\s+/ /g;
- return($w);
- }
-
-sub do_defs
- {
- local($var,$files,$location,$postfix)=@_;
- local($_,$ret,$pf);
- local(*OUT,$tmp,$t);
-
- $files =~ s/\//$o/g if $o ne '/';
- $ret="$var=";
- $n=1;
- $Vars{$var}.="";
- foreach (split(/ /,$files))
- {
- $orig=$_;
- $_=&bname($_) unless /^\$/;
- if ($n++ == 2)
- {
- $n=0;
- $ret.="\\\n\t";
- }
- if (($_ =~ /bss_file/) && ($postfix eq ".h"))
- { $pf=".c"; }
- else { $pf=$postfix; }
- if ($_ =~ /BN_ASM/) { $t="$_ "; }
- elsif ($_ =~ /BNCO_ASM/){ $t="$_ "; }
- elsif ($_ =~ /AES_ASM/){ $t="$_ "; }
- elsif ($_ =~ /DES_ENC/) { $t="$_ "; }
- elsif ($_ =~ /BF_ENC/) { $t="$_ "; }
- elsif ($_ =~ /CAST_ENC/){ $t="$_ "; }
- elsif ($_ =~ /RC4_ENC/) { $t="$_ "; }
- elsif ($_ =~ /RC5_ENC/) { $t="$_ "; }
- elsif ($_ =~ /MD5_ASM/) { $t="$_ "; }
- elsif ($_ =~ /SHA1_ASM/){ $t="$_ "; }
- elsif ($_ =~ /RMD160_ASM/){ $t="$_ "; }
- elsif ($_ =~ /WHIRLPOOL_ASM/){ $t="$_ "; }
- elsif ($_ =~ /CPUID_ASM/){ $t="$_ "; }
- else { $t="$location${o}$_$pf "; }
-
- $Vars{$var}.="$t ";
- $ret.=$t;
- }
- # hack to add version info on MSVC
- if ($shlib && (($platform eq "VC-WIN32") || ($platfrom eq "VC-WIN64I") || ($platform eq "VC-WIN64A") || ($platform eq "VC-NT")))
- {
- if ($var eq "CRYPTOOBJ")
- { $ret.="\$(OBJ_D)\\\$(CRYPTO).res "; }
- elsif ($var eq "SSLOBJ")
- { $ret.="\$(OBJ_D)\\\$(SSL).res "; }
- }
- chomp($ret);
- $ret.="\n\n";
- return($ret);
- }
-
-# return the name with the leading path removed
-sub bname
- {
- local($ret)=@_;
- $ret =~ s/^.*[\\\/]([^\\\/]+)$/$1/;
- return($ret);
- }
-
-# return the leading path
-sub dname
- {
- my $ret=shift;
- $ret =~ s/(^.*)[\\\/][^\\\/]+$/$1/;
- return($ret);
- }
-
-##############################################################
-# do a rule for each file that says 'compile' to new direcory
-# compile the files in '$files' into $to
-sub do_compile_rule
- {
- local($to,$files,$ex)=@_;
- local($ret,$_,$n,$d,$s);
-
- $files =~ s/\//$o/g if $o ne '/';
- foreach (split(/\s+/,$files))
- {
- $n=&bname($_);
- $d=&dname($_);
- if (-f "${_}.c")
- {
- $ret.=&cc_compile_target("$to${o}$n$obj","${_}.c",$ex)
- }
- elsif (-f ($s="${d}${o}asm${o}${n}.pl") or
- ($s=~s/sha256/sha512/ and -f $s) or
- -f ($s="${d}${o}${n}.pl"))
- {
- $ret.=&perlasm_compile_target("$to${o}$n$obj",$s,$n);
- }
- elsif (-f ($s="${d}${o}asm${o}${n}.S") or
- -f ($s="${d}${o}${n}.S"))
- {
- $ret.=&Sasm_compile_target("$to${o}$n$obj",$s,$n);
- }
- else { die "no rule for $_"; }
- }
- return($ret);
- }
-
-##############################################################
-# do a rule for each file that says 'compile' to new direcory
-sub perlasm_compile_target
- {
- my($target,$source,$bname)=@_;
- my($ret);
-
- $bname =~ s/(.*)\.[^\.]$/$1/;
- $ret ="\$(TMP_D)$o$bname.asm: $source\n";
- $ret.="\t\$(PERL) $source $asmtype \$(CFLAG) >\$\@\n\n";
- $ret.="$target: \$(TMP_D)$o$bname.asm\n";
- $ret.="\t\$(ASM) $afile\$\@ \$(TMP_D)$o$bname.asm\n\n";
- return($ret);
- }
-
-sub Sasm_compile_target
- {
- my($target,$source,$bname)=@_;
- my($ret);
-
- $bname =~ s/(.*)\.[^\.]$/$1/;
- $ret ="\$(TMP_D)$o$bname.asm: $source\n";
- $ret.="\t\$(CC) -E \$(CFLAG) $source >\$\@\n\n";
- $ret.="$target: \$(TMP_D)$o$bname.asm\n";
- $ret.="\t\$(ASM) $afile\$\@ \$(TMP_D)$o$bname.asm\n\n";
- return($ret);
- }
-
-sub cc_compile_target
- {
- local($target,$source,$ex_flags)=@_;
- local($ret);
-
- $ex_flags.=" -DMK1MF_BUILD -D$platform_cpp_symbol" if ($source =~ /cversion/);
- $target =~ s/\//$o/g if $o ne "/";
- $source =~ s/\//$o/g if $o ne "/";
- $ret ="$target: \$(SRC_D)$o$source\n\t";
- $ret.="\$(CC) ${ofile}$target $ex_flags -c \$(SRC_D)$o$source\n\n";
- return($ret);
- }
-
-##############################################################
-sub do_asm_rule
- {
- local($target,$src)=@_;
- local($ret,@s,@t,$i);
-
- $target =~ s/\//$o/g if $o ne "/";
- $src =~ s/\//$o/g if $o ne "/";
-
- @t=split(/\s+/,$target);
- @s=split(/\s+/,$src);
-
-
- for ($i=0; $i<=$#s; $i++)
- {
- my $objfile = $t[$i];
- my $srcfile = $s[$i];
-
- if ($perl_asm == 1)
- {
- my $plasm = $objfile;
- $plasm =~ s/${obj}/.pl/;
- $ret.="$srcfile: $plasm\n";
- $ret.="\t\$(PERL) $plasm $asmtype \$(CFLAG) >$srcfile\n\n";
- }
-
- $ret.="$objfile: $srcfile\n";
- $ret.="\t\$(ASM) $afile$objfile \$(SRC_D)$o$srcfile\n\n";
- }
- return($ret);
- }
-
-sub do_shlib_rule
- {
- local($n,$def)=@_;
- local($ret,$nn);
- local($t);
-
- ($nn=$n) =~ tr/a-z/A-Z/;
- $ret.="$n.dll: \$(${nn}OBJ)\n";
- if ($vc && $w32)
- {
- $ret.="\t\$(MKSHLIB) $efile$n.dll $def @<<\n \$(${nn}OBJ_F)\n<<\n";
- }
- $ret.="\n";
- return($ret);
- }
-
-# do a rule for each file that says 'copy' to new direcory on change
-sub do_copy_rule
- {
- local($to,$files,$p)=@_;
- local($ret,$_,$n,$pp);
-
- $files =~ s/\//$o/g if $o ne '/';
- foreach (split(/\s+/,$files))
- {
- $n=&bname($_);
- if ($n =~ /bss_file/)
- { $pp=".c"; }
- else { $pp=$p; }
- $ret.="$to${o}$n$pp: \$(SRC_D)$o$_$pp\n\t\$(CP) \"\$(SRC_D)$o$_$pp\" \"$to${o}$n$pp\"\n\n";
- }
- return($ret);
- }
-
-sub read_options
- {
- # Many options are handled in a similar way. In particular
- # no-xxx sets zero or more scalars to 1.
- # Process these using a hash containing the option name and
- # reference to the scalars to set.
-
- my %valid_options = (
- "no-rc2" => \$no_rc2,
- "no-rc4" => \$no_rc4,
- "no-rc5" => \$no_rc5,
- "no-idea" => \$no_idea,
- "no-aes" => \$no_aes,
- "no-camellia" => \$no_camellia,
- "no-seed" => \$no_seed,
- "no-des" => \$no_des,
- "no-bf" => \$no_bf,
- "no-cast" => \$no_cast,
- "no-md2" => \$no_md2,
- "no-md4" => \$no_md4,
- "no-md5" => \$no_md5,
- "no-sha" => \$no_sha,
- "no-sha1" => \$no_sha1,
- "no-ripemd" => \$no_ripemd,
- "no-mdc2" => \$no_mdc2,
- "no-whirlpool" => \$no_whirlpool,
- "no-patents" =>
- [\$no_rc2, \$no_rc4, \$no_rc5, \$no_idea, \$no_rsa],
- "no-rsa" => \$no_rsa,
- "no-dsa" => \$no_dsa,
- "no-dh" => \$no_dh,
- "no-hmac" => \$no_hmac,
- "no-asm" => \$no_asm,
- "nasm" => \$nasm,
- "nw-nasm" => \$nw_nasm,
- "nw-mwasm" => \$nw_mwasm,
- "gaswin" => \$gaswin,
- "no-ssl2" => \$no_ssl2,
- "no-ssl3" => \$no_ssl3,
- "no-tlsext" => \$no_tlsext,
- "no-cms" => \$no_cms,
- "no-jpake" => \$no_jpake,
- "no-err" => \$no_err,
- "no-sock" => \$no_sock,
- "no-krb5" => \$no_krb5,
- "no-ec" => \$no_ec,
- "no-ecdsa" => \$no_ecdsa,
- "no-ecdh" => \$no_ecdh,
- "no-gost" => \$no_gost,
- "no-engine" => \$no_engine,
- "no-hw" => \$no_hw,
- "just-ssl" =>
- [\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
- \$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
- \$no_ssl2, \$no_err, \$no_ripemd, \$no_rc5,
- \$no_aes, \$no_camellia, \$no_seed],
- "rsaref" => 0,
- "gcc" => \$gcc,
- "debug" => \$debug,
- "profile" => \$profile,
- "shlib" => \$shlib,
- "dll" => \$shlib,
- "shared" => 0,
- "no-gmp" => 0,
- "no-rfc3779" => 0,
- "no-montasm" => 0,
- "no-shared" => 0,
- "no-store" => 0,
- "no-zlib" => 0,
- "no-zlib-dynamic" => 0,
- );
-
- if (exists $valid_options{$_})
- {
- my $r = $valid_options{$_};
- if ( ref $r eq "SCALAR")
- { $$r = 1;}
- elsif ( ref $r eq "ARRAY")
- {
- my $r2;
- foreach $r2 (@$r)
- {
- $$r2 = 1;
- }
- }
- }
- elsif (/^no-comp$/) { $xcflags = "-DOPENSSL_NO_COMP $xcflags"; }
- elsif (/^enable-zlib$/) { $zlib_opt = 1 if $zlib_opt == 0 }
- elsif (/^enable-zlib-dynamic$/)
- {
- $zlib_opt = 2;
- }
- elsif (/^no-static-engine/)
- {
- $no_static_engine = 1;
- }
- elsif (/^enable-static-engine/)
- {
- $no_static_engine = 0;
- }
- # There are also enable-xxx options which correspond to
- # the no-xxx. Since the scalars are enabled by default
- # these can be ignored.
- elsif (/^enable-/)
- {
- my $t = $_;
- $t =~ s/^enable/no/;
- if (exists $valid_options{$t})
- {return 1;}
- return 0;
- }
- # experimental-xxx is mostly like enable-xxx, but opensslconf.v
- # will still set OPENSSL_NO_xxx unless we set OPENSSL_EXPERIMENTAL_xxx.
- # (No need to fail if we don't know the algorithm -- this is for adventurous users only.)
- elsif (/^experimental-/)
- {
- my $algo, $ALGO;
- ($algo = $_) =~ s/^experimental-//;
- ($ALGO = $algo) =~ tr/[a-z]/[A-Z]/;
-
- $xcflags="-DOPENSSL_EXPERIMENTAL_$ALGO $xcflags";
-
- }
- elsif (/^--with-krb5-flavor=(.*)$/)
- {
- my $krb5_flavor = $1;
- if ($krb5_flavor =~ /^force-[Hh]eimdal$/)
- {
- $xcflags="-DKRB5_HEIMDAL $xcflags";
- }
- elsif ($krb5_flavor =~ /^MIT/i)
- {
- $xcflags="-DKRB5_MIT $xcflags";
- if ($krb5_flavor =~ /^MIT[._-]*1[._-]*[01]/i)
- {
- $xcflags="-DKRB5_MIT_OLD11 $xcflags"
- }
- }
- }
- elsif (/^([^=]*)=(.*)$/){ $VARS{$1}=$2; }
- elsif (/^-[lL].*$/) { $l_flags.="$_ "; }
- elsif ((!/^-help/) && (!/^-h/) && (!/^-\?/) && /^-.*$/)
- { $c_flags.="$_ "; }
- else { return(0); }
- return(1);
- }
+#!/usr/local/bin/perl
+# A bit of an evil hack but it post processes the file ../MINFO which
+# is generated by `make files` in the top directory.
+# This script outputs one mega makefile that has no shell stuff or any
+# funny stuff
+#
+
+$INSTALLTOP="/usr/local/ssl";
+$OPENSSLDIR="/usr/local/ssl";
+$OPTIONS="";
+$ssl_version="";
+$banner="\t\@echo Building OpenSSL";
+
+my $no_static_engine = 1;
+my $engines = "";
+my $otherlibs = "";
+local $zlib_opt = 0; # 0 = no zlib, 1 = static, 2 = dynamic
+local $zlib_lib = "";
+local $perl_asm = 0; # 1 to autobuild asm files from perl scripts
+
+# Options to import from top level Makefile
+
+my %mf_import = (
+ VERSION => \$ssl_version,
+ OPTIONS => \$OPTIONS,
+ INSTALLTOP => \$INSTALLTOP,
+ OPENSSLDIR => \$OPENSSLDIR,
+ PLATFORM => \$mf_platform,
+ CFLAG => \$mf_cflag,
+ DEPFLAG => \$mf_depflag,
+ CPUID_OBJ => \$mf_cpuid_asm,
+ BN_ASM => \$mf_bn_asm,
+ DES_ENC => \$mf_des_asm,
+ AES_ENC => \$mf_aes_asm,
+ BF_ENC => \$mf_bf_asm,
+ CAST_ENC => \$mf_cast_asm,
+ RC4_ENC => \$mf_rc4_asm,
+ RC5_ENC => \$mf_rc5_asm,
+ MD5_ASM_OBJ => \$mf_md5_asm,
+ SHA1_ASM_OBJ => \$mf_sha_asm,
+ RMD160_ASM_OBJ => \$mf_rmd_asm,
+ WP_ASM_OBJ => \$mf_wp_asm,
+ CMLL_ENC => \$mf_cm_asm
+);
+
+
+open(IN,"<Makefile") || die "unable to open Makefile!\n";
+while(<IN>) {
+ my ($mf_opt, $mf_ref);
+ while (($mf_opt, $mf_ref) = each %mf_import) {
+ if (/^$mf_opt\s*=\s*(.*)$/) {
+ $$mf_ref = $1;
+ }
+ }
+}
+close(IN);
+
+$debug = 1 if $mf_platform =~ /^debug-/;
+
+die "Makefile is not the toplevel Makefile!\n" if $ssl_version eq "";
+
+$infile="MINFO";
+
+%ops=(
+ "VC-WIN32", "Microsoft Visual C++ [4-6] - Windows NT or 9X",
+ "VC-WIN64I", "Microsoft C/C++ - Win64/IA-64",
+ "VC-WIN64A", "Microsoft C/C++ - Win64/x64",
+ "VC-CE", "Microsoft eMbedded Visual C++ 3.0 - Windows CE ONLY",
+ "VC-NT", "Microsoft Visual C++ [4-6] - Windows NT ONLY",
+ "Mingw32", "GNU C++ - Windows NT or 9x",
+ "Mingw32-files", "Create files with DOS copy ...",
+ "BC-NT", "Borland C++ 4.5 - Windows NT",
+ "linux-elf","Linux elf",
+ "ultrix-mips","DEC mips ultrix",
+ "FreeBSD","FreeBSD distribution",
+ "OS2-EMX", "EMX GCC OS/2",
+ "netware-clib", "CodeWarrior for NetWare - CLib - with WinSock Sockets",
+ "netware-clib-bsdsock", "CodeWarrior for NetWare - CLib - with BSD Sockets",
+ "netware-libc", "CodeWarrior for NetWare - LibC - with WinSock Sockets",
+ "netware-libc-bsdsock", "CodeWarrior for NetWare - LibC - with BSD Sockets",
+ "default","cc under unix",
+ "auto", "auto detect from top level Makefile"
+ );
+
+$platform="";
+my $xcflags="";
+foreach (@ARGV)
+ {
+ if (!&read_options && !defined($ops{$_}))
+ {
+ print STDERR "unknown option - $_\n";
+ print STDERR "usage: perl mk1mf.pl [options] [system]\n";
+ print STDERR "\nwhere [system] can be one of the following\n";
+ foreach $i (sort keys %ops)
+ { printf STDERR "\t%-10s\t%s\n",$i,$ops{$i}; }
+ print STDERR <<"EOF";
+and [options] can be one of
+ no-md2 no-md4 no-md5 no-sha no-mdc2 - Skip this digest
+ no-ripemd
+ no-rc2 no-rc4 no-rc5 no-idea no-des - Skip this symetric cipher
+ no-bf no-cast no-aes no-camellia no-seed
+ no-rsa no-dsa no-dh - Skip this public key cipher
+ no-ssl2 no-ssl3 - Skip this version of SSL
+ just-ssl - remove all non-ssl keys/digest
+ no-asm - No x86 asm
+ no-krb5 - No KRB5
+ no-ec - No EC
+ no-ecdsa - No ECDSA
+ no-ecdh - No ECDH
+ no-engine - No engine
+ no-hw - No hw
+ nasm - Use NASM for x86 asm
+ nw-nasm - Use NASM x86 asm for NetWare
+ nw-mwasm - Use Metrowerks x86 asm for NetWare
+ gaswin - Use GNU as with Mingw32
+ no-socks - No socket code
+ no-err - No error strings
+ dll/shlib - Build shared libraries (MS)
+ debug - Debug build
+ profile - Profiling build
+ gcc - Use Gcc (unix)
+
+Values that can be set
+TMP=tmpdir OUT=outdir SRC=srcdir BIN=binpath INC=header-outdir CC=C-compiler
+
+-L<ex_lib_path> -l<ex_lib> - extra library flags (unix)
+-<ex_cc_flags> - extra 'cc' flags,
+ added (MS), or replace (unix)
+EOF
+ exit(1);
+ }
+ $platform=$_;
+ }
+foreach (grep(!/^$/, split(/ /, $OPTIONS)))
+ {
+ print STDERR "unknown option - $_\n" if !&read_options;
+ }
+
+$no_static_engine = 0 if (!$shlib);
+
+$no_mdc2=1 if ($no_des);
+
+$no_ssl3=1 if ($no_md5 || $no_sha);
+$no_ssl3=1 if ($no_rsa && $no_dh);
+
+$no_ssl2=1 if ($no_md5);
+$no_ssl2=1 if ($no_rsa);
+
+$out_def="out";
+$inc_def="outinc";
+$tmp_def="tmp";
+
+$perl="perl" unless defined $perl;
+$mkdir="-mkdir" unless defined $mkdir;
+
+($ssl,$crypto)=("ssl","crypto");
+$ranlib="echo ranlib";
+
+$cc=(defined($VARS{'CC'}))?$VARS{'CC'}:'cc';
+$src_dir=(defined($VARS{'SRC'}))?$VARS{'SRC'}:'.';
+$bin_dir=(defined($VARS{'BIN'}))?$VARS{'BIN'}:'';
+
+# $bin_dir.=$o causes a core dump on my sparc :-(
+
+
+$NT=0;
+
+push(@INC,"util/pl","pl");
+
+if ($platform eq "auto") {
+ $platform = $mf_platform;
+ print STDERR "Imported platform $mf_platform\n";
+}
+
+if (($platform =~ /VC-(.+)/))
+ {
+ $FLAVOR=$1;
+ $NT = 1 if $1 eq "NT";
+ require 'VC-32.pl';
+ }
+elsif ($platform eq "Mingw32")
+ {
+ require 'Mingw32.pl';
+ }
+elsif ($platform eq "Mingw32-files")
+ {
+ require 'Mingw32f.pl';
+ }
+elsif ($platform eq "BC-NT")
+ {
+ $bc=1;
+ require 'BC-32.pl';
+ }
+elsif ($platform eq "FreeBSD")
+ {
+ require 'unix.pl';
+ $cflags='-DTERMIO -D_ANSI_SOURCE -O2 -fomit-frame-pointer';
+ }
+elsif ($platform eq "linux-elf")
+ {
+ require "unix.pl";
+ require "linux.pl";
+ $unix=1;
+ }
+elsif ($platform eq "ultrix-mips")
+ {
+ require "unix.pl";
+ require "ultrix.pl";
+ $unix=1;
+ }
+elsif ($platform eq "OS2-EMX")
+ {
+ $wc=1;
+ require 'OS2-EMX.pl';
+ }
+elsif (($platform eq "netware-clib") || ($platform eq "netware-libc") ||
+ ($platform eq "netware-clib-bsdsock") || ($platform eq "netware-libc-bsdsock"))
+ {
+ $LIBC=1 if $platform eq "netware-libc" || $platform eq "netware-libc-bsdsock";
+ $BSDSOCK=1 if ($platform eq "netware-libc-bsdsock") || ($platform eq "netware-clib-bsdsock");
+ require 'netware.pl';
+ }
+else
+ {
+ require "unix.pl";
+
+ $unix=1;
+ $cflags.=' -DTERMIO';
+ }
+
+$out_dir=(defined($VARS{'OUT'}))?$VARS{'OUT'}:$out_def.($debug?".dbg":"");
+$tmp_dir=(defined($VARS{'TMP'}))?$VARS{'TMP'}:$tmp_def.($debug?".dbg":"");
+$inc_dir=(defined($VARS{'INC'}))?$VARS{'INC'}:$inc_def;
+
+$bin_dir=$bin_dir.$o unless ((substr($bin_dir,-1,1) eq $o) || ($bin_dir eq ''));
+
+$cflags= "$xcflags$cflags" if $xcflags ne "";
+$cdflags= "$xcflags$cflags" if $xcdflags ne "";
+
+$cflags.=" -DOPENSSL_NO_IDEA" if $no_idea;
+$cdflags.=" -DOPENSSL_NO_IDEA" if $no_idea;
+$cflags.=" -DOPENSSL_NO_AES" if $no_aes;
+$cdflags.=" -DOPENSSL_NO_AES" if $no_aes;
+$cflags.=" -DOPENSSL_NO_CAMELLIA" if $no_camellia;
+$cdflags.=" -DOPENSSL_NO_CAMELLIA" if $no_camellia;
+$cflags.=" -DOPENSSL_NO_SEED" if $no_seed;
+$cdflags.=" -DOPENSSL_NO_SEED" if $no_seed;
+$cflags.=" -DOPENSSL_NO_RC2" if $no_rc2;
+$cdflags.=" -DOPENSSL_NO_RC2" if $no_rc2;
+$cflags.=" -DOPENSSL_NO_RC4" if $no_rc4;
+$cdflags.=" -DOPENSSL_NO_RC4" if $no_rc4;
+$cflags.=" -DOPENSSL_NO_RC5" if $no_rc5;
+$cdflags.=" -DOPENSSL_NO_RC5" if $no_rc5;
+$cflags.=" -DOPENSSL_NO_MD2" if $no_md2;
+$cdflags.=" -DOPENSSL_NO_MD2" if $no_md2;
+$cflags.=" -DOPENSSL_NO_MD4" if $no_md4;
+$cdflags.=" -DOPENSSL_NO_MD4" if $no_md4;
+$cflags.=" -DOPENSSL_NO_MD5" if $no_md5;
+$cdflags.=" -DOPENSSL_NO_MD5" if $no_md5;
+$cflags.=" -DOPENSSL_NO_SHA" if $no_sha;
+$cdflags.=" -DOPENSSL_NO_SHA" if $no_sha;
+$cflags.=" -DOPENSSL_NO_SHA1" if $no_sha1;
+$cdflags.=" -DOPENSSL_NO_SHA1" if $no_sha1;
+$cflags.=" -DOPENSSL_NO_RIPEMD" if $no_ripemd;
+$cdflags.=" -DOPENSSL_NO_RIPEMD" if $no_ripemd;
+$cflags.=" -DOPENSSL_NO_MDC2" if $no_mdc2;
+$cdflags.=" -DOPENSSL_NO_MDC2" if $no_mdc2;
+$cflags.=" -DOPENSSL_NO_BF" if $no_bf;
+$cdflags.=" -DOPENSSL_NO_BF" if $no_bf;
+$cflags.=" -DOPENSSL_NO_CAST" if $no_cast;
+$cdflags.=" -DOPENSSL_NO_CAST" if $no_cast;
+$cflags.=" -DOPENSSL_NO_DES" if $no_des;
+$cdflags.=" -DOPENSSL_NO_DES" if $no_des;
+$cflags.=" -DOPENSSL_NO_RSA" if $no_rsa;
+$cdflags.=" -DOPENSSL_NO_RSA" if $no_rsa;
+$cflags.=" -DOPENSSL_NO_DSA" if $no_dsa;
+$cdflags.=" -DOPENSSL_NO_DSA" if $no_dsa;
+$cflags.=" -DOPENSSL_NO_DH" if $no_dh;
+$cdflags.=" -DOPENSSL_NO_DH" if $no_dh;
+$cflags.=" -DOPENSSL_NO_WHIRLPOOL" if $no_whirlpool;
+$cdflags.=" -DOPENSSL_NO_WHIRLPOOL" if $no_whirlpool;
+$cflags.=" -DOPENSSL_NO_SOCK" if $no_sock;
+$cdflags.=" -DOPENSSL_NO_SOCK" if $no_sock;
+$cflags.=" -DOPENSSL_NO_SSL2" if $no_ssl2;
+$cdflags.=" -DOPENSSL_NO_SSL2" if $no_ssl2;
+$cflags.=" -DOPENSSL_NO_SSL3" if $no_ssl3;
+$cdflags.=" -DOPENSSL_NO_SSL3" if $no_ssl3;
+$cflags.=" -DOPENSSL_NO_TLSEXT" if $no_tlsext;
+$cdflags.=" -DOPENSSL_NO_TLSEXT" if $no_tlsext;
+$cflags.=" -DOPENSSL_NO_CMS" if $no_cms;
+$cdflags.=" -DOPENSSL_NO_CMS" if $no_cms;
+$cflags.=" -DOPENSSL_NO_ERR" if $no_err;
+$cdflags.=" -DOPENSSL_NO_ERR" if $no_err;
+$cflags.=" -DOPENSSL_NO_KRB5" if $no_krb5;
+$cdflags.=" -DOPENSSL_NO_KRB5" if $no_krb5;
+$cflags.=" -DOPENSSL_NO_EC" if $no_ec;
+$cdflags.=" -DOPENSSL_NO_EC" if $no_ec;
+$cflags.=" -DOPENSSL_NO_ECDSA" if $no_ecdsa;
+$cdflags.=" -DOPENSSL_NO_ECDSA" if $no_ecdsa;
+$cflags.=" -DOPENSSL_NO_ECDH" if $no_ecdh;
+$cdflags.=" -DOPENSSL_NO_ECDH" if $no_ecdh;
+$cflags.=" -DOPENSSL_NO_GOST" if $no_gost;
+$cdflags.=" -DOPENSSL_NO_GOST" if $no_gost;
+$cflags.=" -DOPENSSL_NO_ENGINE" if $no_engine;
+$cdflags.=" -DOPENSSL_NO_ENGINE" if $no_engine;
+$cflags.=" -DOPENSSL_NO_HW" if $no_hw;
+$cdflags.=" -DOPENSSL_NO_HW" if $no_hw;
+$cflags.=" -DOPENSSL_NO_JPAKE" if $no_jpake;
+$cdflags.=" -DOPENSSL_NO_JPAKE" if $no_jpake;
+$cflags.= " -DZLIB" if $zlib_opt;
+$cdflags.= " -DZLIB" if $zlib_opt;
+$cflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
+$cdflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
+
+if ($no_static_engine)
+ {
+ $cflags .= " -DOPENSSL_NO_STATIC_ENGINE";
+ $cdflags .= " -DOPENSSL_NO_STATIC_ENGINE";
+ }
+else
+ {
+ $cflags .= " -DOPENSSL_NO_DYNAMIC_ENGINE";
+ $cdflags .= " -DOPENSSL_NO_DYNAMIC_ENGINE";
+ }
+
+#$cflags.=" -DRSAref" if $rsaref ne "";
+
+## if ($unix)
+## { $cflags="$c_flags" if ($c_flags ne ""); }
+##else
+ { $cflags="$c_flags$cflags" if ($c_flags ne ""); }
+
+$ex_libs="$l_flags$ex_libs" if ($l_flags ne "");
+
+
+%shlib_ex_cflags=("SSL" => " -DOPENSSL_BUILD_SHLIBSSL",
+ "CRYPTO" => " -DOPENSSL_BUILD_SHLIBCRYPTO");
+
+if ($msdos)
+ {
+ $banner ="\t\@echo Make sure you have run 'perl Configure $platform' in the\n";
+ $banner.="\t\@echo top level directory, if you don't have perl, you will\n";
+ $banner.="\t\@echo need to probably edit crypto/bn/bn.h, check the\n";
+ $banner.="\t\@echo documentation for details.\n";
+ }
+
+# have to do this to allow $(CC) under unix
+$link="$bin_dir$link" if ($link !~ /^\$/);
+
+$INSTALLTOP =~ s|/|$o|g;
+$OPENSSLDIR =~ s|/|$o|g;
+
+#############################################
+# We parse in input file and 'store' info for later printing.
+open(IN,"<$infile") || die "unable to open $infile:$!\n";
+$_=<IN>;
+for (;;)
+ {
+ chop;
+
+ ($key,$val)=/^([^=]+)=(.*)/;
+ if ($key eq "RELATIVE_DIRECTORY")
+ {
+ if ($lib ne "")
+ {
+ $uc=$lib;
+ $uc =~ s/^lib(.*)\.a/$1/;
+ $uc =~ tr/a-z/A-Z/;
+ $lib_nam{$uc}=$uc;
+ $lib_obj{$uc}.=$libobj." ";
+ }
+ last if ($val eq "FINISHED");
+ $lib="";
+ $libobj="";
+ $dir=$val;
+ }
+
+ if ($key eq "KRB5_INCLUDES")
+ { $cflags .= " $val";}
+
+ if ($key eq "ZLIB_INCLUDE")
+ { $cflags .= " $val" if $val ne "";}
+
+ if ($key eq "LIBZLIB")
+ { $zlib_lib = "$val" if $val ne "";}
+
+ if ($key eq "LIBKRB5")
+ { $ex_libs .= " $val" if $val ne "";}
+
+ if ($key eq "TEST")
+ { $test.=&var_add($dir,$val, 0); }
+
+ if (($key eq "PROGS") || ($key eq "E_OBJ"))
+ { $e_exe.=&var_add($dir,$val, 0); }
+
+ if ($key eq "LIB")
+ {
+ $lib=$val;
+ $lib =~ s/^.*\/([^\/]+)$/$1/;
+ }
+ if ($key eq "LIBNAME" && $no_static_engine)
+ {
+ $lib=$val;
+ $lib =~ s/^.*\/([^\/]+)$/$1/;
+ $otherlibs .= " $lib";
+ }
+
+ if ($key eq "EXHEADER")
+ { $exheader.=&var_add($dir,$val, 1); }
+
+ if ($key eq "HEADER")
+ { $header.=&var_add($dir,$val, 1); }
+
+ if ($key eq "LIBOBJ" && ($dir ne "engines" || !$no_static_engine))
+ { $libobj=&var_add($dir,$val, 0); }
+ if ($key eq "LIBNAMES" && $dir eq "engines" && $no_static_engine)
+ { $engines.=$val }
+
+ if (!($_=<IN>))
+ { $_="RELATIVE_DIRECTORY=FINISHED\n"; }
+ }
+close(IN);
+
+if ($shlib)
+ {
+ $extra_install= <<"EOF";
+ \$(CP) \"\$(O_SSL)\" \"\$(INSTALLTOP)${o}bin\"
+ \$(CP) \"\$(O_CRYPTO)\" \"\$(INSTALLTOP)${o}bin\"
+ \$(CP) \"\$(L_SSL)\" \"\$(INSTALLTOP)${o}lib\"
+ \$(CP) \"\$(L_CRYPTO)\" \"\$(INSTALLTOP)${o}lib\"
+EOF
+ if ($no_static_engine)
+ {
+ $extra_install .= <<"EOF"
+ \$(MKDIR) \"\$(INSTALLTOP)${o}lib${o}engines\"
+ \$(CP) \"\$(E_SHLIB)\" \"\$(INSTALLTOP)${o}lib${o}engines\"
+EOF
+ }
+ }
+else
+ {
+ $extra_install= <<"EOF";
+ \$(CP) \"\$(O_SSL)\" \"\$(INSTALLTOP)${o}lib\"
+ \$(CP) \"\$(O_CRYPTO)\" \"\$(INSTALLTOP)${o}lib\"
+EOF
+ $ex_libs .= " $zlib_lib" if $zlib_opt == 1;
+ }
+
+$defs= <<"EOF";
+# This makefile has been automatically generated from the OpenSSL distribution.
+# This single makefile will build the complete OpenSSL distribution and
+# by default leave the 'intertesting' output files in .${o}out and the stuff
+# that needs deleting in .${o}tmp.
+# The file was generated by running 'make makefile.one', which
+# does a 'make files', which writes all the environment variables from all
+# the makefiles to the file call MINFO. This file is used by
+# util${o}mk1mf.pl to generate makefile.one.
+# The 'makefile per directory' system suites me when developing this
+# library and also so I can 'distribute' indervidual library sections.
+# The one monster makefile better suits building in non-unix
+# environments.
+
+EOF
+
+$defs .= $preamble if defined $preamble;
+
+$defs.= <<"EOF";
+INSTALLTOP=$INSTALLTOP
+OPENSSLDIR=$OPENSSLDIR
+
+!ifdef DEBUG
+# The output directory for everything intersting
+OUT_D=out32_d
+# The output directory for all the temporary muck
+TMP_D=tmp32_d
+!else
+# The output directory for everything intersting
+OUT_D=out32
+# The output directory for all the temporary muck
+TMP_D=tmp32
+!endif
+
+# Set your compiler options
+PLATFORM=$platform
+CC=$bin_dir${cc}
+!ifdef DEBUG
+CFLAG=$cdflags
+!else
+CFLAG=$cflags
+!endif
+APP_CFLAG=$app_cflag
+LIB_CFLAG=$lib_cflag
+SHLIB_CFLAG=$shl_cflag
+APP_EX_OBJ=$app_ex_obj
+SHLIB_EX_OBJ=$shlib_ex_obj
+# add extra libraries to this define, for solaris -lsocket -lnsl would
+# be added
+EX_LIBS=$ex_libs
+
+# The OpenSSL directory
+SRC_D=$src_dir
+
+LINK=$link
+!ifdef DEBUG
+LFLAGS=$lflagsd
+!else
+LFLAGS=$lflags
+!endif
+RSC=$rsc
+
+# The output directory for the header files
+INC_D=$inc_dir
+INCO_D=$inc_dir${o}openssl
+
+PERL=$perl
+CP=$cp
+RM=$rm
+RANLIB=$ranlib
+MKDIR=$mkdir
+!ifdef DEBUG
+MKLIB=$bin_dir$mklibd
+!else
+MKLIB=$bin_dir$mklib
+!endif
+MLFLAGS=$mlflags
+ASM=$bin_dir$asm
+
+######################################################
+# You should not need to touch anything below this point
+######################################################
+
+E_EXE=openssl
+SSL=$ssl
+CRYPTO=$crypto
+
+# BIN_D - Binary output directory
+# TEST_D - Binary test file output directory
+# LIB_D - library output directory
+# ENG_D - dynamic engine output directory
+# Note: if you change these point to different directories then uncomment out
+# the lines around the 'NB' comment below.
+#
+BIN_D=\$(OUT_D)
+TEST_D=\$(OUT_D)
+LIB_D=\$(OUT_D)
+ENG_D=\$(OUT_D)
+
+# INCL_D - local library directory
+# OBJ_D - temp object file directory
+OBJ_D=\$(TMP_D)
+INCL_D=\$(TMP_D)
+
+O_SSL= \$(LIB_D)$o$plib\$(SSL)$shlibp
+O_CRYPTO= \$(LIB_D)$o$plib\$(CRYPTO)$shlibp
+SO_SSL= $plib\$(SSL)$so_shlibp
+SO_CRYPTO= $plib\$(CRYPTO)$so_shlibp
+L_SSL= \$(LIB_D)$o$plib\$(SSL)$libp
+L_CRYPTO= \$(LIB_D)$o$plib\$(CRYPTO)$libp
+
+L_LIBS= \$(L_SSL) \$(L_CRYPTO)
+
+######################################################
+# Don't touch anything below this point
+######################################################
+
+INC=-I\$(INC_D) -I\$(INCL_D)
+APP_CFLAGS=\$(INC) \$(CFLAG) \$(APP_CFLAG)
+LIB_CFLAGS=\$(INC) \$(CFLAG) \$(LIB_CFLAG)
+SHLIB_CFLAGS=\$(INC) \$(CFLAG) \$(LIB_CFLAG) \$(SHLIB_CFLAG)
+LIBS_DEP=\$(O_CRYPTO) \$(O_SSL)
+
+#############################################
+EOF
+
+$rules=<<"EOF";
+all: banner \$(TMP_D) \$(BIN_D) \$(TEST_D) \$(LIB_D) \$(INCO_D) headers lib exe
+
+banner:
+$banner
+
+\$(TMP_D):
+ \$(MKDIR) \"\$(TMP_D)\"
+# NB: uncomment out these lines if BIN_D, TEST_D and LIB_D are different
+#\$(BIN_D):
+# \$(MKDIR) \$(BIN_D)
+#
+#\$(TEST_D):
+# \$(MKDIR) \$(TEST_D)
+
+\$(LIB_D):
+ \$(MKDIR) \"\$(LIB_D)\"
+
+\$(INCO_D): \$(INC_D)
+ \$(MKDIR) \"\$(INCO_D)\"
+
+\$(INC_D):
+ \$(MKDIR) \"\$(INC_D)\"
+
+headers: \$(HEADER) \$(EXHEADER)
+ @
+
+lib: \$(LIBS_DEP) \$(E_SHLIB)
+
+exe: \$(T_EXE) \$(BIN_D)$o\$(E_EXE)$exep
+
+install: all
+ \$(MKDIR) \"\$(INSTALLTOP)\"
+ \$(MKDIR) \"\$(INSTALLTOP)${o}bin\"
+ \$(MKDIR) \"\$(INSTALLTOP)${o}include\"
+ \$(MKDIR) \"\$(INSTALLTOP)${o}include${o}openssl\"
+ \$(MKDIR) \"\$(INSTALLTOP)${o}lib\"
+ \$(CP) \"\$(INCO_D)${o}*.\[ch\]\" \"\$(INSTALLTOP)${o}include${o}openssl\"
+ \$(CP) \"\$(BIN_D)$o\$(E_EXE)$exep \$(INSTALLTOP)${o}bin\"
+ \$(MKDIR) \"\$(OPENSSLDIR)\"
+ \$(CP) apps${o}openssl.cnf \"\$(OPENSSLDIR)\"
+$extra_install
+
+
+test: \$(T_EXE)
+ cd \$(BIN_D)
+ ..${o}ms${o}test
+
+clean:
+ \$(RM) \$(TMP_D)$o*.*
+
+vclean:
+ \$(RM) \$(TMP_D)$o*.*
+ \$(RM) \$(OUT_D)$o*.*
+
+EOF
+
+my $platform_cpp_symbol = "MK1MF_PLATFORM_$platform";
+$platform_cpp_symbol =~ s/-/_/g;
+if (open(IN,"crypto/buildinf.h"))
+ {
+ # Remove entry for this platform in existing file buildinf.h.
+
+ my $old_buildinf_h = "";
+ while (<IN>)
+ {
+ if (/^\#ifdef $platform_cpp_symbol$/)
+ {
+ while (<IN>) { last if (/^\#endif/); }
+ }
+ else
+ {
+ $old_buildinf_h .= $_;
+ }
+ }
+ close(IN);
+
+ open(OUT,">crypto/buildinf.h") || die "Can't open buildinf.h";
+ print OUT $old_buildinf_h;
+ close(OUT);
+ }
+
+open (OUT,">>crypto/buildinf.h") || die "Can't open buildinf.h";
+printf OUT <<EOF;
+#ifdef $platform_cpp_symbol
+ /* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
+ #define CFLAGS "$cc $cflags"
+ #define PLATFORM "$platform"
+EOF
+printf OUT " #define DATE \"%s\"\n", scalar gmtime();
+printf OUT "#endif\n";
+close(OUT);
+
+# Strip of trailing ' '
+foreach (keys %lib_obj) { $lib_obj{$_}=&clean_up_ws($lib_obj{$_}); }
+$test=&clean_up_ws($test);
+$e_exe=&clean_up_ws($e_exe);
+$exheader=&clean_up_ws($exheader);
+$header=&clean_up_ws($header);
+
+# First we strip the exheaders from the headers list
+foreach (split(/\s+/,$exheader)){ $h{$_}=1; }
+foreach (split(/\s+/,$header)) { $h.=$_." " unless $h{$_}; }
+chop($h); $header=$h;
+
+$defs.=&do_defs("HEADER",$header,"\$(INCL_D)","");
+$rules.=&do_copy_rule("\$(INCL_D)",$header,"");
+
+$defs.=&do_defs("EXHEADER",$exheader,"\$(INCO_D)","");
+$rules.=&do_copy_rule("\$(INCO_D)",$exheader,"");
+
+$defs.=&do_defs("T_OBJ",$test,"\$(OBJ_D)",$obj);
+$rules.=&do_compile_rule("\$(OBJ_D)",$test,"\$(APP_CFLAGS)");
+
+$defs.=&do_defs("E_OBJ",$e_exe,"\$(OBJ_D)",$obj);
+$rules.=&do_compile_rule("\$(OBJ_D)",$e_exe,'-DMONOLITH $(APP_CFLAGS)');
+
+foreach (values %lib_nam)
+ {
+ $lib_obj=$lib_obj{$_};
+ local($slib)=$shlib;
+
+ if (($_ eq "SSL") && $no_ssl2 && $no_ssl3)
+ {
+ $rules.="\$(O_SSL):\n\n";
+ next;
+ }
+
+ $defs.=&do_defs(${_}."OBJ",$lib_obj,"\$(OBJ_D)",$obj);
+ $lib=($slib)?" \$(SHLIB_CFLAGS)".$shlib_ex_cflags{$_}:" \$(LIB_CFLAGS)";
+ $rules.=&do_compile_rule("\$(OBJ_D)",$lib_obj{$_},$lib);
+ }
+
+# hack to add version info on MSVC
+if (($platform eq "VC-WIN32") || ($platform eq "VC-WIN64A")
+ || ($platform eq "VC-WIN64I") || ($platform eq "VC-NT")) {
+ $rules.= <<"EOF";
+\$(OBJ_D)\\\$(CRYPTO).res: ms\\version32.rc
+ \$(RSC) /fo"\$(OBJ_D)\\\$(CRYPTO).res" /d CRYPTO ms\\version32.rc
+
+\$(OBJ_D)\\\$(SSL).res: ms\\version32.rc
+ \$(RSC) /fo"\$(OBJ_D)\\\$(SSL).res" /d SSL ms\\version32.rc
+
+EOF
+}
+
+$defs.=&do_defs("T_EXE",$test,"\$(TEST_D)",$exep);
+foreach (split(/\s+/,$test))
+ {
+ $t=&bname($_);
+ $tt="\$(OBJ_D)${o}$t${obj}";
+ $rules.=&do_link_rule("\$(TEST_D)$o$t$exep",$tt,"\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)");
+ }
+
+$defs.=&do_defs("E_SHLIB",$engines . $otherlibs,"\$(ENG_D)",$shlibp);
+
+foreach (split(/\s+/,$engines))
+ {
+ $rules.=&do_compile_rule("\$(OBJ_D)","engines${o}e_$_",$lib);
+ $rules.= &do_lib_rule("\$(OBJ_D)${o}e_${_}.obj","\$(ENG_D)$o$_$shlibp","",$shlib,"");
+ }
+
+
+
+$rules.= &do_lib_rule("\$(SSLOBJ)","\$(O_SSL)",$ssl,$shlib,"\$(SO_SSL)");
+$rules.= &do_lib_rule("\$(CRYPTOOBJ)","\$(O_CRYPTO)",$crypto,$shlib,"\$(SO_CRYPTO)");
+
+foreach (split(" ",$otherlibs))
+ {
+ my $uc = $_;
+ $uc =~ tr /a-z/A-Z/;
+ $rules.= &do_lib_rule("\$(${uc}OBJ)","\$(ENG_D)$o$_$shlibp", "", $shlib, "");
+
+ }
+
+$rules.=&do_link_rule("\$(BIN_D)$o\$(E_EXE)$exep","\$(E_OBJ)","\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)");
+
+print $defs;
+
+if ($platform eq "linux-elf") {
+ print <<"EOF";
+# Generate perlasm output files
+%.cpp:
+ (cd \$(\@D)/..; PERL=perl make -f Makefile asm/\$(\@F))
+EOF
+}
+print "###################################################################\n";
+print $rules;
+
+###############################################
+# strip off any trailing .[och] and append the relative directory
+# also remembering to do nothing if we are in one of the dropped
+# directories
+sub var_add
+ {
+ local($dir,$val,$keepext)=@_;
+ local(@a,$_,$ret);
+
+ return("") if $no_engine && $dir =~ /\/engine/;
+ return("") if $no_hw && $dir =~ /\/hw/;
+ return("") if $no_idea && $dir =~ /\/idea/;
+ return("") if $no_aes && $dir =~ /\/aes/;
+ return("") if $no_camellia && $dir =~ /\/camellia/;
+ return("") if $no_seed && $dir =~ /\/seed/;
+ return("") if $no_rc2 && $dir =~ /\/rc2/;
+ return("") if $no_rc4 && $dir =~ /\/rc4/;
+ return("") if $no_rc5 && $dir =~ /\/rc5/;
+ return("") if $no_rsa && $dir =~ /\/rsa/;
+ return("") if $no_rsa && $dir =~ /^rsaref/;
+ return("") if $no_dsa && $dir =~ /\/dsa/;
+ return("") if $no_dh && $dir =~ /\/dh/;
+ return("") if $no_ec && $dir =~ /\/ec/;
+ return("") if $no_gost && $dir =~ /\/ccgost/;
+ return("") if $no_cms && $dir =~ /\/cms/;
+ return("") if $no_jpake && $dir =~ /\/jpake/;
+ if ($no_des && $dir =~ /\/des/)
+ {
+ if ($val =~ /read_pwd/)
+ { return("$dir/read_pwd "); }
+ else
+ { return(""); }
+ }
+ return("") if $no_mdc2 && $dir =~ /\/mdc2/;
+ return("") if $no_sock && $dir =~ /\/proxy/;
+ return("") if $no_bf && $dir =~ /\/bf/;
+ return("") if $no_cast && $dir =~ /\/cast/;
+ return("") if $no_whirlpool && $dir =~ /\/whrlpool/;
+
+ $val =~ s/^\s*(.*)\s*$/$1/;
+ @a=split(/\s+/,$val);
+ grep(s/\.[och]$//,@a) unless $keepext;
+
+ @a=grep(!/^e_.*_3d$/,@a) if $no_des;
+ @a=grep(!/^e_.*_d$/,@a) if $no_des;
+ @a=grep(!/^e_.*_ae$/,@a) if $no_idea;
+ @a=grep(!/^e_.*_i$/,@a) if $no_aes;
+ @a=grep(!/^e_.*_r2$/,@a) if $no_rc2;
+ @a=grep(!/^e_.*_r5$/,@a) if $no_rc5;
+ @a=grep(!/^e_.*_bf$/,@a) if $no_bf;
+ @a=grep(!/^e_.*_c$/,@a) if $no_cast;
+ @a=grep(!/^e_rc4$/,@a) if $no_rc4;
+ @a=grep(!/^e_camellia$/,@a) if $no_camellia;
+ @a=grep(!/^e_seed$/,@a) if $no_seed;
+
+ #@a=grep(!/(^s2_)|(^s23_)/,@a) if $no_ssl2;
+ #@a=grep(!/(^s3_)|(^s23_)/,@a) if $no_ssl3;
+
+ @a=grep(!/(_sock$)|(_acpt$)|(_conn$)|(^pxy_)/,@a) if $no_sock;
+
+ @a=grep(!/(^md2)|(_md2$)/,@a) if $no_md2;
+ @a=grep(!/(^md4)|(_md4$)/,@a) if $no_md4;
+ @a=grep(!/(^md5)|(_md5$)/,@a) if $no_md5;
+ @a=grep(!/(rmd)|(ripemd)/,@a) if $no_ripemd;
+
+ @a=grep(!/(^d2i_r_)|(^i2d_r_)/,@a) if $no_rsa;
+ @a=grep(!/(^p_open$)|(^p_seal$)/,@a) if $no_rsa;
+ @a=grep(!/(^pem_seal$)/,@a) if $no_rsa;
+
+ @a=grep(!/(m_dss$)|(m_dss1$)/,@a) if $no_dsa;
+ @a=grep(!/(^d2i_s_)|(^i2d_s_)|(_dsap$)/,@a) if $no_dsa;
+
+ @a=grep(!/^n_pkey$/,@a) if $no_rsa || $no_rc4;
+
+ @a=grep(!/_dhp$/,@a) if $no_dh;
+
+ @a=grep(!/(^sha[^1])|(_sha$)|(m_dss$)/,@a) if $no_sha;
+ @a=grep(!/(^sha1)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
+ @a=grep(!/_mdc2$/,@a) if $no_mdc2;
+
+ @a=grep(!/^engine$/,@a) if $no_engine;
+ @a=grep(!/^hw$/,@a) if $no_hw;
+ @a=grep(!/(^rsa$)|(^genrsa$)/,@a) if $no_rsa;
+ @a=grep(!/(^dsa$)|(^gendsa$)|(^dsaparam$)/,@a) if $no_dsa;
+ @a=grep(!/^gendsa$/,@a) if $no_sha1;
+ @a=grep(!/(^dh$)|(^gendh$)/,@a) if $no_dh;
+
+ @a=grep(!/(^dh)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
+
+ grep($_="$dir/$_",@a);
+ @a=grep(!/(^|\/)s_/,@a) if $no_sock;
+ @a=grep(!/(^|\/)bio_sock/,@a) if $no_sock;
+ $ret=join(' ',@a)." ";
+ return($ret);
+ }
+
+# change things so that each 'token' is only separated by one space
+sub clean_up_ws
+ {
+ local($w)=@_;
+
+ $w =~ s/^\s*(.*)\s*$/$1/;
+ $w =~ s/\s+/ /g;
+ return($w);
+ }
+
+sub do_defs
+ {
+ local($var,$files,$location,$postfix)=@_;
+ local($_,$ret,$pf);
+ local(*OUT,$tmp,$t);
+
+ $files =~ s/\//$o/g if $o ne '/';
+ $ret="$var=";
+ $n=1;
+ $Vars{$var}.="";
+ foreach (split(/ /,$files))
+ {
+ $orig=$_;
+ $_=&bname($_) unless /^\$/;
+ if ($n++ == 2)
+ {
+ $n=0;
+ $ret.="\\\n\t";
+ }
+ if (($_ =~ /bss_file/) && ($postfix eq ".h"))
+ { $pf=".c"; }
+ else { $pf=$postfix; }
+ if ($_ =~ /BN_ASM/) { $t="$_ "; }
+ elsif ($_ =~ /BNCO_ASM/){ $t="$_ "; }
+ elsif ($_ =~ /AES_ASM/){ $t="$_ "; }
+ elsif ($_ =~ /DES_ENC/) { $t="$_ "; }
+ elsif ($_ =~ /BF_ENC/) { $t="$_ "; }
+ elsif ($_ =~ /CAST_ENC/){ $t="$_ "; }
+ elsif ($_ =~ /RC4_ENC/) { $t="$_ "; }
+ elsif ($_ =~ /RC5_ENC/) { $t="$_ "; }
+ elsif ($_ =~ /MD5_ASM/) { $t="$_ "; }
+ elsif ($_ =~ /SHA1_ASM/){ $t="$_ "; }
+ elsif ($_ =~ /RMD160_ASM/){ $t="$_ "; }
+ elsif ($_ =~ /WHIRLPOOL_ASM/){ $t="$_ "; }
+ elsif ($_ =~ /CPUID_ASM/){ $t="$_ "; }
+ else { $t="$location${o}$_$pf "; }
+
+ $Vars{$var}.="$t ";
+ $ret.=$t;
+ }
+ # hack to add version info on MSVC
+ if ($shlib && (($platform eq "VC-WIN32") || ($platfrom eq "VC-WIN64I") || ($platform eq "VC-WIN64A") || ($platform eq "VC-NT")))
+ {
+ if ($var eq "CRYPTOOBJ")
+ { $ret.="\$(OBJ_D)\\\$(CRYPTO).res "; }
+ elsif ($var eq "SSLOBJ")
+ { $ret.="\$(OBJ_D)\\\$(SSL).res "; }
+ }
+ chomp($ret);
+ $ret.="\n\n";
+ return($ret);
+ }
+
+# return the name with the leading path removed
+sub bname
+ {
+ local($ret)=@_;
+ $ret =~ s/^.*[\\\/]([^\\\/]+)$/$1/;
+ return($ret);
+ }
+
+# return the leading path
+sub dname
+ {
+ my $ret=shift;
+ $ret =~ s/(^.*)[\\\/][^\\\/]+$/$1/;
+ return($ret);
+ }
+
+##############################################################
+# do a rule for each file that says 'compile' to new direcory
+# compile the files in '$files' into $to
+sub do_compile_rule
+ {
+ local($to,$files,$ex)=@_;
+ local($ret,$_,$n,$d,$s);
+
+ $files =~ s/\//$o/g if $o ne '/';
+ foreach (split(/\s+/,$files))
+ {
+ $n=&bname($_);
+ $d=&dname($_);
+ if (-f "${_}.c")
+ {
+ $ret.=&cc_compile_target("$to${o}$n$obj","${_}.c",$ex)
+ }
+ elsif (-f ($s="${d}${o}asm${o}${n}.pl") or
+ ($s=~s/sha256/sha512/ and -f $s) or
+ -f ($s="${d}${o}${n}.pl"))
+ {
+ $ret.=&perlasm_compile_target("$to${o}$n$obj",$s,$n);
+ }
+ elsif (-f ($s="${d}${o}asm${o}${n}.S") or
+ -f ($s="${d}${o}${n}.S"))
+ {
+ $ret.=&Sasm_compile_target("$to${o}$n$obj",$s,$n);
+ }
+ else { die "no rule for $_"; }
+ }
+ return($ret);
+ }
+
+##############################################################
+# do a rule for each file that says 'compile' to new direcory
+sub perlasm_compile_target
+ {
+ my($target,$source,$bname)=@_;
+ my($ret);
+
+ $bname =~ s/(.*)\.[^\.]$/$1/;
+ $ret ="\$(TMP_D)$o$bname.asm: $source\n";
+ $ret.="\t\$(PERL) $source $asmtype \$(CFLAG) >\$\@\n\n";
+ $ret.="$target: \$(TMP_D)$o$bname.asm\n";
+ $ret.="\t\$(ASM) $afile\$\@ \$(TMP_D)$o$bname.asm\n\n";
+ return($ret);
+ }
+
+sub Sasm_compile_target
+ {
+ my($target,$source,$bname)=@_;
+ my($ret);
+
+ $bname =~ s/(.*)\.[^\.]$/$1/;
+ $ret ="\$(TMP_D)$o$bname.asm: $source\n";
+ $ret.="\t\$(CC) -E \$(CFLAG) $source >\$\@\n\n";
+ $ret.="$target: \$(TMP_D)$o$bname.asm\n";
+ $ret.="\t\$(ASM) $afile\$\@ \$(TMP_D)$o$bname.asm\n\n";
+ return($ret);
+ }
+
+sub cc_compile_target
+ {
+ local($target,$source,$ex_flags)=@_;
+ local($ret);
+
+ $ex_flags.=" -DMK1MF_BUILD -D$platform_cpp_symbol" if ($source =~ /cversion/);
+ $target =~ s/\//$o/g if $o ne "/";
+ $source =~ s/\//$o/g if $o ne "/";
+ $ret ="$target: \$(SRC_D)$o$source\n\t";
+ $ret.="\$(CC) ${ofile}$target $ex_flags -c \$(SRC_D)$o$source\n\n";
+ return($ret);
+ }
+
+##############################################################
+sub do_asm_rule
+ {
+ local($target,$src)=@_;
+ local($ret,@s,@t,$i);
+
+ $target =~ s/\//$o/g if $o ne "/";
+ $src =~ s/\//$o/g if $o ne "/";
+
+ @t=split(/\s+/,$target);
+ @s=split(/\s+/,$src);
+
+
+ for ($i=0; $i<=$#s; $i++)
+ {
+ my $objfile = $t[$i];
+ my $srcfile = $s[$i];
+
+ if ($perl_asm == 1)
+ {
+ my $plasm = $objfile;
+ $plasm =~ s/${obj}/.pl/;
+ $ret.="$srcfile: $plasm\n";
+ $ret.="\t\$(PERL) $plasm $asmtype \$(CFLAG) >$srcfile\n\n";
+ }
+
+ $ret.="$objfile: $srcfile\n";
+ $ret.="\t\$(ASM) $afile$objfile \$(SRC_D)$o$srcfile\n\n";
+ }
+ return($ret);
+ }
+
+sub do_shlib_rule
+ {
+ local($n,$def)=@_;
+ local($ret,$nn);
+ local($t);
+
+ ($nn=$n) =~ tr/a-z/A-Z/;
+ $ret.="$n.dll: \$(${nn}OBJ)\n";
+ if ($vc && $w32)
+ {
+ $ret.="\t\$(MKSHLIB) $efile$n.dll $def @<<\n \$(${nn}OBJ_F)\n<<\n";
+ }
+ $ret.="\n";
+ return($ret);
+ }
+
+# do a rule for each file that says 'copy' to new direcory on change
+sub do_copy_rule
+ {
+ local($to,$files,$p)=@_;
+ local($ret,$_,$n,$pp);
+
+ $files =~ s/\//$o/g if $o ne '/';
+ foreach (split(/\s+/,$files))
+ {
+ $n=&bname($_);
+ if ($n =~ /bss_file/)
+ { $pp=".c"; }
+ else { $pp=$p; }
+ $ret.="$to${o}$n$pp: \$(SRC_D)$o$_$pp\n\t\$(CP) \"\$(SRC_D)$o$_$pp\" \"$to${o}$n$pp\"\n\n";
+ }
+ return($ret);
+ }
+
+sub read_options
+ {
+ # Many options are handled in a similar way. In particular
+ # no-xxx sets zero or more scalars to 1.
+ # Process these using a hash containing the option name and
+ # reference to the scalars to set.
+
+ my %valid_options = (
+ "no-rc2" => \$no_rc2,
+ "no-rc4" => \$no_rc4,
+ "no-rc5" => \$no_rc5,
+ "no-idea" => \$no_idea,
+ "no-aes" => \$no_aes,
+ "no-camellia" => \$no_camellia,
+ "no-seed" => \$no_seed,
+ "no-des" => \$no_des,
+ "no-bf" => \$no_bf,
+ "no-cast" => \$no_cast,
+ "no-md2" => \$no_md2,
+ "no-md4" => \$no_md4,
+ "no-md5" => \$no_md5,
+ "no-sha" => \$no_sha,
+ "no-sha1" => \$no_sha1,
+ "no-ripemd" => \$no_ripemd,
+ "no-mdc2" => \$no_mdc2,
+ "no-whirlpool" => \$no_whirlpool,
+ "no-patents" =>
+ [\$no_rc2, \$no_rc4, \$no_rc5, \$no_idea, \$no_rsa],
+ "no-rsa" => \$no_rsa,
+ "no-dsa" => \$no_dsa,
+ "no-dh" => \$no_dh,
+ "no-hmac" => \$no_hmac,
+ "no-asm" => \$no_asm,
+ "nasm" => \$nasm,
+ "nw-nasm" => \$nw_nasm,
+ "nw-mwasm" => \$nw_mwasm,
+ "gaswin" => \$gaswin,
+ "no-ssl2" => \$no_ssl2,
+ "no-ssl3" => \$no_ssl3,
+ "no-tlsext" => \$no_tlsext,
+ "no-cms" => \$no_cms,
+ "no-jpake" => \$no_jpake,
+ "no-err" => \$no_err,
+ "no-sock" => \$no_sock,
+ "no-krb5" => \$no_krb5,
+ "no-ec" => \$no_ec,
+ "no-ecdsa" => \$no_ecdsa,
+ "no-ecdh" => \$no_ecdh,
+ "no-gost" => \$no_gost,
+ "no-engine" => \$no_engine,
+ "no-hw" => \$no_hw,
+ "just-ssl" =>
+ [\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
+ \$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
+ \$no_ssl2, \$no_err, \$no_ripemd, \$no_rc5,
+ \$no_aes, \$no_camellia, \$no_seed],
+ "rsaref" => 0,
+ "gcc" => \$gcc,
+ "debug" => \$debug,
+ "profile" => \$profile,
+ "shlib" => \$shlib,
+ "dll" => \$shlib,
+ "shared" => 0,
+ "no-gmp" => 0,
+ "no-rfc3779" => 0,
+ "no-montasm" => 0,
+ "no-shared" => 0,
+ "no-store" => 0,
+ "no-zlib" => 0,
+ "no-zlib-dynamic" => 0,
+ );
+
+ if (exists $valid_options{$_})
+ {
+ my $r = $valid_options{$_};
+ if ( ref $r eq "SCALAR")
+ { $$r = 1;}
+ elsif ( ref $r eq "ARRAY")
+ {
+ my $r2;
+ foreach $r2 (@$r)
+ {
+ $$r2 = 1;
+ }
+ }
+ }
+ elsif (/^no-comp$/) { $xcflags = "-DOPENSSL_NO_COMP $xcflags"; }
+ elsif (/^enable-zlib$/) { $zlib_opt = 1 if $zlib_opt == 0 }
+ elsif (/^enable-zlib-dynamic$/)
+ {
+ $zlib_opt = 2;
+ }
+ elsif (/^no-static-engine/)
+ {
+ $no_static_engine = 1;
+ }
+ elsif (/^enable-static-engine/)
+ {
+ $no_static_engine = 0;
+ }
+ # There are also enable-xxx options which correspond to
+ # the no-xxx. Since the scalars are enabled by default
+ # these can be ignored.
+ elsif (/^enable-/)
+ {
+ my $t = $_;
+ $t =~ s/^enable/no/;
+ if (exists $valid_options{$t})
+ {return 1;}
+ return 0;
+ }
+ # experimental-xxx is mostly like enable-xxx, but opensslconf.v
+ # will still set OPENSSL_NO_xxx unless we set OPENSSL_EXPERIMENTAL_xxx.
+ # (No need to fail if we don't know the algorithm -- this is for adventurous users only.)
+ elsif (/^experimental-/)
+ {
+ my $algo, $ALGO;
+ ($algo = $_) =~ s/^experimental-//;
+ ($ALGO = $algo) =~ tr/[a-z]/[A-Z]/;
+
+ $xcflags="-DOPENSSL_EXPERIMENTAL_$ALGO $xcflags";
+
+ }
+ elsif (/^--with-krb5-flavor=(.*)$/)
+ {
+ my $krb5_flavor = $1;
+ if ($krb5_flavor =~ /^force-[Hh]eimdal$/)
+ {
+ $xcflags="-DKRB5_HEIMDAL $xcflags";
+ }
+ elsif ($krb5_flavor =~ /^MIT/i)
+ {
+ $xcflags="-DKRB5_MIT $xcflags";
+ if ($krb5_flavor =~ /^MIT[._-]*1[._-]*[01]/i)
+ {
+ $xcflags="-DKRB5_MIT_OLD11 $xcflags"
+ }
+ }
+ }
+ elsif (/^([^=]*)=(.*)$/){ $VARS{$1}=$2; }
+ elsif (/^-[lL].*$/) { $l_flags.="$_ "; }
+ elsif ((!/^-help/) && (!/^-h/) && (!/^-\?/) && /^-.*$/)
+ { $c_flags.="$_ "; }
+ else { return(0); }
+ return(1);
+ }
diff --git a/openssl/util/mkerr.pl b/openssl/util/mkerr.pl
index 74e3ef67b..d8ea43a5d 100644
--- a/openssl/util/mkerr.pl
+++ b/openssl/util/mkerr.pl
@@ -1,810 +1,810 @@
-#!/usr/local/bin/perl -w
-
-my $config = "crypto/err/openssl.ec";
-my $hprefix = "openssl/";
-my $debug = 0;
-my $rebuild = 0;
-my $static = 1;
-my $recurse = 0;
-my $reindex = 0;
-my $dowrite = 0;
-my $staticloader = "";
-
-my $pack_errcode;
-my $load_errcode;
-
-my $errcount;
-
-while (@ARGV) {
- my $arg = $ARGV[0];
- if($arg eq "-conf") {
- shift @ARGV;
- $config = shift @ARGV;
- } elsif($arg eq "-hprefix") {
- shift @ARGV;
- $hprefix = shift @ARGV;
- } elsif($arg eq "-debug") {
- $debug = 1;
- shift @ARGV;
- } elsif($arg eq "-rebuild") {
- $rebuild = 1;
- shift @ARGV;
- } elsif($arg eq "-recurse") {
- $recurse = 1;
- shift @ARGV;
- } elsif($arg eq "-reindex") {
- $reindex = 1;
- shift @ARGV;
- } elsif($arg eq "-nostatic") {
- $static = 0;
- shift @ARGV;
- } elsif($arg eq "-staticloader") {
- $staticloader = "static ";
- shift @ARGV;
- } elsif($arg eq "-write") {
- $dowrite = 1;
- shift @ARGV;
- } elsif($arg eq "-help" || $arg eq "-h" || $arg eq "-?" || $arg eq "--help") {
- print STDERR <<"EOF";
-mkerr.pl [options] ...
-
-Options:
-
- -conf F Use the config file F instead of the default one:
- crypto/err/openssl.ec
-
- -hprefix P Prepend the filenames in generated #include <header>
- statements with prefix P. Default: 'openssl/' (without
- the quotes, naturally)
-
- -debug Turn on debugging verbose output on stderr.
-
- -rebuild Rebuild all header and C source files, irrespective of the
- fact if any error or function codes have been added/removed.
- Default: only update files for libraries which saw change
- (of course, this requires '-write' as well, or no
- files will be touched!)
-
- -recurse scan a preconfigured set of directories / files for error and
- function codes:
- (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>, <apps/*.c>)
- When this option is NOT specified, the filelist is taken from
- the commandline instead. Here, wildcards may be embedded. (Be
- sure to escape those to prevent the shell from expanding them
- for you when you wish mkerr.pl to do so instead.)
- Default: take file list to scan from the command line.
-
- -reindex Discard the numeric values previously assigned to the error
- and function codes as extracted from the scanned header files;
- instead renumber all of them starting from 100. (Note that
- the numbers assigned through 'R' records in the config file
- remain intact.)
- Default: keep previously assigned numbers. (You are warned
- when collisions are detected.)
-
- -nostatic Generates a different source code, where these additional
- functions are generated for each library specified in the
- config file:
- void ERR_load_<LIB>_strings(void);
- void ERR_unload_<LIB>_strings(void);
- void ERR_<LIB>_error(int f, int r, char *fn, int ln);
- #define <LIB>err(f,r) ERR_<LIB>_error(f,r,__FILE__,__LINE__)
- while the code facilitates the use of these in an environment
- where the error support routines are dynamically loaded at
- runtime.
- Default: 'static' code generation.
-
- -staticloader Prefix generated functions with the 'static' scope modifier.
- Default: don't write any scope modifier prefix.
-
- -write Actually (over)write the generated code to the header and C
- source files as assigned to each library through the config
- file.
- Default: don't write.
-
- -help / -h / -? / --help Show this help text.
-
- ... Additional arguments are added to the file list to scan,
- assuming '-recurse' was NOT specified on the command line.
-
-EOF
- exit 1;
- } else {
- last;
- }
-}
-
-if($recurse) {
- @source = (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>);
-} else {
- @source = @ARGV;
-}
-
-# Read in the config file
-
-open(IN, "<$config") || die "Can't open config file $config";
-
-# Parse config file
-
-while(<IN>)
-{
- if(/^L\s+(\S+)\s+(\S+)\s+(\S+)/) {
- $hinc{$1} = $2;
- $libinc{$2} = $1;
- $cskip{$3} = $1;
- if($3 ne "NONE") {
- $csrc{$1} = $3;
- $fmax{$1} = 100;
- $rmax{$1} = 100;
- $fassigned{$1} = ":";
- $rassigned{$1} = ":";
- $fnew{$1} = 0;
- $rnew{$1} = 0;
- }
- } elsif (/^F\s+(\S+)/) {
- # Add extra function with $1
- } elsif (/^R\s+(\S+)\s+(\S+)/) {
- $rextra{$1} = $2;
- $rcodes{$1} = $2;
- }
-}
-
-close IN;
-
-# Scan each header file in turn and make a list of error codes
-# and function names
-
-while (($hdr, $lib) = each %libinc)
-{
- next if($hdr eq "NONE");
- print STDERR "Scanning header file $hdr\n" if $debug;
- my $line = "", $def= "", $linenr = 0, $gotfile = 0;
- if (open(IN, "<$hdr")) {
- $gotfile = 1;
- while(<IN>) {
- $linenr++;
- print STDERR "line: $linenr\r" if $debug;
-
- last if(/BEGIN\s+ERROR\s+CODES/);
- if ($line ne '') {
- $_ = $line . $_;
- $line = '';
- }
-
- if (/\\$/) {
- $line = $_;
- next;
- }
-
- if(/\/\*/) {
- if (not /\*\//) { # multiline comment...
- $line = $_; # ... just accumulate
- next;
- } else {
- s/\/\*.*?\*\///gs; # wipe it
- }
- }
-
- if ($cpp) {
- $cpp++ if /^#\s*if/;
- $cpp-- if /^#\s*endif/;
- next;
- }
- $cpp = 1 if /^#.*ifdef.*cplusplus/; # skip "C" declaration
-
- next if (/^\#/); # skip preprocessor directives
-
- s/{[^{}]*}//gs; # ignore {} blocks
-
- if (/\{|\/\*/) { # Add a } so editor works...
- $line = $_;
- } else {
- $def .= $_;
- }
- }
- }
-
- print STDERR " \r" if $debug;
- $defnr = 0;
- # Delete any DECLARE_ macros
- $def =~ s/DECLARE_\w+\([\w,\s]+\)//gs;
- foreach (split /;/, $def) {
- $defnr++;
- print STDERR "def: $defnr\r" if $debug;
-
- # The goal is to collect function names from function declarations.
-
- s/^[\n\s]*//g;
- s/[\n\s]*$//g;
-
- # Skip over recognized non-function declarations
- next if(/typedef\W/ or /DECLARE_STACK_OF/ or /TYPEDEF_.*_OF/);
-
- # Remove STACK_OF(foo)
- s/STACK_OF\(\w+\)/void/;
-
- # Reduce argument lists to empty ()
- # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
- while(/\(.*\)/s) {
- s/\([^\(\)]+\)/\{\}/gs;
- s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs; #(*f{}) -> f
- }
- # pretend as we didn't use curly braces: {} -> ()
- s/\{\}/\(\)/gs;
-
- if (/(\w+)\s*\(\).*/s) { # first token prior [first] () is
- my $name = $1; # a function name!
- $name =~ tr/[a-z]/[A-Z]/;
- $ftrans{$name} = $1;
- } elsif (/[\(\)]/ and not (/=/)) {
- print STDERR "Header $hdr: cannot parse: $_;\n";
- }
- }
-
- print STDERR " \r" if $debug;
-
- next if $reindex;
-
- # Scan function and reason codes and store them: keep a note of the
- # maximum code used.
-
- if ($gotfile) {
- while(<IN>) {
- if(/^\#define\s+(\S+)\s+(\S+)/) {
- $name = $1;
- $code = $2;
- next if $name =~ /^${lib}err/;
- unless($name =~ /^${lib}_([RF])_(\w+)$/) {
- print STDERR "Invalid error code $name\n";
- next;
- }
- if($1 eq "R") {
- $rcodes{$name} = $code;
- if ($rassigned{$lib} =~ /:$code:/) {
- print STDERR "!! ERROR: $lib reason code $code assigned twice (collision at $name)\n";
- ++$errcount;
- }
- $rassigned{$lib} .= "$code:";
- if(!(exists $rextra{$name}) &&
- ($code > $rmax{$lib}) ) {
- $rmax{$lib} = $code;
- }
- } else {
- if ($fassigned{$lib} =~ /:$code:/) {
- print STDERR "!! ERROR: $lib function code $code assigned twice (collision at $name)\n";
- ++$errcount;
- }
- $fassigned{$lib} .= "$code:";
- if($code > $fmax{$lib}) {
- $fmax{$lib} = $code;
- }
- $fcodes{$name} = $code;
- }
- }
- }
- }
-
- if ($debug) {
- if (defined($fmax{$lib})) {
- print STDERR "Max function code fmax" . "{" . "$lib" . "} = $fmax{$lib}\n";
- $fassigned{$lib} =~ m/^:(.*):$/;
- @fassigned = sort {$a <=> $b} split(":", $1);
- print STDERR " @fassigned\n";
- }
- if (defined($rmax{$lib})) {
- print STDERR "Max reason code rmax" . "{" . "$lib" . "} = $rmax{$lib}\n";
- $rassigned{$lib} =~ m/^:(.*):$/;
- @rassigned = sort {$a <=> $b} split(":", $1);
- print STDERR " @rassigned\n";
- }
- }
-
- if ($lib eq "SSL") {
- if ($rmax{$lib} >= 1000) {
- print STDERR "!! ERROR: SSL error codes 1000+ are reserved for alerts.\n";
- print STDERR "!! Any new alerts must be added to $config.\n";
- ++$errcount;
- print STDERR "\n";
- }
- }
- close IN;
-}
-
-# Scan each C source file and look for function and reason codes
-# This is done by looking for strings that "look like" function or
-# reason codes: basically anything consisting of all upper case and
-# numerics which has _F_ or _R_ in it and which has the name of an
-# error library at the start. This seems to work fine except for the
-# oddly named structure BIO_F_CTX which needs to be ignored.
-# If a code doesn't exist in list compiled from headers then mark it
-# with the value "X" as a place holder to give it a value later.
-# Store all function and reason codes found in %ufcodes and %urcodes
-# so all those unreferenced can be printed out.
-
-
-foreach $file (@source) {
- # Don't parse the error source file.
- next if exists $cskip{$file};
- print STDERR "File loaded: ".$file."\r" if $debug;
- open(IN, "<$file") || die "Can't open source file $file\n";
- while(<IN>) {
- # skip obsoleted source files entirely!
- last if(/^#error\s+obsolete/);
-
- if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) {
- next unless exists $csrc{$2};
- next if($1 eq "BIO_F_BUFFER_CTX");
- $ufcodes{$1} = 1;
- if(!exists $fcodes{$1}) {
- $fcodes{$1} = "X";
- $fnew{$2}++;
- }
- $notrans{$1} = 1 unless exists $ftrans{$3};
- print STDERR "Function: $1\t= $fcodes{$1} (lib: $2, name: $3)\n" if $debug;
- }
- if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) {
- next unless exists $csrc{$2};
- $urcodes{$1} = 1;
- if(!exists $rcodes{$1}) {
- $rcodes{$1} = "X";
- $rnew{$2}++;
- }
- print STDERR "Reason: $1\t= $rcodes{$1} (lib: $2)\n" if $debug;
- }
- }
- close IN;
-}
-print STDERR " \n" if $debug;
-
-# Now process each library in turn.
-
-foreach $lib (keys %csrc)
-{
- my $hfile = $hinc{$lib};
- my $cfile = $csrc{$lib};
- if(!$fnew{$lib} && !$rnew{$lib}) {
- print STDERR "$lib:\t\tNo new error codes\n";
- next unless $rebuild;
- } else {
- print STDERR "$lib:\t\t$fnew{$lib} New Functions,";
- print STDERR " $rnew{$lib} New Reasons.\n";
- next unless $dowrite;
- }
-
- # If we get here then we have some new error codes so we
- # need to rebuild the header file and C file.
-
- # Make a sorted list of error and reason codes for later use.
-
- my @function = sort grep(/^${lib}_/,keys %fcodes);
- my @reasons = sort grep(/^${lib}_/,keys %rcodes);
-
- # Rewrite the header file
-
- if (open(IN, "<$hfile")) {
- # Copy across the old file
- while(<IN>) {
- push @out, $_;
- last if (/BEGIN ERROR CODES/);
- }
- close IN;
- } else {
- push @out,
-"/* ====================================================================\n",
-" * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.\n",
-" *\n",
-" * Redistribution and use in source and binary forms, with or without\n",
-" * modification, are permitted provided that the following conditions\n",
-" * are met:\n",
-" *\n",
-" * 1. Redistributions of source code must retain the above copyright\n",
-" * notice, this list of conditions and the following disclaimer. \n",
-" *\n",
-" * 2. Redistributions in binary form must reproduce the above copyright\n",
-" * notice, this list of conditions and the following disclaimer in\n",
-" * the documentation and/or other materials provided with the\n",
-" * distribution.\n",
-" *\n",
-" * 3. All advertising materials mentioning features or use of this\n",
-" * software must display the following acknowledgment:\n",
-" * \"This product includes software developed by the OpenSSL Project\n",
-" * for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"\n",
-" *\n",
-" * 4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to\n",
-" * endorse or promote products derived from this software without\n",
-" * prior written permission. For written permission, please contact\n",
-" * openssl-core\@openssl.org.\n",
-" *\n",
-" * 5. Products derived from this software may not be called \"OpenSSL\"\n",
-" * nor may \"OpenSSL\" appear in their names without prior written\n",
-" * permission of the OpenSSL Project.\n",
-" *\n",
-" * 6. Redistributions of any form whatsoever must retain the following\n",
-" * acknowledgment:\n",
-" * \"This product includes software developed by the OpenSSL Project\n",
-" * for use in the OpenSSL Toolkit (http://www.openssl.org/)\"\n",
-" *\n",
-" * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\n",
-" * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n",
-" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n",
-" * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR\n",
-" * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n",
-" * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n",
-" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n",
-" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n",
-" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n",
-" * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n",
-" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n",
-" * OF THE POSSIBILITY OF SUCH DAMAGE.\n",
-" * ====================================================================\n",
-" *\n",
-" * This product includes cryptographic software written by Eric Young\n",
-" * (eay\@cryptsoft.com). This product includes software written by Tim\n",
-" * Hudson (tjh\@cryptsoft.com).\n",
-" *\n",
-" */\n",
-"\n",
-"#ifndef HEADER_${lib}_ERR_H\n",
-"#define HEADER_${lib}_ERR_H\n",
-"\n",
-"#ifdef __cplusplus\n",
-"extern \"C\" {\n",
-"#endif\n",
-"\n",
-"/* BEGIN ERROR CODES */\n";
- }
- open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n";
-
- print OUT @out;
- undef @out;
- print OUT <<"EOF";
-/* The following lines are auto generated by the script mkerr.pl. Any changes
- * made after this point may be overwritten when the script is next run.
- */
-EOF
- if($static) {
- print OUT <<"EOF";
-${staticloader}void ERR_load_${lib}_strings(void);
-
-EOF
- } else {
- print OUT <<"EOF";
-${staticloader}void ERR_load_${lib}_strings(void);
-${staticloader}void ERR_unload_${lib}_strings(void);
-${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line);
-#define ${lib}err(f,r) ERR_${lib}_error((f),(r),__FILE__,__LINE__)
-
-EOF
- }
- print OUT <<"EOF";
-/* Error codes for the $lib functions. */
-
-/* Function codes. */
-EOF
-
- foreach $i (@function) {
- $z=6-int(length($i)/8);
- if($fcodes{$i} eq "X") {
- $fassigned{$lib} =~ m/^:([^:]*):/;
- $findcode = $1;
- if (!defined($findcode)) {
- $findcode = $fmax{$lib};
- }
- while ($fassigned{$lib} =~ m/:$findcode:/) {
- $findcode++;
- }
- $fcodes{$i} = $findcode;
- $fassigned{$lib} .= "$findcode:";
- print STDERR "New Function code $i\n" if $debug;
- }
- printf OUT "#define $i%s $fcodes{$i}\n","\t" x $z;
- }
-
- print OUT "\n/* Reason codes. */\n";
-
- foreach $i (@reasons) {
- $z=6-int(length($i)/8);
- if($rcodes{$i} eq "X") {
- $rassigned{$lib} =~ m/^:([^:]*):/;
- $findcode = $1;
- if (!defined($findcode)) {
- $findcode = $rmax{$lib};
- }
- while ($rassigned{$lib} =~ m/:$findcode:/) {
- $findcode++;
- }
- $rcodes{$i} = $findcode;
- $rassigned{$lib} .= "$findcode:";
- print STDERR "New Reason code $i\n" if $debug;
- }
- printf OUT "#define $i%s $rcodes{$i}\n","\t" x $z;
- }
- print OUT <<"EOF";
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-EOF
- close OUT;
-
- # Rewrite the C source file containing the error details.
-
- # First, read any existing reason string definitions:
- my %err_reason_strings;
- if (open(IN,"<$cfile")) {
- while (<IN>) {
- if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) {
- $err_reason_strings{$1} = $2;
- }
- if (/\b${lib}_F_(\w*)\b.*\"(.*)\"/) {
- if (!exists $ftrans{$1} && ($1 ne $2)) {
- print STDERR "WARNING: Mismatched function string $2\n";
- $ftrans{$1} = $2;
- }
- }
- }
- close(IN);
- }
-
-
- my $hincf;
- if($static) {
- $hfile =~ /([^\/]+)$/;
- $hincf = "<${hprefix}$1>";
- } else {
- $hincf = "\"$hfile\"";
- }
-
- # If static we know the error code at compile time so use it
- # in error definitions.
-
- if ($static)
- {
- $pack_errcode = "ERR_LIB_${lib}";
- $load_errcode = "0";
- }
- else
- {
- $pack_errcode = "0";
- $load_errcode = "ERR_LIB_${lib}";
- }
-
-
- open (OUT,">$cfile") || die "Can't open $cfile for writing";
-
- print OUT <<"EOF";
-/* $cfile */
-/* ====================================================================
- * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core\@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay\@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh\@cryptsoft.com).
- *
- */
-
-/* NOTE: this file was auto generated by the mkerr.pl script: any changes
- * made to it will be overwritten when the script next updates this file,
- * only reason strings will be preserved.
- */
-
-#include <stdio.h>
-#include <openssl/err.h>
-#include $hincf
-
-/* BEGIN ERROR CODES */
-#ifndef OPENSSL_NO_ERR
-
-#define ERR_FUNC(func) ERR_PACK($pack_errcode,func,0)
-#define ERR_REASON(reason) ERR_PACK($pack_errcode,0,reason)
-
-static ERR_STRING_DATA ${lib}_str_functs[]=
- {
-EOF
- # Add each function code: if a function name is found then use it.
- foreach $i (@function) {
- my $fn;
- $i =~ /^${lib}_F_(\S+)$/;
- $fn = $1;
- if(exists $ftrans{$fn}) {
- $fn = $ftrans{$fn};
- }
-# print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n";
- print OUT "{ERR_FUNC($i),\t\"$fn\"},\n";
- }
- print OUT <<"EOF";
-{0,NULL}
- };
-
-static ERR_STRING_DATA ${lib}_str_reasons[]=
- {
-EOF
- # Add each reason code.
- foreach $i (@reasons) {
- my $rn;
- my $rstr = "ERR_REASON($i)";
- my $nspc = 0;
- if (exists $err_reason_strings{$i}) {
- $rn = $err_reason_strings{$i};
- } else {
- $i =~ /^${lib}_R_(\S+)$/;
- $rn = $1;
- $rn =~ tr/_[A-Z]/ [a-z]/;
- }
- $nspc = 40 - length($rstr) unless length($rstr) > 40;
- $nspc = " " x $nspc;
- print OUT "{${rstr}${nspc},\"$rn\"},\n";
- }
-if($static) {
- print OUT <<"EOF";
-{0,NULL}
- };
-
-#endif
-
-${staticloader}void ERR_load_${lib}_strings(void)
- {
-#ifndef OPENSSL_NO_ERR
-
- if (ERR_func_error_string(${lib}_str_functs[0].error) == NULL)
- {
- ERR_load_strings($load_errcode,${lib}_str_functs);
- ERR_load_strings($load_errcode,${lib}_str_reasons);
- }
-#endif
- }
-EOF
-} else {
- print OUT <<"EOF";
-{0,NULL}
- };
-
-#endif
-
-#ifdef ${lib}_LIB_NAME
-static ERR_STRING_DATA ${lib}_lib_name[]=
- {
-{0 ,${lib}_LIB_NAME},
-{0,NULL}
- };
-#endif
-
-
-static int ${lib}_lib_error_code=0;
-static int ${lib}_error_init=1;
-
-${staticloader}void ERR_load_${lib}_strings(void)
- {
- if (${lib}_lib_error_code == 0)
- ${lib}_lib_error_code=ERR_get_next_error_library();
-
- if (${lib}_error_init)
- {
- ${lib}_error_init=0;
-#ifndef OPENSSL_NO_ERR
- ERR_load_strings(${lib}_lib_error_code,${lib}_str_functs);
- ERR_load_strings(${lib}_lib_error_code,${lib}_str_reasons);
-#endif
-
-#ifdef ${lib}_LIB_NAME
- ${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code,0,0);
- ERR_load_strings(0,${lib}_lib_name);
-#endif
- }
- }
-
-${staticloader}void ERR_unload_${lib}_strings(void)
- {
- if (${lib}_error_init == 0)
- {
-#ifndef OPENSSL_NO_ERR
- ERR_unload_strings(${lib}_lib_error_code,${lib}_str_functs);
- ERR_unload_strings(${lib}_lib_error_code,${lib}_str_reasons);
-#endif
-
-#ifdef ${lib}_LIB_NAME
- ERR_unload_strings(0,${lib}_lib_name);
-#endif
- ${lib}_error_init=1;
- }
- }
-
-${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line)
- {
- if (${lib}_lib_error_code == 0)
- ${lib}_lib_error_code=ERR_get_next_error_library();
- ERR_PUT_error(${lib}_lib_error_code,function,reason,file,line);
- }
-EOF
-
-}
-
- close OUT;
- undef %err_reason_strings;
-}
-
-if($debug && defined(%notrans)) {
- print STDERR "The following function codes were not translated:\n";
- foreach(sort keys %notrans)
- {
- print STDERR "$_\n";
- }
-}
-
-# Make a list of unreferenced function and reason codes
-
-foreach (keys %fcodes) {
- push (@funref, $_) unless exists $ufcodes{$_};
-}
-
-foreach (keys %rcodes) {
- push (@runref, $_) unless exists $urcodes{$_};
-}
-
-if($debug && defined(@funref) ) {
- print STDERR "The following function codes were not referenced:\n";
- foreach(sort @funref)
- {
- print STDERR "$_\n";
- }
-}
-
-if($debug && defined(@runref) ) {
- print STDERR "The following reason codes were not referenced:\n";
- foreach(sort @runref)
- {
- print STDERR "$_\n";
- }
-}
-
-if($errcount) {
- print STDERR "There were errors, failing...\n\n";
- exit $errcount;
-}
-
+#!/usr/local/bin/perl -w
+
+my $config = "crypto/err/openssl.ec";
+my $hprefix = "openssl/";
+my $debug = 0;
+my $rebuild = 0;
+my $static = 1;
+my $recurse = 0;
+my $reindex = 0;
+my $dowrite = 0;
+my $staticloader = "";
+
+my $pack_errcode;
+my $load_errcode;
+
+my $errcount;
+
+while (@ARGV) {
+ my $arg = $ARGV[0];
+ if($arg eq "-conf") {
+ shift @ARGV;
+ $config = shift @ARGV;
+ } elsif($arg eq "-hprefix") {
+ shift @ARGV;
+ $hprefix = shift @ARGV;
+ } elsif($arg eq "-debug") {
+ $debug = 1;
+ shift @ARGV;
+ } elsif($arg eq "-rebuild") {
+ $rebuild = 1;
+ shift @ARGV;
+ } elsif($arg eq "-recurse") {
+ $recurse = 1;
+ shift @ARGV;
+ } elsif($arg eq "-reindex") {
+ $reindex = 1;
+ shift @ARGV;
+ } elsif($arg eq "-nostatic") {
+ $static = 0;
+ shift @ARGV;
+ } elsif($arg eq "-staticloader") {
+ $staticloader = "static ";
+ shift @ARGV;
+ } elsif($arg eq "-write") {
+ $dowrite = 1;
+ shift @ARGV;
+ } elsif($arg eq "-help" || $arg eq "-h" || $arg eq "-?" || $arg eq "--help") {
+ print STDERR <<"EOF";
+mkerr.pl [options] ...
+
+Options:
+
+ -conf F Use the config file F instead of the default one:
+ crypto/err/openssl.ec
+
+ -hprefix P Prepend the filenames in generated #include <header>
+ statements with prefix P. Default: 'openssl/' (without
+ the quotes, naturally)
+
+ -debug Turn on debugging verbose output on stderr.
+
+ -rebuild Rebuild all header and C source files, irrespective of the
+ fact if any error or function codes have been added/removed.
+ Default: only update files for libraries which saw change
+ (of course, this requires '-write' as well, or no
+ files will be touched!)
+
+ -recurse scan a preconfigured set of directories / files for error and
+ function codes:
+ (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>, <apps/*.c>)
+ When this option is NOT specified, the filelist is taken from
+ the commandline instead. Here, wildcards may be embedded. (Be
+ sure to escape those to prevent the shell from expanding them
+ for you when you wish mkerr.pl to do so instead.)
+ Default: take file list to scan from the command line.
+
+ -reindex Discard the numeric values previously assigned to the error
+ and function codes as extracted from the scanned header files;
+ instead renumber all of them starting from 100. (Note that
+ the numbers assigned through 'R' records in the config file
+ remain intact.)
+ Default: keep previously assigned numbers. (You are warned
+ when collisions are detected.)
+
+ -nostatic Generates a different source code, where these additional
+ functions are generated for each library specified in the
+ config file:
+ void ERR_load_<LIB>_strings(void);
+ void ERR_unload_<LIB>_strings(void);
+ void ERR_<LIB>_error(int f, int r, char *fn, int ln);
+ #define <LIB>err(f,r) ERR_<LIB>_error(f,r,__FILE__,__LINE__)
+ while the code facilitates the use of these in an environment
+ where the error support routines are dynamically loaded at
+ runtime.
+ Default: 'static' code generation.
+
+ -staticloader Prefix generated functions with the 'static' scope modifier.
+ Default: don't write any scope modifier prefix.
+
+ -write Actually (over)write the generated code to the header and C
+ source files as assigned to each library through the config
+ file.
+ Default: don't write.
+
+ -help / -h / -? / --help Show this help text.
+
+ ... Additional arguments are added to the file list to scan,
+ assuming '-recurse' was NOT specified on the command line.
+
+EOF
+ exit 1;
+ } else {
+ last;
+ }
+}
+
+if($recurse) {
+ @source = (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>);
+} else {
+ @source = @ARGV;
+}
+
+# Read in the config file
+
+open(IN, "<$config") || die "Can't open config file $config";
+
+# Parse config file
+
+while(<IN>)
+{
+ if(/^L\s+(\S+)\s+(\S+)\s+(\S+)/) {
+ $hinc{$1} = $2;
+ $libinc{$2} = $1;
+ $cskip{$3} = $1;
+ if($3 ne "NONE") {
+ $csrc{$1} = $3;
+ $fmax{$1} = 100;
+ $rmax{$1} = 100;
+ $fassigned{$1} = ":";
+ $rassigned{$1} = ":";
+ $fnew{$1} = 0;
+ $rnew{$1} = 0;
+ }
+ } elsif (/^F\s+(\S+)/) {
+ # Add extra function with $1
+ } elsif (/^R\s+(\S+)\s+(\S+)/) {
+ $rextra{$1} = $2;
+ $rcodes{$1} = $2;
+ }
+}
+
+close IN;
+
+# Scan each header file in turn and make a list of error codes
+# and function names
+
+while (($hdr, $lib) = each %libinc)
+{
+ next if($hdr eq "NONE");
+ print STDERR "Scanning header file $hdr\n" if $debug;
+ my $line = "", $def= "", $linenr = 0, $gotfile = 0;
+ if (open(IN, "<$hdr")) {
+ $gotfile = 1;
+ while(<IN>) {
+ $linenr++;
+ print STDERR "line: $linenr\r" if $debug;
+
+ last if(/BEGIN\s+ERROR\s+CODES/);
+ if ($line ne '') {
+ $_ = $line . $_;
+ $line = '';
+ }
+
+ if (/\\$/) {
+ $line = $_;
+ next;
+ }
+
+ if(/\/\*/) {
+ if (not /\*\//) { # multiline comment...
+ $line = $_; # ... just accumulate
+ next;
+ } else {
+ s/\/\*.*?\*\///gs; # wipe it
+ }
+ }
+
+ if ($cpp) {
+ $cpp++ if /^#\s*if/;
+ $cpp-- if /^#\s*endif/;
+ next;
+ }
+ $cpp = 1 if /^#.*ifdef.*cplusplus/; # skip "C" declaration
+
+ next if (/^\#/); # skip preprocessor directives
+
+ s/{[^{}]*}//gs; # ignore {} blocks
+
+ if (/\{|\/\*/) { # Add a } so editor works...
+ $line = $_;
+ } else {
+ $def .= $_;
+ }
+ }
+ }
+
+ print STDERR " \r" if $debug;
+ $defnr = 0;
+ # Delete any DECLARE_ macros
+ $def =~ s/DECLARE_\w+\([\w,\s]+\)//gs;
+ foreach (split /;/, $def) {
+ $defnr++;
+ print STDERR "def: $defnr\r" if $debug;
+
+ # The goal is to collect function names from function declarations.
+
+ s/^[\n\s]*//g;
+ s/[\n\s]*$//g;
+
+ # Skip over recognized non-function declarations
+ next if(/typedef\W/ or /DECLARE_STACK_OF/ or /TYPEDEF_.*_OF/);
+
+ # Remove STACK_OF(foo)
+ s/STACK_OF\(\w+\)/void/;
+
+ # Reduce argument lists to empty ()
+ # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
+ while(/\(.*\)/s) {
+ s/\([^\(\)]+\)/\{\}/gs;
+ s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs; #(*f{}) -> f
+ }
+ # pretend as we didn't use curly braces: {} -> ()
+ s/\{\}/\(\)/gs;
+
+ if (/(\w+)\s*\(\).*/s) { # first token prior [first] () is
+ my $name = $1; # a function name!
+ $name =~ tr/[a-z]/[A-Z]/;
+ $ftrans{$name} = $1;
+ } elsif (/[\(\)]/ and not (/=/)) {
+ print STDERR "Header $hdr: cannot parse: $_;\n";
+ }
+ }
+
+ print STDERR " \r" if $debug;
+
+ next if $reindex;
+
+ # Scan function and reason codes and store them: keep a note of the
+ # maximum code used.
+
+ if ($gotfile) {
+ while(<IN>) {
+ if(/^\#define\s+(\S+)\s+(\S+)/) {
+ $name = $1;
+ $code = $2;
+ next if $name =~ /^${lib}err/;
+ unless($name =~ /^${lib}_([RF])_(\w+)$/) {
+ print STDERR "Invalid error code $name\n";
+ next;
+ }
+ if($1 eq "R") {
+ $rcodes{$name} = $code;
+ if ($rassigned{$lib} =~ /:$code:/) {
+ print STDERR "!! ERROR: $lib reason code $code assigned twice (collision at $name)\n";
+ ++$errcount;
+ }
+ $rassigned{$lib} .= "$code:";
+ if(!(exists $rextra{$name}) &&
+ ($code > $rmax{$lib}) ) {
+ $rmax{$lib} = $code;
+ }
+ } else {
+ if ($fassigned{$lib} =~ /:$code:/) {
+ print STDERR "!! ERROR: $lib function code $code assigned twice (collision at $name)\n";
+ ++$errcount;
+ }
+ $fassigned{$lib} .= "$code:";
+ if($code > $fmax{$lib}) {
+ $fmax{$lib} = $code;
+ }
+ $fcodes{$name} = $code;
+ }
+ }
+ }
+ }
+
+ if ($debug) {
+ if (defined($fmax{$lib})) {
+ print STDERR "Max function code fmax" . "{" . "$lib" . "} = $fmax{$lib}\n";
+ $fassigned{$lib} =~ m/^:(.*):$/;
+ @fassigned = sort {$a <=> $b} split(":", $1);
+ print STDERR " @fassigned\n";
+ }
+ if (defined($rmax{$lib})) {
+ print STDERR "Max reason code rmax" . "{" . "$lib" . "} = $rmax{$lib}\n";
+ $rassigned{$lib} =~ m/^:(.*):$/;
+ @rassigned = sort {$a <=> $b} split(":", $1);
+ print STDERR " @rassigned\n";
+ }
+ }
+
+ if ($lib eq "SSL") {
+ if ($rmax{$lib} >= 1000) {
+ print STDERR "!! ERROR: SSL error codes 1000+ are reserved for alerts.\n";
+ print STDERR "!! Any new alerts must be added to $config.\n";
+ ++$errcount;
+ print STDERR "\n";
+ }
+ }
+ close IN;
+}
+
+# Scan each C source file and look for function and reason codes
+# This is done by looking for strings that "look like" function or
+# reason codes: basically anything consisting of all upper case and
+# numerics which has _F_ or _R_ in it and which has the name of an
+# error library at the start. This seems to work fine except for the
+# oddly named structure BIO_F_CTX which needs to be ignored.
+# If a code doesn't exist in list compiled from headers then mark it
+# with the value "X" as a place holder to give it a value later.
+# Store all function and reason codes found in %ufcodes and %urcodes
+# so all those unreferenced can be printed out.
+
+
+foreach $file (@source) {
+ # Don't parse the error source file.
+ next if exists $cskip{$file};
+ print STDERR "File loaded: ".$file."\r" if $debug;
+ open(IN, "<$file") || die "Can't open source file $file\n";
+ while(<IN>) {
+ # skip obsoleted source files entirely!
+ last if(/^#error\s+obsolete/);
+
+ if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) {
+ next unless exists $csrc{$2};
+ next if($1 eq "BIO_F_BUFFER_CTX");
+ $ufcodes{$1} = 1;
+ if(!exists $fcodes{$1}) {
+ $fcodes{$1} = "X";
+ $fnew{$2}++;
+ }
+ $notrans{$1} = 1 unless exists $ftrans{$3};
+ print STDERR "Function: $1\t= $fcodes{$1} (lib: $2, name: $3)\n" if $debug;
+ }
+ if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) {
+ next unless exists $csrc{$2};
+ $urcodes{$1} = 1;
+ if(!exists $rcodes{$1}) {
+ $rcodes{$1} = "X";
+ $rnew{$2}++;
+ }
+ print STDERR "Reason: $1\t= $rcodes{$1} (lib: $2)\n" if $debug;
+ }
+ }
+ close IN;
+}
+print STDERR " \n" if $debug;
+
+# Now process each library in turn.
+
+foreach $lib (keys %csrc)
+{
+ my $hfile = $hinc{$lib};
+ my $cfile = $csrc{$lib};
+ if(!$fnew{$lib} && !$rnew{$lib}) {
+ print STDERR "$lib:\t\tNo new error codes\n";
+ next unless $rebuild;
+ } else {
+ print STDERR "$lib:\t\t$fnew{$lib} New Functions,";
+ print STDERR " $rnew{$lib} New Reasons.\n";
+ next unless $dowrite;
+ }
+
+ # If we get here then we have some new error codes so we
+ # need to rebuild the header file and C file.
+
+ # Make a sorted list of error and reason codes for later use.
+
+ my @function = sort grep(/^${lib}_/,keys %fcodes);
+ my @reasons = sort grep(/^${lib}_/,keys %rcodes);
+
+ # Rewrite the header file
+
+ if (open(IN, "<$hfile")) {
+ # Copy across the old file
+ while(<IN>) {
+ push @out, $_;
+ last if (/BEGIN ERROR CODES/);
+ }
+ close IN;
+ } else {
+ push @out,
+"/* ====================================================================\n",
+" * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.\n",
+" *\n",
+" * Redistribution and use in source and binary forms, with or without\n",
+" * modification, are permitted provided that the following conditions\n",
+" * are met:\n",
+" *\n",
+" * 1. Redistributions of source code must retain the above copyright\n",
+" * notice, this list of conditions and the following disclaimer. \n",
+" *\n",
+" * 2. Redistributions in binary form must reproduce the above copyright\n",
+" * notice, this list of conditions and the following disclaimer in\n",
+" * the documentation and/or other materials provided with the\n",
+" * distribution.\n",
+" *\n",
+" * 3. All advertising materials mentioning features or use of this\n",
+" * software must display the following acknowledgment:\n",
+" * \"This product includes software developed by the OpenSSL Project\n",
+" * for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"\n",
+" *\n",
+" * 4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to\n",
+" * endorse or promote products derived from this software without\n",
+" * prior written permission. For written permission, please contact\n",
+" * openssl-core\@openssl.org.\n",
+" *\n",
+" * 5. Products derived from this software may not be called \"OpenSSL\"\n",
+" * nor may \"OpenSSL\" appear in their names without prior written\n",
+" * permission of the OpenSSL Project.\n",
+" *\n",
+" * 6. Redistributions of any form whatsoever must retain the following\n",
+" * acknowledgment:\n",
+" * \"This product includes software developed by the OpenSSL Project\n",
+" * for use in the OpenSSL Toolkit (http://www.openssl.org/)\"\n",
+" *\n",
+" * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\n",
+" * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n",
+" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n",
+" * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR\n",
+" * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n",
+" * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n",
+" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n",
+" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n",
+" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n",
+" * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n",
+" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n",
+" * OF THE POSSIBILITY OF SUCH DAMAGE.\n",
+" * ====================================================================\n",
+" *\n",
+" * This product includes cryptographic software written by Eric Young\n",
+" * (eay\@cryptsoft.com). This product includes software written by Tim\n",
+" * Hudson (tjh\@cryptsoft.com).\n",
+" *\n",
+" */\n",
+"\n",
+"#ifndef HEADER_${lib}_ERR_H\n",
+"#define HEADER_${lib}_ERR_H\n",
+"\n",
+"#ifdef __cplusplus\n",
+"extern \"C\" {\n",
+"#endif\n",
+"\n",
+"/* BEGIN ERROR CODES */\n";
+ }
+ open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n";
+
+ print OUT @out;
+ undef @out;
+ print OUT <<"EOF";
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+EOF
+ if($static) {
+ print OUT <<"EOF";
+${staticloader}void ERR_load_${lib}_strings(void);
+
+EOF
+ } else {
+ print OUT <<"EOF";
+${staticloader}void ERR_load_${lib}_strings(void);
+${staticloader}void ERR_unload_${lib}_strings(void);
+${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line);
+#define ${lib}err(f,r) ERR_${lib}_error((f),(r),__FILE__,__LINE__)
+
+EOF
+ }
+ print OUT <<"EOF";
+/* Error codes for the $lib functions. */
+
+/* Function codes. */
+EOF
+
+ foreach $i (@function) {
+ $z=6-int(length($i)/8);
+ if($fcodes{$i} eq "X") {
+ $fassigned{$lib} =~ m/^:([^:]*):/;
+ $findcode = $1;
+ if (!defined($findcode)) {
+ $findcode = $fmax{$lib};
+ }
+ while ($fassigned{$lib} =~ m/:$findcode:/) {
+ $findcode++;
+ }
+ $fcodes{$i} = $findcode;
+ $fassigned{$lib} .= "$findcode:";
+ print STDERR "New Function code $i\n" if $debug;
+ }
+ printf OUT "#define $i%s $fcodes{$i}\n","\t" x $z;
+ }
+
+ print OUT "\n/* Reason codes. */\n";
+
+ foreach $i (@reasons) {
+ $z=6-int(length($i)/8);
+ if($rcodes{$i} eq "X") {
+ $rassigned{$lib} =~ m/^:([^:]*):/;
+ $findcode = $1;
+ if (!defined($findcode)) {
+ $findcode = $rmax{$lib};
+ }
+ while ($rassigned{$lib} =~ m/:$findcode:/) {
+ $findcode++;
+ }
+ $rcodes{$i} = $findcode;
+ $rassigned{$lib} .= "$findcode:";
+ print STDERR "New Reason code $i\n" if $debug;
+ }
+ printf OUT "#define $i%s $rcodes{$i}\n","\t" x $z;
+ }
+ print OUT <<"EOF";
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+EOF
+ close OUT;
+
+ # Rewrite the C source file containing the error details.
+
+ # First, read any existing reason string definitions:
+ my %err_reason_strings;
+ if (open(IN,"<$cfile")) {
+ while (<IN>) {
+ if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) {
+ $err_reason_strings{$1} = $2;
+ }
+ if (/\b${lib}_F_(\w*)\b.*\"(.*)\"/) {
+ if (!exists $ftrans{$1} && ($1 ne $2)) {
+ print STDERR "WARNING: Mismatched function string $2\n";
+ $ftrans{$1} = $2;
+ }
+ }
+ }
+ close(IN);
+ }
+
+
+ my $hincf;
+ if($static) {
+ $hfile =~ /([^\/]+)$/;
+ $hincf = "<${hprefix}$1>";
+ } else {
+ $hincf = "\"$hfile\"";
+ }
+
+ # If static we know the error code at compile time so use it
+ # in error definitions.
+
+ if ($static)
+ {
+ $pack_errcode = "ERR_LIB_${lib}";
+ $load_errcode = "0";
+ }
+ else
+ {
+ $pack_errcode = "0";
+ $load_errcode = "ERR_LIB_${lib}";
+ }
+
+
+ open (OUT,">$cfile") || die "Can't open $cfile for writing";
+
+ print OUT <<"EOF";
+/* $cfile */
+/* ====================================================================
+ * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core\@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay\@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh\@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include $hincf
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK($pack_errcode,func,0)
+#define ERR_REASON(reason) ERR_PACK($pack_errcode,0,reason)
+
+static ERR_STRING_DATA ${lib}_str_functs[]=
+ {
+EOF
+ # Add each function code: if a function name is found then use it.
+ foreach $i (@function) {
+ my $fn;
+ $i =~ /^${lib}_F_(\S+)$/;
+ $fn = $1;
+ if(exists $ftrans{$fn}) {
+ $fn = $ftrans{$fn};
+ }
+# print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n";
+ print OUT "{ERR_FUNC($i),\t\"$fn\"},\n";
+ }
+ print OUT <<"EOF";
+{0,NULL}
+ };
+
+static ERR_STRING_DATA ${lib}_str_reasons[]=
+ {
+EOF
+ # Add each reason code.
+ foreach $i (@reasons) {
+ my $rn;
+ my $rstr = "ERR_REASON($i)";
+ my $nspc = 0;
+ if (exists $err_reason_strings{$i}) {
+ $rn = $err_reason_strings{$i};
+ } else {
+ $i =~ /^${lib}_R_(\S+)$/;
+ $rn = $1;
+ $rn =~ tr/_[A-Z]/ [a-z]/;
+ }
+ $nspc = 40 - length($rstr) unless length($rstr) > 40;
+ $nspc = " " x $nspc;
+ print OUT "{${rstr}${nspc},\"$rn\"},\n";
+ }
+if($static) {
+ print OUT <<"EOF";
+{0,NULL}
+ };
+
+#endif
+
+${staticloader}void ERR_load_${lib}_strings(void)
+ {
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(${lib}_str_functs[0].error) == NULL)
+ {
+ ERR_load_strings($load_errcode,${lib}_str_functs);
+ ERR_load_strings($load_errcode,${lib}_str_reasons);
+ }
+#endif
+ }
+EOF
+} else {
+ print OUT <<"EOF";
+{0,NULL}
+ };
+
+#endif
+
+#ifdef ${lib}_LIB_NAME
+static ERR_STRING_DATA ${lib}_lib_name[]=
+ {
+{0 ,${lib}_LIB_NAME},
+{0,NULL}
+ };
+#endif
+
+
+static int ${lib}_lib_error_code=0;
+static int ${lib}_error_init=1;
+
+${staticloader}void ERR_load_${lib}_strings(void)
+ {
+ if (${lib}_lib_error_code == 0)
+ ${lib}_lib_error_code=ERR_get_next_error_library();
+
+ if (${lib}_error_init)
+ {
+ ${lib}_error_init=0;
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(${lib}_lib_error_code,${lib}_str_functs);
+ ERR_load_strings(${lib}_lib_error_code,${lib}_str_reasons);
+#endif
+
+#ifdef ${lib}_LIB_NAME
+ ${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code,0,0);
+ ERR_load_strings(0,${lib}_lib_name);
+#endif
+ }
+ }
+
+${staticloader}void ERR_unload_${lib}_strings(void)
+ {
+ if (${lib}_error_init == 0)
+ {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(${lib}_lib_error_code,${lib}_str_functs);
+ ERR_unload_strings(${lib}_lib_error_code,${lib}_str_reasons);
+#endif
+
+#ifdef ${lib}_LIB_NAME
+ ERR_unload_strings(0,${lib}_lib_name);
+#endif
+ ${lib}_error_init=1;
+ }
+ }
+
+${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line)
+ {
+ if (${lib}_lib_error_code == 0)
+ ${lib}_lib_error_code=ERR_get_next_error_library();
+ ERR_PUT_error(${lib}_lib_error_code,function,reason,file,line);
+ }
+EOF
+
+}
+
+ close OUT;
+ undef %err_reason_strings;
+}
+
+if($debug && defined(%notrans)) {
+ print STDERR "The following function codes were not translated:\n";
+ foreach(sort keys %notrans)
+ {
+ print STDERR "$_\n";
+ }
+}
+
+# Make a list of unreferenced function and reason codes
+
+foreach (keys %fcodes) {
+ push (@funref, $_) unless exists $ufcodes{$_};
+}
+
+foreach (keys %rcodes) {
+ push (@runref, $_) unless exists $urcodes{$_};
+}
+
+if($debug && defined(@funref) ) {
+ print STDERR "The following function codes were not referenced:\n";
+ foreach(sort @funref)
+ {
+ print STDERR "$_\n";
+ }
+}
+
+if($debug && defined(@runref) ) {
+ print STDERR "The following reason codes were not referenced:\n";
+ foreach(sort @runref)
+ {
+ print STDERR "$_\n";
+ }
+}
+
+if($errcount) {
+ print STDERR "There were errors, failing...\n\n";
+ exit $errcount;
+}
+
diff --git a/openssl/util/mkstack.pl b/openssl/util/mkstack.pl
index 685051f82..f708610a7 100644
--- a/openssl/util/mkstack.pl
+++ b/openssl/util/mkstack.pl
@@ -1,192 +1,192 @@
-#!/usr/local/bin/perl -w
-
-# This is a utility that searches out "DECLARE_STACK_OF()"
-# declarations in .h and .c files, and updates/creates/replaces
-# the corresponding macro declarations in crypto/stack/safestack.h.
-# As it's not generally possible to have macros that generate macros,
-# we need to control this from the "outside", here in this script.
-#
-# Geoff Thorpe, June, 2000 (with massive Perl-hacking
-# help from Steve Robb)
-
-my $safestack = "crypto/stack/safestack";
-
-my $do_write;
-while (@ARGV) {
- my $arg = $ARGV[0];
- if($arg eq "-write") {
- $do_write = 1;
- }
- shift @ARGV;
-}
-
-
-@source = (<crypto/*.[ch]>, <crypto/*/*.[ch]>, <ssl/*.[ch]>, <apps/*.[ch]>);
-foreach $file (@source) {
- next if -l $file;
-
- # Open the .c/.h file for reading
- open(IN, "< $file") || die "Can't open $file for reading: $!";
-
- while(<IN>) {
- if (/^DECLARE_STACK_OF\(([^)]+)\)/) {
- push @stacklst, $1;
- }
- if (/^DECLARE_SPECIAL_STACK_OF\(([^,\s]+)\s*,\s*([^>\s]+)\)/) {
- push @sstacklst, [$1, $2];
- }
- if (/^DECLARE_ASN1_SET_OF\(([^)]+)\)/) {
- push @asn1setlst, $1;
- }
- if (/^DECLARE_PKCS12_STACK_OF\(([^)]+)\)/) {
- push @p12stklst, $1;
- }
- if (/^DECLARE_LHASH_OF\(([^)]+)\)/) {
- push @lhashlst, $1;
- }
- }
- close(IN);
-}
-
-
-
-my $old_stackfile = "";
-my $new_stackfile = "";
-my $inside_block = 0;
-my $type_thing;
-
-open(IN, "< $safestack.h") || die "Can't open input file: $!";
-while(<IN>) {
- $old_stackfile .= $_;
-
- if (m|^/\* This block of defines is updated by util/mkstack.pl, please do not touch! \*/|) {
- $inside_block = 1;
- }
- if (m|^/\* End of util/mkstack.pl block, you may now edit :-\) \*/|) {
- $inside_block = 0;
- } elsif ($inside_block == 0) {
- $new_stackfile .= $_;
- }
- next if($inside_block != 1);
- $new_stackfile .= "/* This block of defines is updated by util/mkstack.pl, please do not touch! */";
-
- foreach $type_thing (sort @stacklst) {
- $new_stackfile .= <<EOF;
-
-#define sk_${type_thing}_new(cmp) SKM_sk_new($type_thing, (cmp))
-#define sk_${type_thing}_new_null() SKM_sk_new_null($type_thing)
-#define sk_${type_thing}_free(st) SKM_sk_free($type_thing, (st))
-#define sk_${type_thing}_num(st) SKM_sk_num($type_thing, (st))
-#define sk_${type_thing}_value(st, i) SKM_sk_value($type_thing, (st), (i))
-#define sk_${type_thing}_set(st, i, val) SKM_sk_set($type_thing, (st), (i), (val))
-#define sk_${type_thing}_zero(st) SKM_sk_zero($type_thing, (st))
-#define sk_${type_thing}_push(st, val) SKM_sk_push($type_thing, (st), (val))
-#define sk_${type_thing}_unshift(st, val) SKM_sk_unshift($type_thing, (st), (val))
-#define sk_${type_thing}_find(st, val) SKM_sk_find($type_thing, (st), (val))
-#define sk_${type_thing}_find_ex(st, val) SKM_sk_find_ex($type_thing, (st), (val))
-#define sk_${type_thing}_delete(st, i) SKM_sk_delete($type_thing, (st), (i))
-#define sk_${type_thing}_delete_ptr(st, ptr) SKM_sk_delete_ptr($type_thing, (st), (ptr))
-#define sk_${type_thing}_insert(st, val, i) SKM_sk_insert($type_thing, (st), (val), (i))
-#define sk_${type_thing}_set_cmp_func(st, cmp) SKM_sk_set_cmp_func($type_thing, (st), (cmp))
-#define sk_${type_thing}_dup(st) SKM_sk_dup($type_thing, st)
-#define sk_${type_thing}_pop_free(st, free_func) SKM_sk_pop_free($type_thing, (st), (free_func))
-#define sk_${type_thing}_shift(st) SKM_sk_shift($type_thing, (st))
-#define sk_${type_thing}_pop(st) SKM_sk_pop($type_thing, (st))
-#define sk_${type_thing}_sort(st) SKM_sk_sort($type_thing, (st))
-#define sk_${type_thing}_is_sorted(st) SKM_sk_is_sorted($type_thing, (st))
-EOF
- }
-
- foreach $type_thing (sort @sstacklst) {
- my $t1 = $type_thing->[0];
- my $t2 = $type_thing->[1];
- $new_stackfile .= <<EOF;
-
-#define sk_${t1}_new(cmp) ((STACK_OF($t1) *)sk_new(CHECKED_SK_CMP_FUNC($t2, cmp)))
-#define sk_${t1}_new_null() ((STACK_OF($t1) *)sk_new_null())
-#define sk_${t1}_push(st, val) sk_push(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val))
-#define sk_${t1}_find(st, val) sk_find(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val))
-#define sk_${t1}_value(st, i) (($t1)sk_value(CHECKED_STACK_OF($t1, st), i))
-#define sk_${t1}_num(st) SKM_sk_num($t1, st)
-#define sk_${t1}_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF($t1, st), CHECKED_SK_FREE_FUNC2($t1, free_func))
-#define sk_${t1}_insert(st, val, i) sk_insert(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val), i)
-#define sk_${t1}_free(st) SKM_sk_free(${t1}, st)
-#define sk_${t1}_set(st, i, val) sk_set(CHECKED_STACK_OF($t1, st), i, CHECKED_PTR_OF($t2, val))
-#define sk_${t1}_zero(st) SKM_sk_zero($t1, (st))
-#define sk_${t1}_unshift(st, val) sk_unshift(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val))
-#define sk_${t1}_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF($t1), st), CHECKED_CONST_PTR_OF($t2, val))
-#define sk_${t1}_delete(st, i) SKM_sk_delete($t1, (st), (i))
-#define sk_${t1}_delete_ptr(st, ptr) ($t1 *)sk_delete_ptr(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, ptr))
-#define sk_${t1}_set_cmp_func(st, cmp) \\
- ((int (*)(const $t2 * const *,const $t2 * const *)) \\
- sk_set_cmp_func(CHECKED_STACK_OF($t1, st), CHECKED_SK_CMP_FUNC($t2, cmp)))
-#define sk_${t1}_dup(st) SKM_sk_dup($t1, st)
-#define sk_${t1}_shift(st) SKM_sk_shift($t1, (st))
-#define sk_${t1}_pop(st) ($t2 *)sk_pop(CHECKED_STACK_OF($t1, st))
-#define sk_${t1}_sort(st) SKM_sk_sort($t1, (st))
-#define sk_${t1}_is_sorted(st) SKM_sk_is_sorted($t1, (st))
-
-EOF
- }
-
- foreach $type_thing (sort @asn1setlst) {
- $new_stackfile .= <<EOF;
-
-#define d2i_ASN1_SET_OF_${type_thing}(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \\
- SKM_ASN1_SET_OF_d2i($type_thing, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
-#define i2d_ASN1_SET_OF_${type_thing}(st, pp, i2d_func, ex_tag, ex_class, is_set) \\
- SKM_ASN1_SET_OF_i2d($type_thing, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
-#define ASN1_seq_pack_${type_thing}(st, i2d_func, buf, len) \\
- SKM_ASN1_seq_pack($type_thing, (st), (i2d_func), (buf), (len))
-#define ASN1_seq_unpack_${type_thing}(buf, len, d2i_func, free_func) \\
- SKM_ASN1_seq_unpack($type_thing, (buf), (len), (d2i_func), (free_func))
-EOF
- }
- foreach $type_thing (sort @p12stklst) {
- $new_stackfile .= <<EOF;
-
-#define PKCS12_decrypt_d2i_${type_thing}(algor, d2i_func, free_func, pass, passlen, oct, seq) \\
- SKM_PKCS12_decrypt_d2i($type_thing, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
-EOF
- }
-
- foreach $type_thing (sort @lhashlst) {
- my $lc_tt = lc $type_thing;
- $new_stackfile .= <<EOF;
-
-#define lh_${type_thing}_new() LHM_lh_new(${type_thing},${lc_tt})
-#define lh_${type_thing}_insert(lh,inst) LHM_lh_insert(${type_thing},lh,inst)
-#define lh_${type_thing}_retrieve(lh,inst) LHM_lh_retrieve(${type_thing},lh,inst)
-#define lh_${type_thing}_delete(lh,inst) LHM_lh_delete(${type_thing},lh,inst)
-#define lh_${type_thing}_doall(lh,fn) LHM_lh_doall(${type_thing},lh,fn)
-#define lh_${type_thing}_doall_arg(lh,fn,arg_type,arg) \\
- LHM_lh_doall_arg(${type_thing},lh,fn,arg_type,arg)
-#define lh_${type_thing}_error(lh) LHM_lh_error(${type_thing},lh)
-#define lh_${type_thing}_num_items(lh) LHM_lh_num_items(${type_thing},lh)
-#define lh_${type_thing}_down_load(lh) LHM_lh_down_load(${type_thing},lh)
-#define lh_${type_thing}_node_stats_bio(lh,out) \\
- LHM_lh_node_stats_bio(${type_thing},lh,out)
-#define lh_${type_thing}_node_usage_stats_bio(lh,out) \\
- LHM_lh_node_usage_stats_bio(${type_thing},lh,out)
-#define lh_${type_thing}_stats_bio(lh,out) \\
- LHM_lh_stats_bio(${type_thing},lh,out)
-#define lh_${type_thing}_free(lh) LHM_lh_free(${type_thing},lh)
-EOF
- }
-
- $new_stackfile .= "/* End of util/mkstack.pl block, you may now edit :-) */\n";
- $inside_block = 2;
-}
-
-
-if ($new_stackfile eq $old_stackfile) {
- print "No changes to $safestack.h.\n";
- exit 0; # avoid unnecessary rebuild
-}
-
-if ($do_write) {
- print "Writing new $safestack.h.\n";
- open OUT, ">$safestack.h" || die "Can't open output file";
- print OUT $new_stackfile;
- close OUT;
-}
+#!/usr/local/bin/perl -w
+
+# This is a utility that searches out "DECLARE_STACK_OF()"
+# declarations in .h and .c files, and updates/creates/replaces
+# the corresponding macro declarations in crypto/stack/safestack.h.
+# As it's not generally possible to have macros that generate macros,
+# we need to control this from the "outside", here in this script.
+#
+# Geoff Thorpe, June, 2000 (with massive Perl-hacking
+# help from Steve Robb)
+
+my $safestack = "crypto/stack/safestack";
+
+my $do_write;
+while (@ARGV) {
+ my $arg = $ARGV[0];
+ if($arg eq "-write") {
+ $do_write = 1;
+ }
+ shift @ARGV;
+}
+
+
+@source = (<crypto/*.[ch]>, <crypto/*/*.[ch]>, <ssl/*.[ch]>, <apps/*.[ch]>);
+foreach $file (@source) {
+ next if -l $file;
+
+ # Open the .c/.h file for reading
+ open(IN, "< $file") || die "Can't open $file for reading: $!";
+
+ while(<IN>) {
+ if (/^DECLARE_STACK_OF\(([^)]+)\)/) {
+ push @stacklst, $1;
+ }
+ if (/^DECLARE_SPECIAL_STACK_OF\(([^,\s]+)\s*,\s*([^>\s]+)\)/) {
+ push @sstacklst, [$1, $2];
+ }
+ if (/^DECLARE_ASN1_SET_OF\(([^)]+)\)/) {
+ push @asn1setlst, $1;
+ }
+ if (/^DECLARE_PKCS12_STACK_OF\(([^)]+)\)/) {
+ push @p12stklst, $1;
+ }
+ if (/^DECLARE_LHASH_OF\(([^)]+)\)/) {
+ push @lhashlst, $1;
+ }
+ }
+ close(IN);
+}
+
+
+
+my $old_stackfile = "";
+my $new_stackfile = "";
+my $inside_block = 0;
+my $type_thing;
+
+open(IN, "< $safestack.h") || die "Can't open input file: $!";
+while(<IN>) {
+ $old_stackfile .= $_;
+
+ if (m|^/\* This block of defines is updated by util/mkstack.pl, please do not touch! \*/|) {
+ $inside_block = 1;
+ }
+ if (m|^/\* End of util/mkstack.pl block, you may now edit :-\) \*/|) {
+ $inside_block = 0;
+ } elsif ($inside_block == 0) {
+ $new_stackfile .= $_;
+ }
+ next if($inside_block != 1);
+ $new_stackfile .= "/* This block of defines is updated by util/mkstack.pl, please do not touch! */";
+
+ foreach $type_thing (sort @stacklst) {
+ $new_stackfile .= <<EOF;
+
+#define sk_${type_thing}_new(cmp) SKM_sk_new($type_thing, (cmp))
+#define sk_${type_thing}_new_null() SKM_sk_new_null($type_thing)
+#define sk_${type_thing}_free(st) SKM_sk_free($type_thing, (st))
+#define sk_${type_thing}_num(st) SKM_sk_num($type_thing, (st))
+#define sk_${type_thing}_value(st, i) SKM_sk_value($type_thing, (st), (i))
+#define sk_${type_thing}_set(st, i, val) SKM_sk_set($type_thing, (st), (i), (val))
+#define sk_${type_thing}_zero(st) SKM_sk_zero($type_thing, (st))
+#define sk_${type_thing}_push(st, val) SKM_sk_push($type_thing, (st), (val))
+#define sk_${type_thing}_unshift(st, val) SKM_sk_unshift($type_thing, (st), (val))
+#define sk_${type_thing}_find(st, val) SKM_sk_find($type_thing, (st), (val))
+#define sk_${type_thing}_find_ex(st, val) SKM_sk_find_ex($type_thing, (st), (val))
+#define sk_${type_thing}_delete(st, i) SKM_sk_delete($type_thing, (st), (i))
+#define sk_${type_thing}_delete_ptr(st, ptr) SKM_sk_delete_ptr($type_thing, (st), (ptr))
+#define sk_${type_thing}_insert(st, val, i) SKM_sk_insert($type_thing, (st), (val), (i))
+#define sk_${type_thing}_set_cmp_func(st, cmp) SKM_sk_set_cmp_func($type_thing, (st), (cmp))
+#define sk_${type_thing}_dup(st) SKM_sk_dup($type_thing, st)
+#define sk_${type_thing}_pop_free(st, free_func) SKM_sk_pop_free($type_thing, (st), (free_func))
+#define sk_${type_thing}_shift(st) SKM_sk_shift($type_thing, (st))
+#define sk_${type_thing}_pop(st) SKM_sk_pop($type_thing, (st))
+#define sk_${type_thing}_sort(st) SKM_sk_sort($type_thing, (st))
+#define sk_${type_thing}_is_sorted(st) SKM_sk_is_sorted($type_thing, (st))
+EOF
+ }
+
+ foreach $type_thing (sort @sstacklst) {
+ my $t1 = $type_thing->[0];
+ my $t2 = $type_thing->[1];
+ $new_stackfile .= <<EOF;
+
+#define sk_${t1}_new(cmp) ((STACK_OF($t1) *)sk_new(CHECKED_SK_CMP_FUNC($t2, cmp)))
+#define sk_${t1}_new_null() ((STACK_OF($t1) *)sk_new_null())
+#define sk_${t1}_push(st, val) sk_push(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val))
+#define sk_${t1}_find(st, val) sk_find(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val))
+#define sk_${t1}_value(st, i) (($t1)sk_value(CHECKED_STACK_OF($t1, st), i))
+#define sk_${t1}_num(st) SKM_sk_num($t1, st)
+#define sk_${t1}_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF($t1, st), CHECKED_SK_FREE_FUNC2($t1, free_func))
+#define sk_${t1}_insert(st, val, i) sk_insert(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val), i)
+#define sk_${t1}_free(st) SKM_sk_free(${t1}, st)
+#define sk_${t1}_set(st, i, val) sk_set(CHECKED_STACK_OF($t1, st), i, CHECKED_PTR_OF($t2, val))
+#define sk_${t1}_zero(st) SKM_sk_zero($t1, (st))
+#define sk_${t1}_unshift(st, val) sk_unshift(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, val))
+#define sk_${t1}_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF($t1), st), CHECKED_CONST_PTR_OF($t2, val))
+#define sk_${t1}_delete(st, i) SKM_sk_delete($t1, (st), (i))
+#define sk_${t1}_delete_ptr(st, ptr) ($t1 *)sk_delete_ptr(CHECKED_STACK_OF($t1, st), CHECKED_PTR_OF($t2, ptr))
+#define sk_${t1}_set_cmp_func(st, cmp) \\
+ ((int (*)(const $t2 * const *,const $t2 * const *)) \\
+ sk_set_cmp_func(CHECKED_STACK_OF($t1, st), CHECKED_SK_CMP_FUNC($t2, cmp)))
+#define sk_${t1}_dup(st) SKM_sk_dup($t1, st)
+#define sk_${t1}_shift(st) SKM_sk_shift($t1, (st))
+#define sk_${t1}_pop(st) ($t2 *)sk_pop(CHECKED_STACK_OF($t1, st))
+#define sk_${t1}_sort(st) SKM_sk_sort($t1, (st))
+#define sk_${t1}_is_sorted(st) SKM_sk_is_sorted($t1, (st))
+
+EOF
+ }
+
+ foreach $type_thing (sort @asn1setlst) {
+ $new_stackfile .= <<EOF;
+
+#define d2i_ASN1_SET_OF_${type_thing}(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \\
+ SKM_ASN1_SET_OF_d2i($type_thing, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+#define i2d_ASN1_SET_OF_${type_thing}(st, pp, i2d_func, ex_tag, ex_class, is_set) \\
+ SKM_ASN1_SET_OF_i2d($type_thing, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_${type_thing}(st, i2d_func, buf, len) \\
+ SKM_ASN1_seq_pack($type_thing, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_${type_thing}(buf, len, d2i_func, free_func) \\
+ SKM_ASN1_seq_unpack($type_thing, (buf), (len), (d2i_func), (free_func))
+EOF
+ }
+ foreach $type_thing (sort @p12stklst) {
+ $new_stackfile .= <<EOF;
+
+#define PKCS12_decrypt_d2i_${type_thing}(algor, d2i_func, free_func, pass, passlen, oct, seq) \\
+ SKM_PKCS12_decrypt_d2i($type_thing, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+EOF
+ }
+
+ foreach $type_thing (sort @lhashlst) {
+ my $lc_tt = lc $type_thing;
+ $new_stackfile .= <<EOF;
+
+#define lh_${type_thing}_new() LHM_lh_new(${type_thing},${lc_tt})
+#define lh_${type_thing}_insert(lh,inst) LHM_lh_insert(${type_thing},lh,inst)
+#define lh_${type_thing}_retrieve(lh,inst) LHM_lh_retrieve(${type_thing},lh,inst)
+#define lh_${type_thing}_delete(lh,inst) LHM_lh_delete(${type_thing},lh,inst)
+#define lh_${type_thing}_doall(lh,fn) LHM_lh_doall(${type_thing},lh,fn)
+#define lh_${type_thing}_doall_arg(lh,fn,arg_type,arg) \\
+ LHM_lh_doall_arg(${type_thing},lh,fn,arg_type,arg)
+#define lh_${type_thing}_error(lh) LHM_lh_error(${type_thing},lh)
+#define lh_${type_thing}_num_items(lh) LHM_lh_num_items(${type_thing},lh)
+#define lh_${type_thing}_down_load(lh) LHM_lh_down_load(${type_thing},lh)
+#define lh_${type_thing}_node_stats_bio(lh,out) \\
+ LHM_lh_node_stats_bio(${type_thing},lh,out)
+#define lh_${type_thing}_node_usage_stats_bio(lh,out) \\
+ LHM_lh_node_usage_stats_bio(${type_thing},lh,out)
+#define lh_${type_thing}_stats_bio(lh,out) \\
+ LHM_lh_stats_bio(${type_thing},lh,out)
+#define lh_${type_thing}_free(lh) LHM_lh_free(${type_thing},lh)
+EOF
+ }
+
+ $new_stackfile .= "/* End of util/mkstack.pl block, you may now edit :-) */\n";
+ $inside_block = 2;
+}
+
+
+if ($new_stackfile eq $old_stackfile) {
+ print "No changes to $safestack.h.\n";
+ exit 0; # avoid unnecessary rebuild
+}
+
+if ($do_write) {
+ print "Writing new $safestack.h.\n";
+ open OUT, ">$safestack.h" || die "Can't open output file";
+ print OUT $new_stackfile;
+ close OUT;
+}