diff options
author | marha <marha@users.sourceforge.net> | 2011-04-13 08:10:11 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-04-13 08:10:11 +0000 |
commit | c1e91b66cbcf91645f65b9d63f115dcb5a441406 (patch) | |
tree | 67be8fec5fa39c8febbd86416aeb9ef09053d1d4 | |
parent | d92d86b5e751381366dcde13cf983e041e300ee2 (diff) | |
parent | 7bcdd32ccff794b9a83a88ff9bc2d0b7b088bd06 (diff) | |
download | vcxsrv-c1e91b66cbcf91645f65b9d63f115dcb5a441406.tar.gz vcxsrv-c1e91b66cbcf91645f65b9d63f115dcb5a441406.tar.bz2 vcxsrv-c1e91b66cbcf91645f65b9d63f115dcb5a441406.zip |
svn merge ^/branches/released .
43 files changed, 43447 insertions, 42998 deletions
diff --git a/openssl/CHANGES b/openssl/CHANGES index 38bfd34aa..862321280 100644 --- a/openssl/CHANGES +++ b/openssl/CHANGES @@ -1,9419 +1,9452 @@ - - OpenSSL CHANGES - _______________ - - 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.8o and 0.9.8p [xx XXX xxxx] - - *) 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 - - *) 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 50e931408..b34e1091c 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.0c was released on Dec 2nd, 2010. - -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 a2c4adcbe..5cb670496 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-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 - * 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 139c1e02b..2bf07a2c3 100644 --- a/openssl/NEWS +++ b/openssl/NEWS @@ -1,571 +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.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: - - 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.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 509350db7..7809cb3c4 100644 --- a/openssl/README +++ b/openssl/README @@ -1,218 +1,218 @@ - - OpenSSL 1.0.0c 2 Dec 2010 - - Copyright (c) 1998-2010 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 c8acd2ade..99a3da250 100644 --- a/openssl/VMS/mkshared.com +++ b/openssl/VMS/mkshared.com @@ -1,371 +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 = "" -$ 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" -$ 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" -$ 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" -$ gosub create_vax_shr -$ endif -$ exit -$ -$! ----- Soubroutines 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 58f286562..6a7e4b4a4 100644 --- a/openssl/apps/makeapps.com +++ b/openssl/apps/makeapps.com @@ -1,997 +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. -$! -$! -$! 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.OLB -$! -$! Define The SSL Library. -$! -$ SSL_LIB := SYS$DISK:[-.'ARCH'.EXE.SSL]LIBSSL.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 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" + - - "/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 7fc14d329..d9172e055 100644 --- a/openssl/crypto/asn1/a_strex.c +++ b/openssl/crypto/asn1/a_strex.c @@ -1,567 +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) - - -/* 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(!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 */ -}; - -#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \ - ASN1_STRFLGS_ESC_QUOTE | \ - ASN1_STRFLGS_ESC_CTRL | \ - ASN1_STRFLGS_ESC_MSB) - -/* 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, "es, 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, "es, 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 753021a7a..0a2f13c29 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(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 9a8b6cc22..5e26a14b8 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; - ENGINE *e; - - 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 - /* 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 f7718b5a9..1a5123216 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(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 eb7e36546..117ab599d 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_IVP6 - 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 8bfa0bcd9..a3d925d94 100644 --- a/openssl/crypto/bio/bss_file.c +++ b/openssl/crypto/bio/bss_file.c @@ -1,471 +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; - - /* - * 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,MB_ERR_INVALID_CHARS, - filename,len_0,NULL,0))>0) - { - WCHAR wmode[8]; - WCHAR *wfilename = _alloca(sz*sizeof(WCHAR)); - - if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS, - 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 - ) /* 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 efd366fa2..3f0ae4c56 100644 --- a/openssl/crypto/comp/c_rle.c +++ b/openssl/crypto/comp/c_rle.c @@ -1,62 +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 (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 96d9d5354..f6d6c53cb 100644 --- a/openssl/crypto/crypto-lib.com +++ b/openssl/crypto/crypto-lib.com @@ -1,1336 +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. -$! -$! -$! 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.OLB -$! -$! Define The CRYPTO-LIB We Are To Use. -$! -$ CRYPTO_LIB := 'EXE_DIR'LIBCRYPTO.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 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" + - - "/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 1fb665ec5..927f6e2b8 100644 --- a/openssl/crypto/dsa/dsa_ossl.c +++ b/openssl/crypto/dsa/dsa_ossl.c @@ -1,416 +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; - - /* reject a excessive digest length (currently at most - * dsa-with-SHA256 is supported) */ - if (dlen > SHA256_DIGEST_LENGTH) - { - reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; - 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; - } - - /* reject a excessive digest length (currently at most - * dsa-with-SHA256 is supported) */ - if (dgst_len > SHA256_DIGEST_LENGTH) - { - DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - 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 cf357b462..1725dd128 100644 --- a/openssl/crypto/ec/ec2_smpl.c +++ b/openssl/crypto/ec/ec2_smpl.c @@ -1,1039 +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 (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 12fb0e6d6..0458d340b 100644 --- a/openssl/crypto/ec/ec_key.c +++ b/openssl/crypto/ec/ec_key.c @@ -1,457 +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 ((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 4d26f8bdf..766f5fc51 100644 --- a/openssl/crypto/ec/ecp_smpl.c +++ b/openssl/crypto/ec/ecp_smpl.c @@ -1,1716 +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 (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 7fbd95f63..c24e26d4c 100644 --- a/openssl/crypto/engine/engine.h +++ b/openssl/crypto/engine/engine.h @@ -1,830 +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) { \ - 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) { \ - 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 b3290165c..5ddd4d794 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 -$ -$ 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 79c679cbf..ecffe494f 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 0x1000003f -#ifdef OPENSSL_FIPS -#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0c-fips 2 Dec 2010" -#else -#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0c 2 Dec 2010" -#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 a498f1b10..d416f2c9b 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_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val)) -#define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val)) -#define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_PTR_OF(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_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func)) -#define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val)) -#define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val)) -#define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_PTR_OF(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_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func)) -#define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val)) -#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val)) -#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_PTR_OF(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_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func)) -#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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 b079b50fc..b008687a2 100644 --- a/openssl/crypto/ts/ts_verify_ctx.c +++ b/openssl/crypto/ts/ts_verify_ctx.c @@ -1,160 +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 <assert.h> -#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) - { - 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; - - 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 9087d66e0..247d671a8 100644 --- a/openssl/crypto/x509v3/v3_addr.c +++ b/openssl/crypto/x509v3/v3_addr.c @@ -1,1287 +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; - - switch (afi) { - case IANA_AFI_IPV4: - 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: - 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 56702f86b..fb7bc147c 100644 --- a/openssl/crypto/x509v3/v3_asid.c +++ b/openssl/crypto/x509v3/v3_asid.c @@ -1,844 +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 <assert.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_; - - 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)); - - 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; - 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; - 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) -{ - 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. - */ - 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). - */ - 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; - } - } - - 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; - - assert(chain != NULL && sk_X509_num(chain) > 0); - assert(ctx != NULL || ext != NULL); - 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); - 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); - 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. - */ - 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 5871491fd..5c1fbeff3 100644 --- a/openssl/engines/e_capi.c +++ b/openssl/engines/e_capi.c @@ -1,1822 +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) { 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 c1f5601b6..63d68b0c2 100644 --- a/openssl/engines/e_gmp.c +++ b/openssl/engines/e_gmp.c @@ -1,478 +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) { 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 381a74605..dbeff3bb8 100644 --- a/openssl/engines/e_padlock.c +++ b/openssl/engines/e_padlock.c @@ -1,1227 +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 - -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 -} - -#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) { 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 6cf423607..a7e4aa86d 100644 --- a/openssl/engines/makeengines.com +++ b/openssl/engines/makeengines.com @@ -1,961 +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. -$! -$!----------------------------------------------------------------------------- -$! -$! 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.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 -$ -$ 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_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" + - - "/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:[.ENGINE.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:[.ENGINE.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 20211b73b..fe8271405 100644 --- a/openssl/makevms.com +++ b/openssl/makevms.com @@ -1,1354 +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. -$! -$! -$! P2 is ignored (it was used to denote if RSAref should be used or not, -$! and is simply kept so surrounding scripts don't get confused) -$! -$! 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 """" /* Not filled in for now */" -$ 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.OLB" Library. -$! -$ CRYPTO: -$! -$! Tell The User What We Are Doing. -$! -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "Building The [.",ARCH,".EXE.CRYPTO]LIBCRYPTO.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'" -$! -$! Build The [.xxx.EXE.CRYPTO]*.EXE Test Applications. -$! -$ @CRYPTO-LIB APPS 'DEBUGGER' "''COMPILER'" "''TCPIP_TYPE'" 'ISSEVEN' "''BUILDPART'" -$! -$! Go Back To The Main Directory. -$! -$ SET DEFAULT [-] -$! -$! Time To RETURN. -$! -$ RETURN -$! -$! Build The "[.xxx.EXE.SSL]LIBSSL.OLB" Library. -$! -$ SSL: -$! -$! Tell The User What We Are Doing. -$! -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "Building The [.",ARCH,".EXE.SSL]LIBSSL.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' -$! -$! 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' -$! -$! 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' -$! -$! 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' -$! -$! 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'" -$! -$! 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] [not-used option] [Debug option] <Compiler>" -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "Example: @MAKEVMS.COM ALL NORSAREF 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 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 9b9072a7d..1fc73408f 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 c -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 8fa57347a..d762dc5c5 100644 --- a/openssl/ssl/d1_enc.c +++ b/openssl/ssl/d1_enc.c @@ -1,293 +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) - { - SSLerr(SSL_F_DTLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); - ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); - return 0; - } - } - - 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 1fd58bf59..79b723a5e 100644 --- a/openssl/ssl/d1_pkt.c +++ b/openssl/ssl/d1_pkt.c @@ -1,1768 +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 */ - goto 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 7f5606759..c79f76ef9 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 -$ -$ 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 947167687..6643c787c 100644 --- a/openssl/ssl/s2_srvr.c +++ b/openssl/ssl/s2_srvr.c @@ -1,1141 +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); s->session->key_arg_length=i; - if(s->session->key_arg_length > 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->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 c5ca9e1df..8847c9bd3 100644 --- a/openssl/ssl/ssl-lib.com +++ b/openssl/ssl/ssl-lib.com @@ -1,1057 +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) -$! -$! -$! 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.OLB -$! -$! Define The CRYPTO-LIB We Are To Use. -$! -$ CRYPTO_LIB := SYS$DISK:[-.'ARCH'.EXE.CRYPTO]LIBCRYPTO.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.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 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" + - - "/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 5cdd7e572..1ebad6166 100644 --- a/openssl/ssl/t1_lib.c +++ b/openssl/ssl/t1_lib.c @@ -1,1741 +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; - 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 */ - 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 3d8129bf2..cf9eaa117 100644 --- a/openssl/test/maketests.com +++ b/openssl/test/maketests.com @@ -1,927 +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) -$! -$! -$! 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.OLB -$! -$! Define The SSL We Are To Use. -$! -$ SSL_LIB := SYS$DISK:[-.'ARCH'.EXE.SSL]LIBSSL.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 P2 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" + - - "/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 2526c86f8..2387cebb3 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(/\s+/,$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 15b774f27..74e3ef67b 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-2010 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 6a43757c9..685051f82 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_PTR_OF(STACK_OF($t1), st), CHECKED_PTR_OF($t2, val)) -#define sk_${t1}_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF($t1), st), CHECKED_PTR_OF($t2, val)) -#define sk_${t1}_value(st, i) (($t1)sk_value(CHECKED_PTR_OF(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_PTR_OF(STACK_OF($t1), st), CHECKED_SK_FREE_FUNC2($t1, free_func)) -#define sk_${t1}_insert(st, val, i) sk_insert(CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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((_STACK *)CHECKED_PTR_OF(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;
+}
diff --git a/packages.txt b/packages.txt index 0df8958d8..d9b9cb17c 100644 --- a/packages.txt +++ b/packages.txt @@ -65,7 +65,7 @@ libxcb git version libxkbfile-1.0.7
mesa git version
mkfontscale git version
-openssl-1.0.0c
+openssl-1.0.0d
pixman git version
pthreads-w32-2-8-0-release
randrproto git version
|